Canvas 是 HTML5 提供的一个强大的绘图 API,它允许开发者通过 JavaScript 在网页上绘制图形、动画和游戏等。本文将介绍 Canvas 的基础绘图功能,并分享一些性能优化的实用技巧。
一、Canvas 基础绘图
1. 初始化 Canvas
首先需要在 HTML 中创建 canvas 元素:
html
<canvas id="myCanvas" width="800" height="600"></canvas>
然后通过 JavaScript 获取上下文:
javascript
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
2. 基本绘图方法
绘制矩形
javascript
// 填充矩形
ctx.fillStyle = 'red';
ctx.fillRect(10, 10, 100, 50);
// 描边矩形
ctx.strokeStyle = 'blue';
ctx.lineWidth = 2;
ctx.strokeRect(150, 10, 100, 50);
绘制路径
javascript
ctx.beginPath();
ctx.moveTo(50, 50); // 起点
ctx.lineTo(150, 50); // 第一条线
ctx.lineTo(100, 150); // 第二条线
ctx.closePath(); // 闭合路径
ctx.stroke(); // 描边
绘制圆形/圆弧
javascript
ctx.beginPath();
ctx.arc(200, 200, 50, 0, Math.PI * 2); // 圆心(x,y), 半径, 起始角, 结束角
ctx.fillStyle = 'green';
ctx.fill();
3. 文本绘制
javascript
ctx.font = '30px Arial';
ctx.fillStyle = 'black';
ctx.fillText('Hello Canvas', 50, 300);
ctx.strokeStyle = 'purple';
ctx.strokeText('Stroke Text', 50, 350);
二、性能优化技巧
1. 减少绘制操作
Canvas 性能的关键在于减少绘制操作:
- 合并相似的绘制操作
- 避免在动画循环中频繁创建路径
- 使用
requestAnimationFrame
替代setInterval
或setTimeout
2. 分层 Canvas
对于复杂场景,可以使用多个叠加的 canvas 元素:
html
<div class="canvas-container">
<canvas id="bgCanvas" width="800" height="600"></canvas>
<canvas id="gameCanvas" width="800" height="600"></canvas>
<canvas id="uiCanvas" width="800" height="600"></canvas>
</div>
这样可以将静态背景、动态游戏元素和UI界面分开绘制,避免不必要的重绘。
3. 离屏 Canvas
对于需要重复绘制的复杂图形,可以使用离屏 Canvas:
javascript
// 创建离屏canvas
const offscreenCanvas = document.createElement('canvas');
offscreenCanvas.width = 100;
offscreenCanvas.height = 100;
const offscreenCtx = offscreenCanvas.getContext('2d');
// 在离屏canvas上绘制复杂图形
drawComplexGraphic(offscreenCtx);
// 在主canvas上绘制离屏内容
ctx.drawImage(offscreenCanvas, 0, 0);
4. 合理使用 clearRect
避免清除整个画布,只清除需要更新的区域:
javascript
// 不好 - 清除整个画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 更好 - 只清除需要更新的区域
ctx.clearRect(x, y, width, height);
5. 优化图像绘制
- 预加载所有图像资源
- 使用合适的图像尺寸(不要绘制大图然后缩小)
- 对于重复的图像,使用
createPattern
方法
javascript
const img = new Image();
img.onload = function() {
const pattern = ctx.createPattern(img, 'repeat');
ctx.fillStyle = pattern;
ctx.fillRect(0, 0, canvas.width, canvas.height);
};
img.src = 'texture.png';
6. 减少状态改变
Canvas 的状态改变(如样式、变换等)是昂贵的操作:
javascript
// 不好 - 频繁改变状态
for (let i = 0; i < 100; i++) {
ctx.fillStyle = colors[i];
ctx.fillRect(x[i], y[i], 10, 10);
}
// 更好 - 按状态分组绘制
ctx.fillStyle = 'red';
for (let i = 0; i < redItems.length; i++) {
ctx.fillRect(redItems[i].x, redItems[i].y, 10, 10);
}
ctx.fillStyle = 'blue';
for (let i = 0; i < blueItems.length; i++) {
ctx.fillRect(blueItems[i].x, blueItems[i].y, 10, 10);
}
三、高级技巧
1. 使用 WebGL
对于需要3D或更复杂图形的应用,可以考虑使用 WebGL(通过 canvas.getContext('webgl')
)。
2. 硬件加速
确保浏览器启用了硬件加速,可以通过 CSS 开启:
css
canvas {
transform: translateZ(0);
}
3. 性能监控
使用 performance.now()
来测量绘制时间:
javascript
const start = performance.now();
// 绘制操作
const duration = performance.now() - start;
console.log(`绘制耗时: ${duration}ms`);
结语
Canvas 提供了强大的绘图能力,但要实现高性能的绘图应用需要掌握这些优化技巧。通过减少绘制操作、合理分层、使用离屏渲染等方法,可以显著提升 Canvas 应用的性能表现。在实际开发中,应根据具体场景选择合适的优化策略。