HTML5 入门教程
Canvas 变换与合成
本教程共 110 篇 · 第 84 篇 · 更新于 2026-07-28 · 约 4 分钟阅读
HTML5HTML5 入门教程Canvas变换旋转缩放合成
84. Canvas 变换与合成
本节目标:掌握 Canvas 的坐标变换(平移、旋转、缩放)和图形合成模式。
Canvas 的变换功能让你不用重新计算坐标,就能画出旋转、缩放、偏移的图形。这在做动画和游戏时特别有用。
平移:translate
translate(x, y) 把坐标原点移动到新的位置。
ctx.fillStyle = 'blue';
ctx.fillRect(10, 10, 50, 50); // 原始位置
ctx.translate(100, 100); // 原点移到 (100, 100)
ctx.fillStyle = 'red';
ctx.fillRect(10, 10, 50, 50); // 实际画在 (110, 110)
平移之后,所有后续绘制的坐标都相对于新原点。
Tip平移常用于把旋转中心移到图形中心。比如画一个绕中心旋转的矩形,先平移到中心点,再旋转,然后画矩形。
旋转:rotate
rotate(angle) 旋转坐标系,角度用弧度。
ctx.translate(100, 100); // 把原点移到 (100, 100)
ctx.rotate(Math.PI / 4); // 旋转 45 度
ctx.fillStyle = 'green';
ctx.fillRect(0, 0, 80, 40); // 画一个旋转了 45 度的矩形
旋转是绕原点进行的,所以通常配合 translate 使用。
缩放:scale
scale(x, y) 在 X 和 Y 方向上缩放。
ctx.scale(2, 1); // X 方向放大 2 倍,Y 方向不变
ctx.fillRect(50, 50, 40, 40); // 实际画出 80x40 的矩形
缩放值大于 1 是放大,小于 1 是缩小,负值会翻转。
保存和恢复状态
变换操作会累积。画完一个旋转的图形后,坐标系还是旋转的。这时候需要恢复。
ctx.save(); // 保存当前状态
ctx.translate(100, 100);
ctx.rotate(Math.PI / 6);
ctx.fillRect(0, 0, 50, 50);
ctx.restore(); // 恢复到 save 时的状态
// 现在坐标系又回到原始状态
ctx.fillRect(0, 0, 30, 30); // 正常绘制
save() 把当前状态压入栈,restore() 从栈中弹出。可以嵌套使用。
变换矩阵:transform 和 setTransform
除了上面三个方法,Canvas 还提供了直接操作变换矩阵的接口:
ctx.transform(a, b, c, d, e, f);
参数对应一个 3x3 矩阵(实际只用 6 个值)。大多数情况下用 translate、rotate、scale 就够了。
setTransform 会重置变换矩阵再应用新的变换,不受之前变换的影响:
ctx.setTransform(1, 0, 0, 1, 0, 0); // 重置为单位矩阵
图形合成:globalCompositeOperation
这个属性控制新图形和已有图形的合成方式。
ctx.fillStyle = 'red';
ctx.fillRect(50, 50, 100, 100);
ctx.globalCompositeOperation = 'destination-over';
ctx.fillStyle = 'blue';
ctx.fillRect(80, 80, 100, 100);
常用合成模式:
| 模式 | 效果 |
|---|---|
source-over | 默认,新图形覆盖旧图形 |
destination-over | 旧图形覆盖新图形 |
source-in | 只显示新旧重叠部分的新图形 |
destination-out | 擦除新旧重叠部分的旧图形 |
lighter | 重叠部分颜色叠加变亮 |
xor | 重叠部分变透明 |
Note
destination-out模式常用来”擦除”部分画面,实现橡皮擦效果。
完整示例:画一个时钟刻度
const centerX = 200, centerY = 200;
// 画表盘
ctx.beginPath();
ctx.arc(centerX, centerY, 150, 0, Math.PI * 2);
ctx.stroke();
// 画刻度
for (let i = 0; i < 12; i++) {
ctx.save();
ctx.translate(centerX, centerY);
ctx.rotate((Math.PI * 2 / 12) * i);
ctx.beginPath();
ctx.moveTo(130, 0);
ctx.lineTo(145, 0);
ctx.lineWidth = 3;
ctx.stroke();
ctx.restore();
}
小结
translate平移坐标系原点rotate旋转坐标系(弧度)scale缩放坐标系save/restore保存和恢复状态globalCompositeOperation控制图形合成模式- 变换通常配合使用,先平移再旋转是常见套路