You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 04:27:03