Z轴旋转对象:鼠标按下暂停、抬起2秒后缓动恢复旋转的实现求助
实现旋转恢复时的Ease-in缓动效果
嘿,我来帮你搞定这个旋转恢复的缓动问题!你的现有逻辑已经实现了启停和延迟恢复,但要做到缓慢恢复的ease-in效果,我们需要给旋转速度加一个过渡过程,而不是直接跳回原速度。下面是具体的实现思路和代码修改方案:
核心思路
我们需要维护几个状态变量来跟踪缓动过程:
- 记录当前的实际旋转速度,而不是直接用固定值
- 标记是否处于缓动恢复阶段
- 跟踪缓动的进度值(从0到1),用来计算当前的过渡速度
完整代码修改
首先,在全局或你的对象作用域里添加这些状态变量:
// 初始化状态变量 let currentRotationSpeed = 0.05; // 正常旋转速度 let isEasingIn = false; // 是否正在缓动恢复 let easeProgress = 0; // 缓动进度(0-1) let timerHandle = null; // 计时器引用,方便重置
然后修改你的计时器逻辑,让它触发缓动而不是直接恢复:
// 假设这是你处理鼠标抬起的逻辑 function onMouseUp() { // 先清除之前的计时器,避免重复触发 if (timerHandle) clearTimeout(timerHandle); // 设置新的计时器,2秒后开始缓动恢复 timerHandle = setTimeout(() => { isEasingIn = true; easeProgress = 0; // 重置缓动进度 }, 2000); } // 鼠标按下时的逻辑 function onMouseDown() { // 按下时立刻停止旋转,同时清除计时器 currentRotationSpeed = 0; isEasingIn = false; if (timerHandle) clearTimeout(timerHandle); }
最后修改你的旋转更新逻辑,加入缓动计算:
// 这部分放在你的动画循环(比如requestAnimationFrame回调)里 if (etaj1 !== undefined) { if (isMouseDown) { // 鼠标按下时,直接停转 currentRotationSpeed = 0; isEasingIn = false; } else if (isEasingIn) { // 缓动恢复阶段:用ease-in公式计算当前速度 // 二次方ease-in,曲线是从慢到快,符合需求 const easeFactor = easeProgress * easeProgress; currentRotationSpeed = easeFactor * 0.05; // 更新缓动进度,每次增加0.01(可根据帧率调整) easeProgress += 0.01; // 进度到1时,结束缓动,恢复正常速度 if (easeProgress >= 1) { isEasingIn = false; currentRotationSpeed = 0.05; } } else { // 非缓动、非按下状态,保持正常速度 currentRotationSpeed = 0.05; } // 应用当前速度到旋转 etaj1.rotation.z += delta * currentRotationSpeed; }
关键细节解释
- Ease-in公式:这里用了
easeProgress * easeProgress,这是最简单的二次方ease-in曲线,你也可以用更高次方(比如三次方easeProgress ** 3)让初始速度更慢,或者用1 - Math.cos(easeProgress * Math.PI / 2)这类公式,效果会更平滑。 - 缓动进度增量:
easeProgress += 0.01这个值可以根据你的动画帧率调整,如果是60fps,每次加0.01大概1秒完成缓动;改成0.005会让过程更长,0.02则会更短。 - 计时器重置:在鼠标按下和再次抬起时,都要清除之前的计时器,避免多个计时器冲突,确保每次都是重新计算2秒延迟。
这样修改后,当你抬起鼠标2秒后,对象会从静止开始,慢慢加速到原来的旋转速度,完美实现类似CSS的ease-in缓动效果~
内容的提问来源于stack exchange,提问作者unknown
相关产品推荐
相关产品推荐

