如何在Three.js中结合Anime.js实现相机目标位置移动时的平滑过渡
如何在Three.js中结合Anime.js实现相机目标位置移动时的平滑过渡
嘿,我看你这问题是相机移动的时候过渡太生硬,像直接切画面似的对吧?刚好我对Three.js结合Anime.js做动画这块熟,来给你支个招~
你现在的代码逻辑是先把画布透明度降到0,再瞬间把相机挪到目标位置,然后再显示画布——这本质上是用“隐藏画面”来掩盖生硬的位置切换,自然会有类似display: none转display: block的突兀感。要实现真正的平滑移动,核心是让Three.js在相机位置变化的每一刻都实时渲染画面,而不是靠隐藏画布来蒙混过关。
关键改进思路
- 保留Three.js的持续渲染循环:Anime.js每帧更新相机位置后,需要Three.js立刻把新的相机视角渲染出来,这样才能看到平滑的移动过程。
- 直接对相机的
position属性做动画:去掉先隐藏画布的多余逻辑,让Anime.js直接操控相机的x/y/z坐标,同时依赖渲染循环实时刷新画面。 - 可选保留淡入淡出作为视觉增强:如果想要过渡更丝滑,可以给画布加个淡入淡出动画,但这只是锦上添花,不是解决生硬问题的核心。
修正后的完整代码
const setupCameraForPart2 = (propsCameraPart: CameraPropsPart): void => { const { center, distance, name } = propsCameraPart; if (!name) { console.error('Part name is not provided'); // 修复了你代码里引号未闭合的小问题 return; } console.log('Current Position:', _camera.position); // 计算目标位置,保持你原来的逻辑 const targetPosition = new THREE.Vector3(center.x, center.y, center.z + distance); // 直接对相机位置做平滑动画,这才是核心 anime({ targets: _camera.position, x: targetPosition.x, y: targetPosition.y, z: targetPosition.z, duration: 800, // 时长可以根据需求调,比如想慢一点就设1000 easing: 'easeInOutQuad', // 这个缓动函数过渡最自然,适合相机移动 // 可选:如果你的渲染循环没在自动运行,就在这里每帧触发渲染 update: () => { // renderer.render(scene, _camera); }, complete: () => { console.log('相机已经平滑挪到目标位置啦'); } }); // 可选:给画布加个淡入淡出增强过渡效果(非必须) anime({ targets: '.viewport-three-d > canvas', opacity: [0.7, 1], duration: 600, easing: 'easeInOutQuad', }); };
额外要注意的点
- 一定要确保你的Three.js场景有持续的渲染循环,比如这样的基础结构:
只要这个循环在跑,Anime.js每更新一次相机位置,Three.js就会自动渲染新的画面,动画自然就平滑了。function animateScene() { requestAnimationFrame(animateScene); renderer.render(scene, _camera); } // 启动渲染循环 animateScene(); - 如果你之前的渲染循环是暂停的,那就要在Anime.js的
update回调里手动调用renderer.render(scene, _camera),确保每帧都刷新。 - 缓动函数别乱选,
easeInOutQuad是相机移动的黄金选择——开头和结尾速度慢,中间快,符合人眼的自然预期,不会有突然的加速减速感。
备注:内容来源于stack exchange,提问作者notnuyy
相关产品推荐
相关产品推荐

