繁体   English   中英

鼠标单击时对象的动画(旋转,移动)

[英]Animation (rotation, movement) of an object on mouse click

考虑这个three.js示例

https://threejs.org/examples/?q=glt#webgl_loader_gltf

我正在尝试在鼠标单击事件上实现对象的动画(对象当前所在位置的旋转/移动),但没有动画。

这是我添加的代码。 我会过度渲染吗?

        document.addEventListener( 'mousedown', clickMe, false );
        render();

        function clickMe() {
            rotation();
            render();   
        }


        var gltfModel;


        function rotation() {
            var rotationAnimation = 5 * (Math.PI / 180);
            gltfModel.rotation.x += rotationAnimation;
            render();       
        }

        function render() {
            renderer.render( scene, camera );
        }

如果我添加功能rotation(); requestAnimationFrame(rotation);

            function rotation() {
            requestAnimationFrame( rotation );
            var rotationAnimation = 5 * (Math.PI / 180);
            gltfModel.rotation.x += rotationAnimation;
            render();       
        }

gltfModel保持循环旋转,每次单击速度都会翻倍

这是完整的代码:

        <script>

        if ( WEBGL.isWebGLAvailable() === false ) {

            document.body.appendChild( WEBGL.getWebGLErrorMessage() );

        }

        var container, stats, controls;
        var camera, scene, renderer, light;




        init();
        animate();

        function init() {

            container = document.createElement( 'div' );
            document.body.appendChild( container );

            camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 );
            camera.position.set( - 1.8, 0.9, 2.7 );

            controls = new THREE.OrbitControls( camera );
            controls.target.set( 0, - 0.2, - 0.2 );
            controls.update();

            var urls = [ 'posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg' ];
            var loader = new THREE.CubeTextureLoader().setPath( 'textures/cube/Bridge2/' );
            var background = loader.load( urls );

            scene = new THREE.Scene();
            scene.background = background;

            light = new THREE.HemisphereLight( 0xbbbbff, 0x444422 );
            light.position.set( 0, 1, 0 );
            scene.add( light );

            // model
            var loader = new THREE.GLTFLoader().setPath( 'models/gltf/DamagedHelmet/glTF/' );
            loader.load( 'DamagedHelmet.gltf', function ( gltf ) {

                gltf.scene.traverse( function ( child ) {

                    if ( child.isMesh ) {

                        child.material.envMap = background;

                        gltfModel = child;

                    }

                } );

                scene.add( gltf.scene );

            }, undefined, function ( e ) {

                console.error( e );

            } );

            renderer = new THREE.WebGLRenderer( { antialias: true } );
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            renderer.gammaOutput = true;
            container.appendChild( renderer.domElement );

            window.addEventListener( 'resize', onWindowResize, false );

            //MY LINE OF CODE
            document.addEventListener( 'mousedown', clickMe, false );
            render();


            // stats
            stats = new Stats();
            container.appendChild( stats.dom );

        }

        function onWindowResize() {

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            renderer.setSize( window.innerWidth, window.innerHeight );

        }

        //MY LINE OF CODE
        ///////////////////////////////////////

        function clickMe() {

            rotation();

            render();



        }


        var gltfModel;


        function rotation() {

            var rotationAnimation = 5 * (Math.PI / 180);

            gltfModel.rotation.x += rotationAnimation;

            render();

        }




        ///////////////////////////////////////



        function animate() {

            requestAnimationFrame( animate );


            render();

            stats.update();


        }


        function render() {
            renderer.render( scene, camera );
        }

    </script>

可以用EventDispatcher完成吗? 如果是这样,怎么办? https://threejs.org/docs/#api/en/core/EventDispatcher

但我宁愿选择第一种方法?

是的,您只需要调用一次render ,这样您就可以从rotation()clickMe()以及在document.addEventListener( 'mousedown', clickMe, false );之后取出这三个调用document.addEventListener( 'mousedown', clickMe, false );

但是,每次单击仅旋转对象一次。 我假设您要实现的是按住鼠标的同时旋转对象。

如果要执行此操作,可以在mousedown上设置一个布尔值。

因此,在clickMe内,您可以执行以下操作:

function clickMe() {
  rotating = true; // declare this as a global variable
}

然后在渲染功能中,您可以执行以下操作:

function render() {
  if (rotating) {
    var rotationAnimation = 5 * (Math.PI / 180);
    gltfModel.rotation.x += rotationAnimation;
  }
  renderer.render( scene, camera );
}

完成所有这些操作后,请确保添加一个mouseup侦听器,以在放开鼠标时停止旋转。

function handleMouseUp() {
  rotating = false;
}

document.addEventListener('mouseup', handleMouseUp);

一个盒子的简单代码示例,它将鼠标向下滚动以帮助您入门。 您可以轻松地将其应用于gltf模型。 至于render方法,是的,您无缘无故地在函数中使用它。 您应该看一下基本的场景示例。

https://threejs.org/docs/#manual/en/introduction/Creating-a-scene

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> </body> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/101/three.min.js"></script> <script> var box; var isMouseDown = false; var rotateSpeed = 0; init(); animate(); function init() { container = document.createElement('div'); document.body.appendChild(container); camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 20); camera.position.set(5,5,5); camera.lookAt(new THREE.Vector3(0,0,0)); scene = new THREE.Scene(); light = new THREE.HemisphereLight(0xbbbbff, 0x444422); light.position.set(0, 1, 0); scene.add(light); var geometry = new THREE.BoxBufferGeometry( 1, 1, 1 ); var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); box = new THREE.Mesh( geometry, material ); scene.add( box ); renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); container.appendChild(renderer.domElement); window.addEventListener('mousedown', () => isMouseDown = true,false); window.addEventListener('mouseup', () => isMouseDown = false,false); animate(); } function animate() { requestAnimationFrame(animate); if(isMouseDown) rotateSpeed += 0.001; else rotateSpeed /= 1.01; box.rotation.y += rotateSpeed; render(); } function render() { renderer.render(scene, camera); } </script> </html> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM