Three.js触发交互事件时物体动画平滑减速且保持当前位置的实现咨询
问题根因
你当前的实现出现角度跳变,核心是用总运行时长 * 转速的方式直接计算实时角度,转速发生变化时,这个乘积会直接跳变,对应立方体的旋转角度就会出现突兀跳转。
解决方案
核心做两点改造即可实现无跳变的平滑变速效果:
- 放弃总时长计算角度的逻辑,改用帧增量更新角度,每帧只在上一帧的角度基础上叠加本次帧的旋转量,保证已产生的旋转角度不会因为转速修改发生变化
- 新增目标转速变量,切换状态时只修改目标转速,每帧用缓动插值更新实际转速,实现类似CSS transition的平滑过渡效果
修改后代码
// 基础默认转速 const baseRotationSpeed = 0.9; // 实际生效的当前转速 let currentRotationSpeed = baseRotationSpeed; // 过渡用的目标转速 let targetRotationSpeed = baseRotationSpeed; // 过渡系数,数值越小过渡越平缓,可按需调整 const transitionFactor = 0.1; const interaction = new Interaction(renderer, scene, camera); cube.cursor = "pointer"; cube.on("mouseover", () => { // 仅修改目标转速,不直接修改当前生效转速 targetRotationSpeed = baseRotationSpeed - 0.5; }); cube.on("mouseout", () => { targetRotationSpeed = baseRotationSpeed; }); const clock = new THREE.Clock(); const tick = () => { // 获取当前帧与上一帧的时间差,替代原有总运行时长 const deltaTime = clock.getDelta(); // 缓动更新当前转速,实现平滑过渡 currentRotationSpeed += (targetRotationSpeed - currentRotationSpeed) * transitionFactor; // 增量更新旋转角度,在原有角度基础上叠加,避免跳变 cube.rotation.y += currentRotationSpeed * deltaTime; cube.rotation.x += currentRotationSpeed * deltaTime; // 原有剩余渲染逻辑保持不变 // renderer.render(scene, camera); requestAnimationFrame(tick); };
参数调整说明
如果需要调整过渡的快慢,修改transitionFactor即可:
- 数值越小,过渡越慢、越柔和,比如0.05对应较慢的过渡效果
- 数值越大,过渡越快,比如0.2对应更快的响应速度
内容的提问来源于stack exchange,提问作者relativenoob
相关产品推荐
相关产品推荐

