一、纯 CSS 动画(推荐优先使用)
原理:利用 CSS 的 transition(过渡)或 @keyframes(关键帧动画)实现动画。
- transition 过渡
<div class="box"></div>
.box {
width: 100px;
height: 100px;
background: red;
transition: transform 0.5s ease; /* 监听 transform 属性变化 */
}
.box:hover {
transform: translateX(200px); /* 触发动画 */
}
效果:悬停时盒子在 0.5 秒内向右移动 200px。
- @keyframes 关键帧动画
.box {
animation: move 2s infinite alternate; /* 无限循环 + 往返 */
}
@keyframes move {
0% { transform: translateX(0); }
100% { transform: translateX(200px); }
}
效果:盒子在 2 秒内循环左右移动。
二、Web Animations API(现代浏览器支持)
原理:通过 JavaScript 直接操作元素的 animate() 方法控制动画。
const box = document.querySelector('.box');
box.animate(
[
{ transform: 'translateX(0)' }, // 起始帧
{ transform: 'translateX(200px)' } // 结束帧
],
{
duration: 1000, // 动画时长 1 秒
iterations: Infinity, // 无限循环
easing: 'ease-in-out' // 缓动函数
}
);
三、requestAnimationFrame(精准帧控制)
原理:与浏览器刷新率同步(通常 60fps),避免 setTimeout 的帧率不稳定问题。
function animate(startTime) {
const duration = 1000; // 动画时长 1 秒
const element = document.querySelector('.box');
function step(timestamp) {
if (!startTime) startTime = timestamp;
const progress = timestamp - startTime;
const translateX = (progress / duration) * 200; // 计算位移
if (progress < duration) {
element.style.transform = `translateX(${translateX}px)`;
requestAnimationFrame(step); // 递归调用下一帧
}
}
requestAnimationFrame(step);
}
animate(); // 启动动画
四、SVG SMIL 动画(适合矢量图形)
原理:直接在 SVG 标签中定义动画。
<svg width="300" height="100">
<rect x="0" y="0" width="100" height="100" fill="red">
<animate
attributeName="x"
from="0"
to="200"
dur="1s"
repeatCount="indefinite"/>
</rect>
</svg>
效果:红色矩形在 1 秒内循环水平移动。
总结
优先使用 CSS 动画:性能最优,开发效率高。
需要动态控制时:选择 Web Animations API。
完全定制化需求:使用 requestAnimationFrame。
SVG 动画:仅在需要矢量图形时使用。
性能关键点:避免使用 JavaScript 的 setTimeout/setInterval,它们会导致 布局抖动(Layout Thrashing) 和 帧率不稳定。