requestAnimationFrame 是实现轻量级关键帧动画的最佳选择,比 setInterval 和 setTimeout 更精准省资源,需手动管理关键帧数组并实时线性插值计算中间状态。

用 requestAnimationFrame 实现最简关键帧动画
HTML5 本身不提供“建模动画”功能,所谓“HTML5建模动画”实际是用 Canvas 或 SVG + JavaScript 控制图形状态随时间变化。最轻量、最可控的方式就是手动管理关键帧,靠 requestAnimationFrame 驱动循环。
它比 setInterval 更精准、更省资源,且自动适配屏幕刷新率。浏览器会在下次重绘前调用回调,避免丢帧或卡顿。
- 必须用
requestAnimationFrame替代setTimeout做主循环,否则动画会抖动或掉帧 - 关键帧数据建议存为数组,每个元素含
time(毫秒)、state(如{ x: 100, scale: 1.2 }) - 动画播放时需实时插值:根据当前时间戳,在两个相邻关键帧之间线性计算中间状态
Canvas 中绘制位移+缩放关键帧的最小示例
以下代码在 上让一个矩形从左到右平移,同时轻微缩放——只依赖原生 API,无框架。
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const frames = [
{ time: 0, state: { x: 0, y: 100, scale: 1.0 } },
{ time: 1000, state: { x: 300, y: 100, scale: 1.3 } },
{ time: 2000, state: { x: 600, y: 100, scale: 1.0 } }
];
let startTime = null;
function animate(timestamp) {
if (!startTime) startTime = timestamp;
const elapsed = timestamp - startTime;
const t = elapsed % 2000; // 循环播放
// 查找当前应处的关键帧区间
let i = 0;
while (i < frames.length - 1 && frames[i + 1].time <= t) i++;
const a = frames[i];
const b = frames[i + 1] || a;
// 线性插值
const alpha = (t - a.time) / (b.time - a.time || 1);
const x = a.state.x + (b.state.x - a.state.x) alpha;
const y = a.state.y + (b.state.y - a.state.y) alpha;
const scale = a.state.scale + (b.state.scale - a.state.scale) * alpha;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(x, y);
ctx.scale(scale, scale);
ctx.fillStyle = '#4a90e2';
ctx.fillRect(-20, -15, 40, 30);
ctx.restore();
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
SVG + CSS 关键帧动画的适用边界
如果动画只是简单位移、旋转、透明度变化,且不需要运行时动态计算或响应用户交互,直接用 SVG 内联 或外联 CSS @keyframes 更省事。但要注意限制:
立即学习“前端免费学习笔记(深入)”;
-
不支持 easing 函数自定义(仅linear/discrete),也不支持 JS 动态修改关键帧 - CSS 动画作用于 SVG 元素时,
transform必须写全(如transform: translate(100px) scale(1.2)),不能只写translateX - 无法对路径
d属性做关键帧插值(浏览器不支持),想变形得用或 JS 逐点计算
为什么不用 Three.js 做“HTML5建模动画”?
Three.js 是 WebGL 渲染器,适合 3D 模型(glTF)、光照、材质等复杂场景。但如果你只是想让几个图形按时间移动、变色、缩放——引入 Three.js 就像为切菜买整套数控机床。
真正需要它的信号只有两个:
– 你有 .glb 模型文件要加载
– 你需要摄像机视角控制或阴影/反射等物理效果
否则,Canvas 2D 或 SVG + JS 足够,体积小、启动快、调试直观。很多所谓“HTML5建模动画演示”,背后只是用 Path2D 绘制贝塞尔曲线再做 strokeDashoffset 动画,根本没建模这回事。











