登录
首页 >  文章 >  前端

JavaScript实现简单动画技巧【教程】

时间:2026-03-09 14:04:05 395浏览 收藏

前往漫画官网入口并下载 ➜
本文深入解析了JavaScript中实现高性能网页动画的三大核心方法:用requestAnimationFrame替代setTimeout以获得浏览器统一调度的平滑帧率,利用CSS transition实现轻量、硬件加速的声明式动画,以及借助现代Element.animate() API实现可控、可暂停的关键帧动画;同时揭示了left/top等属性引发强制重排的性能陷阱,并强调动画质量的关键在于精准的时间控制、避免主线程阻塞及合理选择渲染属性——真正决定动画成败的,往往不是“如何动”,而是“为何这样动”。

javascript如何实现简单的动画效果?【教程】

requestAnimationFrame 替代 setTimeout 实现平滑动画

直接用 setTimeout 控制样式变化容易掉帧,尤其在页面负载高时。浏览器无法协调绘制时机,导致卡顿或跳变。requestAnimationFrame 会把动画逻辑交给浏览器统一调度,保证每帧在下一次重绘前执行,是 Web 动画的底层推荐方式。

  • 必须在回调函数末尾再次调用 requestAnimationFrame 才能持续执行
  • 不要在回调里做耗时操作(如 DOM 查询、大量计算),否则会挤占渲染时间
  • 可配合 performance.now() 做时间差控制,实现精确的缓动逻辑
let startTime = null;
function animate(timestamp) {
  if (!startTime) startTime = timestamp;
  const elapsed = timestamp - startTime;
  const progress = Math.min(elapsed / 1000, 1); // 持续1秒
  element.style.transform = `translateX(${progress * 200}px)`;
  if (progress <h3>用 <code>transition</code> CSS 属性做声明式位移动画</h3><p>对简单位移、缩放、透明度变化,纯 CSS 更轻量、更稳定,且支持硬件加速。关键不是写动画本身,而是控制触发时机和过渡参数。</p>
  • 必须提前在 CSS 中定义 transition,仅靠 JS 改变 style 不会生效
  • 避免同时过渡多个属性(如 left + top + opacity),优先用 transformopacity
  • 过渡时间单位用 ms 更易控制,例如 transition: transform 300ms ease-out
/* CSS */
.box { transition: transform 250ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
.box.active { transform: translateX(100px); }
<p>/<em> JS </em>/
element.classList.add('active');</p>

animate() API 实现可控的关键帧动画

Element.animate() 是现代浏览器原生支持的 JavaScript 动画接口,比手动管理 requestAnimationFrame 更简洁,且自带播放控制能力(暂停、反向、时间偏移)。

  • 不兼容 IE,Safari 16.4+ 才支持 iterationStart 等高级参数
  • 动画结束后默认不保留最终状态,需显式设置 fill: 'forwards'
  • 传入的 keyframes 对象中,offset 值必须在 0–1 之间,且有序
element.animate(
  [
    { transform: 'scale(1)', opacity: 1 },
    { transform: 'scale(1.2)', opacity: 0.7 }
  ],
  {
    duration: 400,
    fill: 'forwards',
    easing: 'ease-in-out'
  }
);

为什么 left/top 动画性能差?

修改 lefttop 会触发浏览器强制同步布局(layout),每次重排都要重新计算整个文档流,代价远高于只改 transform(只影响合成层)。

  • 即使元素已设 position: absoluteleft 变化仍会引发 layout
  • transform: translateX() 不影响文档流,且大多数情况下走 GPU 合成,帧率更稳
  • 检查工具:Chrome DevTools 的 Rendering 面板打开 “Paint flashing” 和 “FPS meter”,对比两种写法的闪烁区域和帧率波动

复杂动画真正难的不是“怎么动起来”,而是“怎么动得准、停得稳、不抢主线程”。比如缓动函数选错、未清理旧动画句柄、CSS 触发重排却不自知——这些细节比写第一行 requestAnimationFrame 更容易让效果失真。

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于文章的相关知识,也可关注golang学习网公众号。

资料下载
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>