参考学习
https://blog.csdn.net/tuoxinquyu/article/details/72391797
一.鼠标控制原理:
当按下鼠标时及时当前鼠标的水平坐标clientX1,在鼠标移动的过程中不断触发onMouseMove事件,不停的记录鼠标的当前坐标clientX2,由当前坐标减去记录的上一个水平坐标,
并且将当前的坐标付给上一个坐标clientX1,计算两个坐标的之间的差clientX2-clientX1,
将得到的差值除以一个常量(这个常量可以根据自己的需要调整),得到旋转的角度
二.核心代码:
function init() {
//加载json模型,将模型放入group1中
var loaderC1 = new THREE.ObjectLoader();
loaderC1.load("json/che0312.json", function(obj1) {
obj1.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.side = THREE.DoubleSide;
}
});
obj1.scale.multiplyScalar(50);
mesh1 = new THREE.Mesh();
mesh1.name="Me1";
mesh1.add(obj1);
group1.add(mesh1);
scene.add(group1);
renderer.render(scene, camera);
});
//事件监听
document.addEventListener( 'mousedown', onMouseDown, false );
document.addEventListener( 'mouseup', onMouseup, false );
}
//鼠标事件
var rotateStart;
rotateStart = new THREE.Vector2();
function onMouseDown(event){
//阻止浏览器默认事件。什么是默认事件,例如浏览器默认右键菜单、a标签默认连接跳转
event.preventDefault();
mouseDown = true;
//clientX 事件属性返回当事件被触发时鼠标指针向对于浏览器页面(或客户区)的水平坐标。客户区指的是当前窗口。
mouseX = event.clientX;//触发事件时的鼠标指针的水平坐标
rotateStart.set( event.clientX, event.clientY );
document.addEventListener( 'mousemove', onMouseMove2, false );
}
function onMouseup(event){
//当鼠标松开时
mouseDown = false;
//移除鼠标移动的操作
document.removeEventListener("mousemove", onMouseMove2);
}
function onMouseMove2(event){
//如果鼠标没有按下,终止操作
if(!mouseDown){
return;
}
//event.clientX是当前移动时,不断记录的鼠标X坐标。mouseX是鼠标按下时第一次记录的旋转起始点的鼠标X坐标,随着每一次移动,mouseX不断更新为上一次移动后的坐标点
var deltaX = event.clientX - mouseX;
mouseX = event.clientX;//我理解是,每移动单位距离就赋值,作为下一次移动的起始点
//这样才能保证鼠标按下无论是向右还是向左,模型都跟着移动
rotateScene(deltaX);
}
//设置模型旋转速度,可以根据自己的需要调整
function rotateScene(deltaX){
//设置旋转方向和移动方向相反,所以加了个负号。不加负号就是正向移动
// var deg = -deltaX/279;
var deg = deltaX/279;
//deg 设置模型旋转的弧度 在原来转动的基础上累加
group1.rotation.y += deg;
render();
}
function render() {
renderer.render(scene, camera);
}
三.模型旋转
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>threejs鼠标移动控制模型旋转</title>
</head>
<body>
<script type="text/javascript" src="js/three.js"></script>
<!--<script src="http://jsrun.it/assets/a/q/3/W/aq3Wl" type="text/javascript"></script>-->
<!--<script src="js/CanvasRenderer.js"></script>
<script src="js/Projector.js"></script>
<script src="js/DDSLoader.js"></script>
<script src="js/MTLLoader.js"></script>-->
<script src="js/OBJLoader.js"></script>
<!-- <script src="js/jquery-2.1.1.min.js"></script>
<script src="https://raw.githack.com/mrdoob/three.js/master/examples/fonts/helvetiker_regular.typeface.js"></script> -->
<script>
var camera, scene, renderer, geometry, material, mesh, mesh1;
var pivot5, pivot6;
var group = new THREE.Group();
var group1 = new THREE.Group();
init();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(20, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(15,15,15);
// camera.lookAt(new THREE.Vector3(0,0,0));
camera.lookAt( scene.position );
// camera.position.z = 500;
// camera.position.y = 100;
scene.add(camera);
//坐标轴辅助
var axes = new THREE.AxisHelper(500);
scene.add(axes);
//渲染
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor( 0xffffcc );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//添加环境光
var ambient = new THREE.AmbientLight( 0x444444 );
scene.add( ambient );
// 添加定向光线
var directionalLight = new THREE.DirectionalLight( 0xffeedd );
directionalLight.position.set( 0, 0, 1 ).normalize();
scene.add( directionalLight );
var onProgress = function ( xhr ) {
if ( xhr.lengthComputable ) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log( Math.round(percentComplete, 2) + '% downloaded' );
}
};
//json模型
var loaderC1 = new THREE.ObjectLoader();
loaderC1.load("json/che0312.json", function(obj1) {
obj1.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.side = THREE.DoubleSide;
}
});
obj1.scale.multiplyScalar(50);
mesh1 = new THREE.Mesh();
mesh1.name="Me1";
mesh1.add(obj1);
group1.add(mesh1);
scene.add(group1);
renderer.render(scene, camera);
});
//监听
document.addEventListener( 'mousedown', onMouseDown, false );
document.addEventListener( 'mouseup', onMouseup, false );
}//init end
var rotateStart;
rotateStart = new THREE.Vector2();
/*
鼠标移动控制模型旋转思想:
当按下鼠标时及时当前鼠标的水平坐标clientX1,在鼠标移动的过程中不断触发onMouseMove事件,
不停的记录鼠标的当前坐标clientX2,由当前坐标减去记录的上一个水平坐标,
并且将当前的坐标付给上一个坐标clientX1,计算两个坐标的之间的差clientX2-clientX1,
将得到的差值除以一个常量(这个常量可以根据自己的需要调整),得到旋转的角度
*/
function onMouseDown(event){
event.preventDefault();
//当鼠标按下时,记录鼠标按下时的水平坐标
mouseDown = true;
mouseX = event.clientX;//出发事件时的鼠标指针的水平坐标
//鼠标按下时,将旋转起始点设置为鼠标点击的坐标
rotateStart.set( event.clientX, event.clientY );
//当鼠标按住不放,进行mousemove操作时,执行ononMouseMove2函数,也就是
//计算差值
document.addEventListener( 'mousemove', onMouseMove2, false );
}
function onMouseup(event){
//当鼠标松开时
mouseDown = false;
//移除鼠标移动的操作
document.removeEventListener("mousemove", onMouseMove2);
}
function onMouseMove2(event){
//如果鼠标没有按下,终止操作
if(!mouseDown){
return;
}
//event.clientX是当前移动时,不断记录的鼠标X坐标。mouseX是鼠标按下时第一次记录的旋转起始点的鼠标X坐标,随着每一次移动,mouseX不断更新为上一次移动后的坐标点
var deltaX = event.clientX - mouseX;
mouseX = event.clientX;//我理解是,每移动单位距离就赋值,作为下一次移动的起始点
//这样才能保证鼠标按下无论是向右还是向左,模型都跟着移动
rotateScene(deltaX);
}
//设置模型旋转速度,可以根据自己的需要调整
function rotateScene(deltaX){
//设置旋转方向和移动方向相反,所以加了个负号。不加负号就是正向移动
// var deg = -deltaX/279;
var deg = deltaX/279;
//deg 设置模型旋转的弧度 在原来转动的基础上累加
group1.rotation.y += deg;
render();
}
function render() {
renderer.render(scene, camera);
}
</script>
</body>
</html>
四.多轴旋转+2个模型
没有写选中单独某个模型,目前两个只能一起,下一篇再试试
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>threejs鼠标移动控制模型旋转</title>
</head>
<body>
<script type="text/javascript" src="js/three.js"></script>
<!--<script src="http://jsrun.it/assets/a/q/3/W/aq3Wl" type="text/javascript"></script>-->
<!--<script src="js/CanvasRenderer.js"></script>
<script src="js/Projector.js"></script>
<script src="js/DDSLoader.js"></script>
<script src="js/MTLLoader.js"></script>-->
<script src="js/OBJLoader.js"></script>
<!-- <script src="js/jquery-2.1.1.min.js"></script>
<script src="https://raw.githack.com/mrdoob/three.js/master/examples/fonts/helvetiker_regular.typeface.js"></script> -->
<script>
var camera, scene, renderer, geometry, material, mesh, mesh1, mesh2;
var pivot5, pivot6;
var group = new THREE.Group();
var group1 = new THREE.Group();
var group2 = new THREE.Group();
init();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(20, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(15,15,15);
camera.lookAt( 0,0,0 );
// camera.lookAt(new THREE.Vector3(0,0,0));
// camera.lookAt( scene.position );
// camera.position.z = 500;
// camera.position.y = 100;
scene.add(camera);
//坐标轴辅助
var axes = new THREE.AxisHelper(500);
scene.add(axes);
//渲染
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor( 0xffffcc );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//添加环境光
var ambient = new THREE.AmbientLight( 0x444444 );
scene.add( ambient );
// 添加定向光线
var directionalLight = new THREE.DirectionalLight( 0xffeedd );
directionalLight.position.set( 0, 0, 1 ).normalize();
scene.add( directionalLight );
var onProgress = function ( xhr ) {
if ( xhr.lengthComputable ) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log( Math.round(percentComplete, 2) + '% downloaded' );
}
};
//json模型
var loaderC1 = new THREE.ObjectLoader();
loaderC1.load("json/che0312.json", function(obj1) {
obj1.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.side = THREE.DoubleSide;
}
});
obj1.scale.multiplyScalar(50);
mesh1 = new THREE.Mesh();
mesh1.name="Me1";
mesh1.add(obj1);
group1.add(mesh1);
scene.add(group1);
renderer.render(scene, camera);
});
var loaderC2 = new THREE.ObjectLoader();
loaderC2.load("json/che0312.json", function(obj2) {
obj2.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.side = THREE.DoubleSide;
}
});
obj2.scale.multiplyScalar(50);
mesh2 = new THREE.Mesh();
mesh2.name="Me2";
mesh2.add(obj2);
group2.add(mesh2);
scene.add(group2);
group2.position.set(5,0,0);
renderer.render(scene, camera);
});
//监听
document.addEventListener( 'mousedown', onMouseDown, false );
document.addEventListener( 'mouseup', onMouseup, false );
}//init end
var rotateStart;
rotateStart = new THREE.Vector2();
/*
鼠标移动控制模型旋转思想:
当按下鼠标时及时当前鼠标的水平坐标clientX1,在鼠标移动的过程中不断触发onMouseMove事件,
不停的记录鼠标的当前坐标clientX2,由当前坐标减去记录的上一个水平坐标,
并且将当前的坐标付给上一个坐标clientX1,计算两个坐标的之间的差clientX2-clientX1,
将得到的差值除以一个常量(这个常量可以根据自己的需要调整),得到旋转的角度
*/
function onMouseDown(event){
event.preventDefault();
//当鼠标按下时,记录鼠标按下时的水平坐标
mouseDown = true;
mouseX = event.clientX;//出发事件时的鼠标指针的水平坐标
mouseY = event.clientY;
//鼠标按下时,将旋转起始点设置为鼠标点击的坐标
rotateStart.set( event.clientX, event.clientY );
//当鼠标按住不放,进行mousemove操作时,执行ononMouseMove2函数,也就是
//计算差值
document.addEventListener( 'mousemove', onMouseMove2, false );
}
function onMouseup(event){
//当鼠标松开时
mouseDown = false;
//移除鼠标移动的操作
document.removeEventListener("mousemove", onMouseMove2);
}
function onMouseMove2(event){
//如果鼠标没有按下,终止操作
if(!mouseDown){
return;
}
//event.clientX是当前移动时,不断记录的鼠标X坐标。mouseX是鼠标按下时第一次记录的旋转起始点的鼠标X坐标,随着每一次移动,mouseX不断更新为上一次移动后的坐标点
var deltaX = event.clientX - mouseX;
var deltaY = event.clientY - mouseY;
mouseX = event.clientX;//我理解是,每移动单位距离就赋值,作为下一次移动的起始点
//这样才能保证鼠标按下无论是向右还是向左,模型都跟着移动
mouseY = event.clientY;
rotateScene(deltaX,deltaY);
}
//设置模型旋转速度,可以根据自己的需要调整
function rotateScene(deltaX,deltaY){
//设置旋转方向和移动方向相反,所以加了个负号。不加负号就是正向移动
// var deg = -deltaX/279;
var deg1 = deltaX/100;
var deg2 = deltaY/100;
//deg 设置模型旋转的弧度 在原来转动的基础上累加
group1.rotation.y += deg1;
group1.rotation.x += deg2;
group1.rotation.z += deg2;
group2.rotation.y += deg1;
group2.rotation.x += deg2;
group2.rotation.z += deg2;
render();
}
function render() {
renderer.render(scene, camera);
}
</script>
</body>
</html>
五.参考案例的完整代码转载
参考案例来自:
https://blog.csdn.net/tuoxinquyu/article/details/72391797
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>threejs鼠标移动控制模型旋转</title>
</head>
<body>
<script src="js/threejs/three.js"></script>
<!--<script src="http://jsrun.it/assets/a/q/3/W/aq3Wl" type="text/javascript"></script>-->
<script src="js/threejs/renderers/CanvasRenderer.js"></script>
<script src="js/threejs/renderers/Projector.js"></script>
<script src="js/threejs/DDSLoader.js"></script>
<script src="js/threejs/MTLLoader.js"></script>
<script src="js/threejs/OBJLoader.js"></script>
<script src="js/jquery-2.1.1.min.js"></script>
<script src="https://raw.githack.com/mrdoob/three.js/master/examples/fonts/helvetiker_regular.typeface.js"></script>
<script>
var camera, scene, renderer, geometry, material, mesh;
var pivot5, pivot6;
init();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 500;
camera.position.y = 100;
scene.add(camera);
//坐标轴辅助
var axes = new THREE.AxisHelper(500);
scene.add(axes);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor( 0xffffcc );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth, window.innerHeight);
//添加环境光
var ambient = new THREE.AmbientLight( 0x444444 );
scene.add( ambient );
// 添加定向光线
var directionalLight = new THREE.DirectionalLight( 0xffeedd );
directionalLight.position.set( 0, 0, 1 ).normalize();
scene.add( directionalLight );
var onProgress = function ( xhr ) {
if ( xhr.lengthComputable ) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log( Math.round(percentComplete, 2) + '% downloaded' );
}
};
//加载obj 、材质、贴图
var onError = function ( xhr ) { };
THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
var texture = new THREE.Texture();
var loader = new THREE.OBJLoader();
loader.setPath( 'models/' );
pivot5 = new THREE.Object3D();
//导入obj模型
loader.load( 'tree.obj', function ( object ) {
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.material.map = texture;
//将模型放大40倍
var n=40;
child.scale.x =n;
child.scale.y =n;
child.scale.z =n;
}
} );
pivot5.position.x = -100;
pivot5.position.z = 100;
object.position.x = 0;
object.position.z = 0;
object.position.y = 50;
//scene.add( object );
pivot5.add(object);
}, onProgress, onError );
//导入贴图
var cubemtlLoader = new THREE.MTLLoader();
cubemtlLoader.setPath( 'models/' );
pivot6 = new THREE.Object3D();
cubemtlLoader.load( 'cube.mtl', function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( 'models/' );
objLoader.load( 'cube.obj', function ( object ) {
var n= 20;
object.scale.x =n;
object.scale.y =n;
object.scale.z =n;
//修改旋转轴的坐标点,默认是(0,0,0);
pivot6.position.x = 100;
pivot6.position.z = 100;
object.position.x = 0;
object.position.z = 0;
object.position.y = 100;
pivot6.add(object);
render();
}, onProgress, onError );
});
scene.add(pivot5);
scene.add(pivot6);
document.body.appendChild(renderer.domElement);
document.addEventListener( 'mousedown', onMouseDown, false );
document.addEventListener( 'mouseup', onMouseup, false );
}
var rotateStart;
rotateStart = new THREE.Vector2();
/*
鼠标移动控制模型旋转思想:
当按下鼠标时及时当前鼠标的水平坐标clientX1,在鼠标移动的过程中不断触发onMouseMove事件,
不停的记录鼠标的当前坐标clientX2,由当前坐标减去记录的上一个水平坐标,
并且将当前的坐标付给上一个坐标clientX1,计算两个坐标的之间的差clientX2-clientX1,
将得到的差值除以一个常量(这个常量可以根据自己的需要调整),得到旋转的角度
*/
function onMouseDown(event){
event.preventDefault();
mouseDown = true;
mouseX = event.clientX;//出发事件时的鼠标指针的水平坐标
rotateStart.set( event.clientX, event.clientY );
document.addEventListener( 'mousemove', onMouseMove2, false );
}
function onMouseup(event){
mouseDown = false;
document.removeEventListener("mousemove", onMouseMove2);
}
function onMouseMove2(event){
if(!mouseDown){
return;
}
var deltaX = event.clientX - mouseX;
mouseX = event.clientX;
rotateScene(deltaX);
}
//设置模型旋转速度,可以根据自己的需要调整
function rotateScene(deltaX){
//设置旋转方向和移动方向相反,所以加了个负号
var deg = -deltaX/279;
//deg 设置模型旋转的弧度
pivot5.rotation.y += deg;
pivot6.rotation.y += deg;
render();
}
function render() {
renderer.render(scene, camera);
}
</script>
</body>
</html>