如何在滚动(上/下)中的Three.js中更新DeltaY时钟

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在滚动(上/下)中的Three.js中更新DeltaY时钟相关的知识,希望对你有一定的参考价值。

我有一个动画原型-可以在滚动中播放-有没有办法将滚动上的动画重置到顶部/底部?基本上是从顶部开始播放,直到到达底部才停止?现在,动画将循环播放,并忽略顶部/底部(开始/结束)。

从顶部滚动时,它向前播放,而到达底部时,它则反向播放是想要的行为。

 var container, stats, controls;
      var camera, scene, renderer, light;
      var clock = new THREE.Clock();

      var mixer = [];

      var mixers = [];

      init();

      animate();

      function init() 

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

        camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.set( 0, 100, 100 );

        scene = new THREE.Scene();

        light = new THREE.HemisphereLight( 0xffffff, 0x444444 );
        light.position.set( 0, 200, 0 );
        scene.add( light );

        light = new THREE.DirectionalLight( 0xffffff );
        light.position.set( 0, 200, 100 );
        light.castShadow = true;
        light.shadow.camera.top = 180;
        light.shadow.camera.bottom = -100;
        light.shadow.camera.left = -120;
        light.shadow.camera.right = 120;
        scene.add( light );

          // scene.add( new THREE.CameraHelper( light.shadow.camera ) );

          var grid = new THREE.GridHelper( 2000, 20, 0x000000, 0x000000 );
          grid.material.opacity = 0.2;
          grid.material.transparent = true;
          scene.add( grid );

          // model
          var loader = new THREE.FBXLoader();
          loader.load( 'https://threejs.org/examples/models/fbx/Samba Dancing.fbx', function ( object ) 

            object.mixer = new THREE.AnimationMixer( object );
            mixers.push( object.mixer );


            var action = object.mixer.clipAction( object.animations[ 0 ] );
            action.play();


            object.traverse( function ( child ) 

              if ( child.isMesh ) 

                child.castShadow = true;
                child.receiveShadow = true;

              

             );
            object.position.y = 85;

            scene.add( object );

           );


          renderer = new THREE.WebGLRenderer(  alpha: true, antialias: true  );
          renderer.setPixelRatio( window.devicePixelRatio );
          renderer.setSize( window.innerWidth, window.innerHeight );
          renderer.shadowMap.enabled = true;
          container.appendChild( renderer.domElement );

          window.addEventListener( 'mousewheel', onMouseWheel, false );
          window.addEventListener( 'touchstart', onTouchStart, false );
          window.addEventListener( 'touchmove', onTouchMove, false );

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

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

        


        function onResize() 
          camera.aspect = window.innerWidth / window.innerHeight;
          camera.updateProjectionMatrix();
          renderer.setSize(window.innerWidth, window.innerHeight);
        


        function onMouseWheel( event ) 


          if(event.deltaY > 0)
            for ( var i = 0; i < mixers.length; i ++ ) 
              mixers[ i ].update( clock.getDelta() * 5 );
            
           else 
            for ( var i = 0; i < mixers.length; i ++ ) 
              mixers[ i ].update( clock.getDelta() * -5 );

            
          
        


        function onTouchStart(event) 

          startY = event.touches[ 0 ].pageY;


        

        function onTouchMove( event ) 

          var delta = event.deltaY;

          if(event.deltaY > 0)
            for ( var i = 0; i < mixers.length; i ++ ) 
              mixers[ i ].update( clock.getDelta() * 5 );
            
           else 
            for ( var i = 0; i < mixers.length; i ++ ) 
              mixers[ i ].update( clock.getDelta() * -5 );

            
          


        


        function animate() 

         delta = clock.getDelta();

         requestAnimationFrame( animate );

         renderer.render( scene, camera );

         stats.update();

       
body 

        margin: 0px;
        overflow: hidden;
      
     <script src="https://threejs.org/build/three.js"></script>
       <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
      <script src="https://threejs.org/examples/js/libs/inflate.min.js"></script>
       <script src="https://threejs.org/examples/js/loaders/FBXLoader.js"></script>
         <script src="https://threejs.org/examples/js/WebGL.js"></script>
          <script src="https://threejs.org/examples/js/libs/stats.min.js"></script>
答案

首先,您应该绝对不要直接链接到threejs.org。当three.js开发人员更新版本时,您的示例将中断,这将使您的问题示例对其他人无效。使用CDN中的特定版本!

否则,如果您不保存剪辑,则>

                object.mixer = new THREE.AnimationMixer( object );
                mixers.push( object.mixer );


                const clip = object.animations[0];
                clips.push(clip);
                var action = object.mixer.clipAction(clip);
                action.play();

