当咱们须要固定场景背景,固定摄像机的时候。移动旋转物体可使用Three.js提供的OrbitControls.js,也能够手动写控制器。javascript
原理:获取鼠标点击的位置与移动的距离,根据移动的距离计算出大概旋转的角度。html
查看旋转效果java
<script src="../dist/js/three.js"></script> <script src="../dist/js/Projector.js"></script> <script src="../dist/js/CanvasRenderer.js"></script>
<script> var container; var camera, scene, renderer; var cube, plane; var width, height; var targetRotation = 0; var targetRotationOnMouseDown = 0; var mouseX = 0; var mouseXOnMouseDown = 0; var windowHalfX = window.innerWidth / 2; var windowHalfY = window.innerHeight / 2; console.log(window.innerHeight) init(); animate(); function init() { container = document.getElementById('canvasWrap') width = document.getElementById('canvasWrap').clientWidth; height = document.getElementById('canvasWrap').clientHeight; camera = new THREE.PerspectiveCamera(70, width / height, 1, 1000); camera.position.y = 150; camera.position.z = 500; scene = new THREE.Scene(); scene.background = new THREE.Color(0xf0f0f0); //cube var geometry = new THREE.BoxGeometry(200, 200, 200); //console.log(geometry.faces.length) //12 一个面有2个三角面片 for (var i = 0; i < geometry.faces.length; i += 2) { var hex = Math.random() * 0xffffff; geometry.faces[i].color.setHex(hex); geometry.faces[i + 1].color.setHex(hex) } //vertexColors:THREE.FaceColors 顶点颜色采用上面循环中建立的3角面片的颜色(立方体显示的颜色就是三角面片的颜色) //overdraw:0.5 设置的目的避免相邻的2个三角面片有分隔线,至关于重叠部分为0.5 var material = new THREE.MeshBasicMaterial({ vertexColors: THREE.FaceColors, overdraw: 0.5 }); // cube = new THREE.Mesh(geometry, material); cube.position.y = 150; //position(0,150,0) scene.add(cube); //plane var geometry = new THREE.PlaneBufferGeometry(200, 200); geometry.rotateX(-Math.PI / 2); //从右边看顺时针旋转 var material = new THREE.MeshBasicMaterial({ color: 0xe0e0e0, overdraw: 0.5 }); plane = new THREE.Mesh(geometry, material); scene.add(plane); //CanvasRenderer 有更好的兼容性 renderer = new THREE.CanvasRenderer(); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(width, height); container.appendChild(renderer.domElement); document.addEventListener("mousedown", onDocumentMouseDown, false); document.addEventListener("touchstart", onDocumentTouchStart, false); document.addEventListener("touchmove", onDocumentTouchMove, false); window.addEventListener("resize", onWindowResize, false); } function onWindowResize() { windwoHalfX = width / 2; windwoHalfY = height / 2; camera.aspect = width / height; camera.updateProjectionMatrix(); renderer.setSize(width, height); } function onDocumentMouseDown(event) { event.preventDefault(); document.addEventListener("mousemove", onDocumentMouseMove, false); document.addEventListener("mouseup", onDocumentMouseUp, false); document.addEventListener("mouseout", onDocumentMouseOut, false); //按下去的时候鼠标相对位置 mouseXOnMouseDown = event.layerX - windowHalfX; //鼠标按下的旋转角度 targetRotationOnMouseDown = targetRotation; } function onDocumentMouseMove(event) { //移动的时候鼠标相对位置 mouseX = event.layerX - windowHalfX; //移动的时候旋转的角度 = 刚按下鼠标的角度+移动的位置-鼠标按下时的位置 targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.02; } function onDocumentMouseUp(event) { document.removeEventListener("mousemove", onDocumentMouseMove, false); document.removeEventListener("mouseup", onDocumentMouseUp, false); document.removeEventListener("mouseout", onDocumentMouseOut, false); } function onDocumentMouseOut(event) { document.removeEventListener("mousemove", onDocumentMouseMove, false); document.removeEventListener("mouseup", onDocumentMouseUp, false); document.removeEventListener("mouseout", onDocumentMouseOut, false); } function onDocumentTouchStart(event) { if (event.touches.length === 1) { event.preventaDefault(); mouseXOnMouseDown = event.touches[0].layerX - windowHalfX; targetRotationMouseDown = targetRotation; } } function onDocumentTouchMove(event) { if (event.touches.length === 1) { event.preventaDefault(); mouseX = event.touches[0].layerX - windowHalfX; targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.05;; } } function animate() { requestAnimationFrame(animate); render(); } function render() { // cube.rotation.y 初始值为0 plane.rotation.y = cube.rotation.y += (targetRotation - cube.rotation.y) * 0.05; renderer.render(scene, camera); } </script>