如何在滚动(上/下)中的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时钟的主要内容,如果未能解决你的问题,请参考以下文章
onMouseWheel在移动设备上的触摸行为-three.js