Canvas图形变换进阶:运用setTransform实现矩阵变换

作者:袖梨 2026-06-20
要用 setTransform 实现稳定、可预测的 Canvas 图形变换,关键不是叠加操作,而是每次从干净的单位矩阵出发,直接设定全部变换效果;它先重置为单位矩阵再应用参数,不累积误差,绕任意点旋转或缩放可用一步公式计算参数,配合 save/restore 可避免状态污染,与 transform() 的叠加机制有本质区别。

要用 setTransform 实现稳定、可预测的 Canvas 图形变换,关键不是叠加操作,而是每次从干净的单位矩阵出发,直接设定你想要的全部变换效果。

setTransform 的作用机制

setTransform(a, b, c, d, e, f) 会先清空当前所有变换(重置为单位矩阵 [1,0,0,1,0,0]),再应用你传入的这组参数。它不依赖之前的状态,也不累积误差。

  • 参数 a 和 d 控制 x、y 方向缩放
  • 参数 b 和 c 控制倾斜(旋转也通过它们体现)
  • 参数 e 和 f 是最终平移量(单位像素),已包含坐标系旋转/缩放后的偏移修正

绕任意点旋转或缩放的一步写法

想让图形绕自身中心 (cx, cy) 旋转 θ 弧度,不用 translate-rotate-translate 三步,直接用公式算出 setTransform 参数:

  • a = cos(θ),b = sin(θ)
  • c = -sin(θ),d = cos(θ)
  • e = cx − cx×cos(θ) + cy×sin(θ)
  • f = cy − cx×sin(θ) − cy×cos(θ)

例如:绕点 (100, 80) 顺时针转 45°(即 −π/4 弧度),代入后调用 setTransform 即可生效,后续 draw 就自动按新坐标系绘制。

避免污染后续绘图的关键习惯

Canvas 的变换状态是全局持续的,一次 setTransform 会影响之后所有绘制,直到被覆盖或重置。

  • 每次使用前加 ctx.save()
  • 设置完立即调用 ctx.setTransform(...)
  • 绘图完成后必须跟 ctx.restore()

这样能确保文字、边框、图标等不同元素互不干扰。漏掉 save/restore 是图形错位最常见原因。

和 transform() 的本质区别

transform() 是“在已有变形上再叠加”,矩阵右乘,容易越调越歪;setTransform() 是“彻底换一套规则”,左乘单位矩阵,结果完全由你控制。

  • 做动画或频繁更新时,优先选 setTransform()
  • 需要复用同一套变换多次,就封装成函数,内部含 save/setTransform/restore
  • 临时清空所有变换,可用 ctx.resetTransform()(等价于 setTransform(1,0,0,1,0,0))

相关文章

精彩推荐