HTML5 Canvas高级动画技巧:从基础到粒子系统实战
一、Canvas动画基础架构
构建高性能Canvas动画的核心循环:
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
function init() {
// 初始化代码
window.requestAnimationFrame(gameLoop);
}
function gameLoop(timestamp) {
// 1. 清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 2. 更新状态
update(timestamp);
// 3. 渲染画面
render();
// 4. 继续循环
window.requestAnimationFrame(gameLoop);
}
function update(timestamp) {
// 更新游戏状态
}
function render() {
// 渲染图形
}
// 启动游戏
init();
二、高效绘制技巧
1. 离屏Canvas优化
// 创建离屏Canvas
const offscreenCanvas = document.createElement('canvas');
const offscreenCtx = offscreenCanvas.getContext('2d');
// 预先绘制复杂图形
offscreenCtx.beginPath();
offscreenCtx.arc(50, 50, 40, 0, Math.PI*2);
offscreenCtx.fillStyle = 'red';
offscreenCtx.fill();
// 主Canvas中重复使用
function render() {
ctx.drawImage(offscreenCanvas, x, y);
}
2. 批量绘制API
// 使用Path2D对象
const circlePath = new Path2D();
circlePath.arc(100, 100, 50, 0, Math.PI*2);
// 批量绘制
ctx.fillStyle = 'blue';
ctx.fill(circlePath);
三、粒子系统实战
实现烟花粒子效果:
class Particle {
constructor(x, y, color) {
this.x = x;
this.y = y;
this.color = color;
this.radius = Math.random() * 3 + 1;
this.velocity = {
x: (Math.random() - 0.5) * 8,
y: (Math.random() - 0.5) * 8
};
this.alpha = 1;
}
draw() {
ctx.save();
ctx.globalAlpha = this.alpha;
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2);
ctx.fillStyle = this.color;
ctx.fill();
ctx.restore();
}
update() {
this.velocity.y += 0.05; // 重力
this.x += this.velocity.x;
this.y += this.velocity.y;
this.alpha -= 0.01; // 渐隐
}
}
// 使用示例
const particles = [];
function createFirework(x, y) {
const color = `hsl(${Math.random()*360}, 100%, 50%)`;
for(let i=0; i<150; i++) {
particles.push(new Particle(x, y, color));
}
}
四、性能优化策略
- 分层渲染:使用多个Canvas叠加
- 脏矩形重绘:只重绘变化区域
- 对象池模式:复用对象减少GC
- 节流控制:限制帧率节省资源
// 对象池示例
const particlePool = [];
function getParticle(x, y, color) {
if(particlePool.length > 0) {
const p = particlePool.pop();
p.x = x;
p.y = y;
p.color = color;
p.alpha = 1;
return p;
}
return new Particle(x, y, color);
}
五、现代浏览器新特性
1. OffscreenCanvas (Web Worker)
// 主线程
const offscreen = canvas.transferControlToOffscreen();
worker.postMessage({ canvas: offscreen }, [offscreen]);
// Worker线程
onmessage = function(e) {
const canvas = e.data.canvas;
const ctx = canvas.getContext('2d');
// 在Worker中渲染
};
2. WebGL混合模式
// 创建WebGL上下文
const gl = canvas.getContext('webgl', {
alpha: false, // 提升性能
antialias: false
});