Three.js入门学习笔记17:鼠标控制json文件的3d模型旋转

参考学习
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>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值