當咱們須要固定場景背景,固定攝像機的時候。移動旋轉物體可使用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>