// 绕当前视点旋转 RotControl = function ( camera, div) { var self = this; var $div = $(div); camera.target = new THREE.Vector3( 0, 0, 0 ); // 事件,回调函数 this.onRot = function(event){ } var limit = Math.PI *3/ 4; var first = true; var drag = false; var lastX=0; var lastY=0; var lastDist=0; // touch消息里没有offseXY数值,我得想办法从其他数值计算出来 // 以前我记得做过,好像是要遍历父子链 function getDivPos(div) { var pos={}; pos.x = div.offsetLeft; pos.y = div.offsetTop; while(div.offsetParent!=null) { div = div.offsetParent; pos.x += div.offsetLeft; pos.y += div.offsetTop; } return pos; } function calcOffset(event) { if (event.offsetX != null) return; var pos = getDivPos(event.target); event.offsetX = event.clientX - pos.x + document.body.scrollLeft; event.offsetY = event.clientY - pos.y + document.body.scrollTop; } var onMouseDown = function ( event ) { drag = true; first = true; } var onMouseUp = function ( event ) { drag = false; } var onMouseMove = function ( event ) { /* var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; */ if (event.originalEvent.touches !=null) { if (event.originalEvent.touches.length>=2)//缩放 { var m1 = event.originalEvent.touches[0]; var m2 = event.originalEvent.touches[1]; var dx = m1.clientX-m2.clientX; var dy = m1.clientY-m2.clientY; var dist = Math.sqrt(dx*dx+dy*dy); var delta = dist - lastDist; lastDist = dist; if (first) { first = false; return; } if (delta>0 && camera.fov>5){ camera.fov*=0.99; camera.updateProjectionMatrix(); }else if (delta<0 && camera.fov<90){ camera.fov*=1.01;; camera.updateProjectionMatrix(); } return; } else if (event.originalEvent.touches.length>=1)//模仿鼠标 { event = event.originalEvent.touches[0]; // 重点touch消息里没有offseXY数值,我得想办法从其他数值计算出来 calcOffset(event); // event.buttons = 1; } else //说明length=0,应该不可能 { return; } } var movementX = event.offsetX-lastX; var movementY = event.offsetY-lastY; lastX = event.offsetX; lastY = event.offsetY; if (first) { first = false; return; } if ( self.enabled == false ) return; // event.button\buttons\which和按键有关 // 但没有按键时,button也等于0,和左键冲突 // buttons=1、4、2,好像是ie的定义 // which=1、2、3,比较正常 //if (event.which == 0)//左中右健按下,意味着开始拖拽,ie下放开按键后,仍然保持状态 // return; if (event.buttons == 0)//左中右健按下,意味着开始拖拽 return; if (!drag) return; // 对camera施加一个微小的旋转,直接改变matrix // 1 更新prs到matrix //camera.updateMatrix(); // var angleZ = 0.02*camera.fov*movementX/div.clientHeight; var angleX = 0.02*camera.fov*movementY/div.clientHeight; var dir = camera.getWorldDirection(); var up = new THREE.Vector3(0,0,1); var side = new THREE.Vector3(); side.crossVectors(dir, up); side.normalize(); var rotX = new THREE.Quaternion(); rotX.setFromAxisAngle(side, angleX); var rotZ = new THREE.Quaternion(); rotZ.setFromAxisAngle(up, angleZ); // 限制上下不能垂直 var temp = new THREE.Vector3(); temp.copy(dir); temp.applyQuaternion(rotX); if (Math.abs(temp.z)<0.9) dir.applyQuaternion(rotX); dir.applyQuaternion(rotZ); var pos = camera.position; var tar = new THREE.Vector3(); tar.addVectors(pos, dir); camera.up.set(0,0,1); camera.lookAt(tar); // 这里一大堆是为了从视线计算出航向角 var dir = camera.getWorldDirection(); // 注意,heading的目的地是leaflet的orientedMarker // 他的起始轴是y轴,但正方向是顺时针 var heading= Math.atan2(dir.x, dir.y)*180/Math.PI;//[-pi, pi] var fovy = camera.fov; var fovx = (Math.atan(Math.tan(fovy/2)*camera.aspect)*2)*180/Math.PI; var eventEye = {heading:heading, fovx:fovx}; self.onRot(eventEye); }; this.dispose = function() { $div.unbind( 'mousemove', onMouseMove ); $div.unbind( 'mousedown', onMouseDown ); $div.unbind( 'mouseup', onMouseUp ); // $div.unbind( 'touchmove', onMouseMove ); // $div.unbind( 'touchstart', onMouseDown ); // $div.unbind( 'touchend', onMouseUp ); }; $div.bind( 'mousemove', onMouseMove ); $div.bind( 'mousedown', onMouseDown ); $div.bind( 'mouseup', onMouseUp ); $div.bind( 'touchmove', onMouseMove ); $div.bind( 'touchstart', onMouseDown ); $div.bind( 'touchend', onMouseUp ); this.enabled = false; };