<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Three.js_MouseEvent</title>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/0.157.0/three.min.js"></script>
<script type="text/javascript" src="three.js-master/examples/js/controls/OrbitControls.js"></script>
</head>
<body>
<div id="output">
</div>
<script>
function init() {
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(90, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(15, 15, 15);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
var cube = new THREE.Mesh(new THREE.BoxGeometry(3, 3, 3), new THREE.MeshBasicMaterial({
color: 0x0051ba,
wireframe: true
}));
scene.add(cube);
document.getElementById("output").appendChild(renderer.domElement);
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
document.addEventListener('mousedown', onMouseDown);
document.addEventListener('mouseup', onMouseUp);
document.addEventListener('wheel', onMouseWheel);
//阻止右键菜单呼出事件
document.oncontextmenu = function (event) {
event.preventDefault();
};
var liftMouseDown, rightMouseDown;
var selectObj, lastPosition;
var lastIntersection, nowIntersection;
var mouseX, mouseY;
function onMouseDown(event) {
var rayCaster = getRay(event);
var intersects = rayCaster.intersectObjects([cube]);//参数需为数组
//左键点击并且点击的是物体时
if (event.button === 0 && intersects[0]) {
selectObj = intersects[0].object;//储存当前点击的对象
liftMouseDown = true;
lastPosition = selectObj.position;//储存当前物体坐标位置
lastIntersection = getIntersection(event);//获取点击时的交点
document.addEventListener('mousemove', onMouseMove);
}
//右键点击屏幕时
if (event.button === 2) {
mouseX = event.clientX;
mouseY = event.clientY;
rightMouseDown = true;
document.addEventListener('mousemove', onMouseMove);
}
}
function onMouseUp(event) {
liftMouseDown = false;
rightMouseDown = false;
document.removeEventListener('mousemove', onMouseMove);
}
function onMouseMove(event) {
//左键点击状态下移动,网格跟随鼠标移动
if (liftMouseDown) {
nowIntersection = getIntersection(event);//获得移动后当前的交点
var offset = new THREE.Vector3();
//现在的交点减去之前的交点能够得到一个位移向量,再加上之前的物体坐标,就等于现在的物体坐标
selectObj.position.copy(offset.subVectors(nowIntersection, lastIntersection).add(lastPosition));
lastIntersection = nowIntersection;
lastPosition = offset;
}
//右键点击状态下移动,网格自身跟随鼠标旋转
if (rightMouseDown) {
var deltaX = event.clientX - mouseX;
mouseX = event.clientX;
var deltaY = event.clientY - mouseY;
mouseY = event.clientY;
rotation(deltaX, deltaY);
}
}
//旋转物体
function rotation(x, y) {
cube.rotation.y += x / 100;
cube.rotation.x += y / 100;
}
//鼠标中键滚动时放大或者缩小
function onMouseWheel(event) {
if (event.wheelDelta > 0) {
cube.scale.copy(cube.scale.add(new THREE.Vector3(0.1, 0.1, 0.1)))
} else {
cube.scale.copy(cube.scale.sub(new THREE.Vector3(0.1, 0.1, 0.1)))
}
}
//根据鼠标点击的点和相机建立一条射线
function getRay(event) {
event.preventDefault();
var mouse = new THREE.Vector2();
var rayCaster = new THREE.Raycaster();
var rect = renderer.domElement.getBoundingClientRect();
mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
rayCaster.setFromCamera(mouse, camera);
return rayCaster;
}
//获取射线与屏幕平面的交点
function getIntersection(event) {
var plane = new THREE.Plane();
//通过相机位置生成法向量,该法向量和一个点可以建立一个平面
plane.setFromNormalAndCoplanarPoint(camera.getWorldDirection(plane.normal), new THREE.Vector3(0, 0, 0));
var rayCaster = getRay(event);
var worldPoint = new THREE.Vector3();
//获得射线和平面相交的世界坐标
rayCaster.ray.intersectPlane(plane, worldPoint);
return worldPoint;
}
}
init();
</script>
</body>
</html>