Привет форумчане!
Сначала посмотрите сам проект:
http://test3.stdmed.ru
Пилю проект по картам (mapbox GL JS)
Прикрутил сверху слой с визуализацией (Three.js)
Получается вроде норм, но вот все медленнее и медленнее все ворочается в браузере. Боюсь что когда я допилю функционал, приложение совсем помрет
Подскажите, если кто знает как мне поднять производительность?
Если что вот код app2.js (правда он большой, хоть я и удалил из него половину а то не влазиет):
$.getJSON('geo.json', function(info){
data = info;
for (var j = 0; j<data.length; j++) {
type[j] = data[j].json_geometry.type;
if (type[j] == "MultiPolygon") {
j++;
};
latlon[j] = data[j].json_geometry.coordinates[0];
}
document.getElementById("log").innerHTML += "> Json data loaded successfully. Objects loaded = " + data.length + "<br>";
buildMap();
});
function buildMap() {
map.on('load', function () {
document.getElementById("log").innerHTML += "> Map Loaded successfully<br>";
initGL();
function initGL() {
document.getElementById("log").innerHTML += "> function initGL() started<br>";
var mapDiv = document.getElementById("map").firstChild;
renderer = new THREE.WebGLRenderer( { alpha: true } );
renderer.shadowMap.enabled;
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
renderer.domElement.id = 'webGL';
//renderer.setClearColor( 0xff0000, 0.2 );
mapDiv.appendChild( renderer.domElement );
renderer.domElement.style.position = "absolute";
renderer.domElement.style.top = "0px";
renderer.domElement.style.left = "0px";
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 35, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 5000 );
//camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, 1, 1000 );
camera.position.z = 4;
controls = new THREE.TrackballControls( camera, container );
controls.rotateSpeed = 2;
controls.zoomSpeed = 7;
// controls.panSpeed = 3;
controls.noZoom = false;
// controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.maxPolarAngle = Math.PI/2.0;
// LIGHTS
var light;
light = new THREE.AmbientLight( 0xdddddd );
scene.add( light );
// STATS
stats = new Stats();
// remember these initial values
var tanFOV = Math.tan( ( ( Math.PI / 180 ) * camera.fov / 2 ) );
var windowHeight = window.innerHeight;
$("#map").append( stats.dom );
plane = new THREE.Mesh(
new THREE.PlaneBufferGeometry( 2000, 2000, 8, 8 ),
new THREE.MeshBasicMaterial( { visible: false, color: 0xff0000, transparent: true, opacity: 0.4 } )
);
scene.add( plane );
EventsControls2 = new EventsControls( camera, renderer.domElement );
EventsControls2.attach( plane );
EventsControls2.attachEvent( 'mouseOver', function () {
controls.target0.copy( controls.target );
controls.enabled = true;
});
EventsControls2.attachEvent( 'mouseOut', function () {
controls.reset();
controls.target.copy( controls.target0 );
controls.object.position.copy( controls.position0 );
controls.update();
controls.enabled = true;
});
EventsControls = new EventsControls( camera, renderer.domElement );
EventsControls.map = plane;
EventsControls.offsetUse = true;
EventsControls.attachEvent( 'mouseOver', function () {
this.container.style.cursor = 'pointer';
mouseOveredObject = this.mouseOveredChild;
prevOpacity = mouseOveredObject.material.opacity;
});
EventsControls.attachEvent( 'mouseOut', function () {
this.container.style.cursor = 'auto';
mouseOveredObject = undefined;
this.mouseOveredChild.material.opacity = prevOpacity;
});
EventsControls.attachEvent( 'dragAndDrop', function () {
this.container.style.cursor = 'move';
});
EventsControls.attachEvent( 'onclick', function () {
controls.enabled = false;
});
EventsControls.attachEvent( 'mouseUp', function () {
this.container.style.cursor = 'auto';
});
THREE.Triangulation.setLibrary('earcut');
/*
function onWindowResize() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.left = -window.innerWidth / 2;
camera.right = window.innerWidth / 2;
camera.top = window.innerHeight / 2;
camera.bottom = -window.innerHeight / 2;
camera.updateProjectionMatrix();
}
*/
function animate() {
requestAnimationFrame( animate );
render();
rotDegree = -1*(map.transform._pitch* 180 / Math.PI);
camera.position.y = Math.sin(THREE.Math.degToRad( rotDegree )) * 4;
camera.position.z = Math.cos(THREE.Math.degToRad( rotDegree )) * 4;
camera.lookAt( scene.position );
stats.update();
if ( !mouseOveredObject ) { } else { mouseOveredObject.material.opacity += 0.02 }
//console.log(map.dragPan._inertia);
//map.dragPan._inertia = [];
/*
if ((flag == 1) && (zGrow < 2)) {
zGrow += 0.01;
group.scale.set(1,1,zGrow)
}
*/
}
function render() {
renderer.render( scene, camera );
}
setTimeout(function(){latlonToWorld()}, 0);
animate();
}
function latlonToPx() {
for (var j = 0; j<data.length; j++) {
intersectsF[j] = [];
for (var i = 0; i<data[j].json_geometry.coordinates[0].length; i++) {
p[j] = [];
p[j][i] = map.project(new mapboxgl.LngLat( latlon[j][i][1],latlon[j][i][1] ));
op.x = ( p[j][i].x / window.innerWidth ) * 2 - 1;
op.y = - ( p[j][i].y / window.innerHeight ) * 2 + 1;
raycaster.setFromCamera( op, camera );
intersects = raycaster.intersectObjects( objarray );
if ( intersects.length > 0 ) {
if ( INTERSECTED != intersects[ 0 ].object ) {
intersectsF[j][i][0] = intersects[0].point.x;
intersectsF[j][i][1] = intersects[0].point.y;
}
} else {
INTERSECTED = null;
}
}
}
}
function latlonToWorld() {
mapWidth = window.innerWidth;
mapHeight = window.innerHeight;
mapLonLeft = map.getBounds()._sw.lng;
mapLonRight = map.getBounds()._ne.lng;
mapLonDelta = mapLonRight - mapLonLeft;
mapLatBottom = map.getBounds()._sw.lat;
mapLatBottomDegree = mapLatBottom * Math.PI / 180;
for (var i = 0; i < data.length; i++) {
geometryF[i] = new THREE.Geometry();
coords[i] = data[i].json_geometry.coordinates;
type[i] = data[i].json_geometry.type
for (var j = 0; j < coords[i][0].length; j++) {
//2D coordinates
latitude = coords[i][0][j][1];
longitude = coords[i][0][j][0];
var x = (longitude - mapLonLeft) * (mapWidth / mapLonDelta);
latitude = latitude * Math.PI / 180;
var worldMapWidth = ((mapWidth / mapLonDelta) * 360) / (2 * Math.PI);
var mapOffsetY = (worldMapWidth / 2 * Math.log((1 + Math.sin(mapLatBottomDegree)) / (1 - Math.sin(mapLatBottomDegree))));
var y = mapHeight - ((worldMapWidth / 2 * Math.log((1 + Math.sin(latitude)) / (1 - Math.sin(latitude)))) - mapOffsetY);
var point3D = new THREE.Vector3( ( x / window.innerWidth ) * 2 - 1, -( y / window.innerHeight ) * 2 + 1, 0.5 );
var vertice3D = point3D.unproject(camera);
geometryF[i].vertices.push( vertice3D );
}
}
setTimeout(function(){buildMesh()}, 0);
}
function buildMesh() {
group = new THREE.Object3D();
for (var j = 0; j < geometryF.length; j++) {
var vertices = geometryF[j].vertices;
var holes = [];
var triangles, mesh;
var geometry = new THREE.Geometry();
var material = new THREE.MeshPhongMaterial( { color: 0x33D8DE, specular: 0x825AB6, shininess: 70, shading: THREE.FlatShading, transparent:true, opacity: Math.random()*0.2+0.2} )
//material.color.setHex( Math.random() * 0xffffff );
material.side = THREE.DoubleSide;
geometry.vertices = vertices;
if (type[j] == "MultiPolygon") {
var multitriangles = earcut(vertices, holes);
};
triangles = THREE.ShapeUtils.triangulateShape( vertices, holes );
for( var i = 0; i < triangles.length; i++ ){
geometry.faces.push( new THREE.Face3( triangles[i][0], triangles[i][1], triangles[i][2] ));
}
mesh = new THREE.Mesh( geometry, material );
objects.push( mesh );
group.add( mesh );
scene.add(group);
EventsControls.attach( group );
}
}
});