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

如何为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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 19:20:23