那么您也许可以使用这样的代码

        function updateAnimation(direction) 
          const delta = direction * 5 * clock.getDelta();
          for (let i = 0; i < mixers.length; ++i) 
            const mixer = mixers[i];
            const clip = clips[i];
            const duration = clip.duration;
            const newTime = THREE.MathUtils.clamp(mixer.time + delta, 0, duration);
            mixer.setTime(newTime);
          
        


        function onMouseWheel( event ) 
          updateAnimation(Math.sign(event.deltaY)); 
        

...

var container, stats, controls;
      var camera, scene, renderer, light;
      var duration;
      var clock = new THREE.Clock();

      var mixer = [];

      var mixers = [];
      var clips = [];

      init();

      animate();

      function init() 

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

        camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.set( 0, 100, 100 );

        scene = new THREE.Scene();

        light = new THREE.HemisphereLight( 0xffffff, 0x444444 );
        light.position.set( 0, 200, 0 );
        scene.add( light );

        light = new THREE.DirectionalLight( 0xffffff );
        light.position.set( 0, 200, 100 );
        light.castShadow = true;
        light.shadow.camera.top = 180;
        light.shadow.camera.bottom = -100;
        light.shadow.camera.left = -120;
        light.shadow.camera.right = 120;
        scene.add( light );

          // scene.add( new THREE.CameraHelper( light.shadow.camera ) );

          var grid = new THREE.GridHelper( 2000, 20, 0x000000, 0x000000 );
          grid.material.opacity = 0.2;
          grid.material.transparent = true;
          scene.add( grid );

          // model
          var loader = new THREE.FBXLoader();
          loader.load( 'https://threejs.org/examples/models/fbx/Samba Dancing.fbx', function ( object ) 

            object.mixer = new THREE.AnimationMixer( object );
            mixers.push( object.mixer );


            const clip = object.animations[0];
            clips.push(clip);
            var action = object.mixer.clipAction(clip);
            action.play();


            object.traverse( function ( child ) 

              if ( child.isMesh ) 

                child.castShadow = true;
                child.receiveShadow = true;

              

             );
            object.position.y = 85;

            scene.add( object );

           );


          renderer = new THREE.WebGLRenderer(  alpha: true, antialias: true  );
          renderer.setPixelRatio( window.devicePixelRatio );
          renderer.setSize( window.innerWidth, window.innerHeight );
          renderer.shadowMap.enabled = true;
          container.appendChild( renderer.domElement );

          window.addEventListener( 'mousewheel', onMouseWheel, false );


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

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

        


        function onResize() 
          camera.aspect = window.innerWidth / window.innerHeight;
          camera.updateProjectionMatrix();
          renderer.setSize(window.innerWidth, window.innerHeight);
        
        
        function updateAnimation(direction) 
          const delta = direction * 5 * clock.getDelta();
          for (let i = 0; i < mixers.length; ++i) 
            const mixer = mixers[i];
            const clip = clips[i];
            const duration = clip.duration;
            const newTime = THREE.MathUtils.clamp(mixer.time + delta, 0, duration);
            mixer.setTime(newTime);
          
        


        function onMouseWheel( event ) 
          updateAnimation(Math.sign(event.deltaY)); 
        


        function animate() 

         delta = clock.getDelta();

         requestAnimationFrame( animate );

         renderer.render( scene, camera );

         stats.update();

       
body 

        margin: 0px;
        overflow: hidden;
      
<script src="https://cdn.jsdelivr.net/npm/three@0.113.2/build/three.min.js"></script>
       <script src="https://cdn.jsdelivr.net/npm/three@0.113.2/examples/js/controls/OrbitControls.js"></script>
      <script src="https://cdn.jsdelivr.net/npm/three@0.113.2/examples/js/libs/inflate.min.js"></script>
       <script src="https://cdn.jsdelivr.net/npm/three@0.113.2/examples/js/loaders/FBXLoader.js"></script>
         <script src="https://cdn.jsdelivr.net/npm/three@0.113.2/examples/js/WebGL.js"></script>
          <script src="https://cdn.jsdelivr.net/npm/three@0.113.2/examples/js/libs/stats.min.js"></script>

以上是关于如何在滚动(上/下)中的Three.js中更新DeltaY时钟的主要内容,如果未能解决你的问题,请参考以下文章

Three.js 进阶之旅:滚动控制模型动画和相机动画 🦢

onMouseWheel在移动设备上的触摸行为-three.js

Three.js:如何正确配置内存中的场景

如何在轴 three.js 上旋转 3D 对象?

如何在 Autodesk Forge 中动态更新 THREE.js PointCloud 覆盖

three.js css3d 如何更新数据