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

时间:2019-02-17 08:51:29

标签: javascript function three.js jquery-animate

考虑这个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

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

2 个答案:

答案 0 :(得分:0)

是的,您只需要拨打一次render,这样您就可以从rotation()clickMe()以及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);

答案 1 :(得分:0)

一个简单的代码示例,可以将鼠标向下旋转以使您入门。您可以轻松地将其应用于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>