Canvas 的 translate() 方法移动的是坐标系原点而非画布或图形,调用后所有绘图坐标均相对于新原点;需配合 save()/restore() 避免变换累加混乱,并支持以中心为锚点的语义化绘制。

Canvas 的 translate() 方法不是移动画布本身,而是移动坐标系原点,从而让后续所有绘图操作都基于新的“相对坐标”进行。理解这一点,是实现灵活、模块化绘制的关键。
translate 改变的是坐标系,不是图形位置
调用 ctx.translate(x, y) 后,坐标原点 (0, 0) 会从左上角移到当前点 (x, y)。之后你画的 rect(10, 10, 20, 20),实际出现在画布上的位置是 (x+10, y+10) —— 因为这个 (10, 10) 是相对于新原点的坐标。
常见误区:以为 translate 是把图形“拖过去”。其实图形始终按代码写的坐标画,只是坐标系被平移了。
配合 save() 和 restore() 实现局部坐标系
多次平移容易导致坐标混乱,尤其在绘制多个独立对象(如按钮、图标、角色)时。推荐用 save() 保存当前状态,平移后绘制,再用 restore() 恢复原坐标系:
立即学习“前端免费学习笔记(深入)”;
ctx.save();-
ctx.translate(100, 50);→ 原点移到 (100, 50) -
ctx.fillRect(0, 0, 30, 30);→ 绘制在 (100, 50) 到 (130, 80) -
ctx.restore();→ 坐标系回到初始状态
这样每个组件都可以用 (0, 0) 作为自己的“本地锚点”,逻辑清晰,便于复用和位移调整。
用 translate 实现“以中心为原点”的绘制
默认 Canvas 以左上为原点,但很多图形(如圆形、旋转图标)更习惯以中心为参考。可先平移到目标中心点,再绘制,再反向平移(或用 save/restore):
- 想在 (200, 150) 画一个半径 20 的圆,且希望 (0, 0) 就是圆心:
ctx.save();ctx.translate(200, 150);-
ctx.arc(0, 0, 20, 0, Math.PI * 2);→ 圆心就在 (0, 0),即画布上的 (200, 150) ctx.restore();
这种写法比直接写 arc(200, 150, 20, ...) 更具语义性,也方便后续叠加旋转、缩放等变换。
注意:translate 累加,需谨慎重置
连续调用 translate(10, 10); translate(20, 30);,等效于一次 translate(30, 40)。如果忘记恢复或重置,后续所有绘图都会偏移。
安全做法:
- 优先使用
save()/restore()包裹平移段落 - 避免跨函数隐式依赖当前变换状态
- 调试时可用
ctx.setTransform(1, 0, 0, 1, 0, 0)彻底重置变换(清除所有平移、旋转、缩放)
不复杂但容易忽略:每次平移都是对当前变换矩阵的追加,不是覆盖。



















