如何为requestAnimationFrame设置时长,实现指定时间装水动画
如何在指定时长内完成基于requestAnimationFrame的装水动画?
requestAnimationFrame是实现JavaScript动画的优质方案,但它本身不支持设置动画时长。我希望让装水动画在特定的X秒内完成,试过一些基于帧率的方案,但动画效果不够流畅。

解决方案:基于时间差计算动画进度
不要用固定步长累加的方式,而是通过时间差计算进度来控制动画,这样能保证动画在指定时长内精准完成,同时保持流畅性。核心逻辑是:记录动画开始时间,每次回调时计算已流逝的时间占总时长的比例,用这个比例作为动画的进度值。
修改后的JavaScript代码如下:
const water = document.querySelector('.water'); const duration = 3000; // 动画总时长,单位:毫秒,这里设置为3秒 let startTime; const fillGlass = (timestamp) => { // 第一次调用时记录动画开始时间 if (!startTime) startTime = timestamp; // 计算从动画开始到当前已流逝的时间 const elapsed = timestamp - startTime; // 计算动画进度,确保数值在0-1之间 const progress = Math.min(elapsed / duration, 1); // 应用进度到水的缩放比例 water.style.transform = `scaleY(${progress})`; // 进度未完成时继续触发下一次动画帧 if (progress < 1) { requestAnimationFrame(fillGlass); } }; requestAnimationFrame(fillGlass);
关键说明
duration:直接修改这个值就能调整动画时长,比如改成2000就是2秒完成装水timestamp:requestAnimationFrame会自动传入当前时间戳,用于精准计算时间差progress:完全基于时间计算的进度值,不受设备帧率波动影响,能保证动画流畅且按时完成Math.min:避免进度超过1,防止动画结束后出现异常状态
原代码参考
HTML
<div class="glass"> <div class="water"></div> </div>
CSS
.glass { margin: 100px; width: 150px; height: 250px; border: 3px solid #000; border-top: 0; border-bottom-width: 12px } .water { height: 100%; background-color: #BBDEFB; transform: scaleY(0); transform-origin: bottom center; }
内容的提问来源于stack exchange,提问作者wpuzman
相关产品推荐
相关产品推荐

