如何实现点击事件中Decay属性的平滑渐变恢复效果
解决方案:实现Shader decay属性的平滑增减动画
问题根源
当前pointerup事件中直接将config.shader.decay赋值为初始值decaybackup,导致数值跳变,破坏了动画流畅性。需要替换为和pointerdown时一致的渐进式修改逻辑。
修改后的代码(基于setInterval)
let decaybackup = config.shader.decay; world.resize(); let interval = ''; const myshape = document.getElementById('shapeId'); myshape.addEventListener('pointerdown', function(event) { // 清除可能存在的恢复定时器,避免多个定时器同时运行 clearInterval(interval); interval = setInterval(()=>{ config.shader.decay += 0.001; }, 1); }); myshape.addEventListener('pointerup', function(event) { // 停止增加的定时器 clearInterval(interval); // 启动递减动画,直到回到初始值 interval = setInterval(()=>{ if (config.shader.decay > decaybackup) { config.shader.decay -= 0.001; } else { // 确保最终值准确,停止定时器 config.shader.decay = decaybackup; clearInterval(interval); interval = ''; } }, 1); });
优化方案:使用requestAnimationFrame(更平滑的动画)
setInterval的执行间隔受浏览器主线程阻塞影响,可能导致动画卡顿,推荐用requestAnimationFrame实现更流畅的动画:
let decaybackup = config.shader.decay; world.resize(); let animationId = null; const myshape = document.getElementById('shapeId'); // 递增decay的动画函数 function increaseDecay() { config.shader.decay += 0.001; animationId = requestAnimationFrame(increaseDecay); } // 递减到初始值的动画函数 function decreaseDecay() { if (config.shader.decay > decaybackup) { config.shader.decay -= 0.001; animationId = requestAnimationFrame(decreaseDecay); } else { config.shader.decay = decaybackup; animationId = null; } } myshape.addEventListener('pointerdown', function(event) { if (animationId) { cancelAnimationFrame(animationId); } increaseDecay(); }); myshape.addEventListener('pointerup', function(event) { if (animationId) { cancelAnimationFrame(animationId); } decreaseDecay(); });
关键改动说明
- 启动新动画前必须清除已有定时器/动画帧,避免多个动画逻辑同时运行导致数值异常
pointerup阶段通过渐进式递减代替直接赋值,保持和pointerdown相同的变化速率,确保动画流畅性- 增加边界判断,当
decay回到初始值时停止动画,避免无效循环
内容的提问来源于stack exchange,提问作者Vox
相关产品推荐
相关产品推荐

