当我们需要固定场景背景,固定摄像机的时候。移动旋转物体可以使用Three.js提供的OrbitControls.js,也可以手动写控制器。
原理:获取鼠标点击的位置与移动的距离,根据移动的距离计算出大概旋转的角度。
<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>
(adsbygoogle = window.adsbygoogle || []).push({});