变换矩阵 – SVG 代码示例

SVG transformation matrix 用一个 matrix(a,b,c,d,e,f) transform 表达平移、缩放、旋转和倾斜。当多个变换需要组合、计算或从图形工具导出时,它很有用。如果你只需要简单移动、调整大小或旋转, SVG Transformations 中的单独 transform functions 通常更易读。

本文将学习:

  • 读取 matrix(a,b,c,d,e,f) 中的六个值。
  • 使用 matrix 值进行平移、缩放、旋转和 skewing。
  • 围绕指定 pivot point 缩放或旋转。
  • 避免与原点、顺序和 skew 值相关的常见矩阵错误。
  • 在可读的 transform functions 和计算得到的 matrix 之间做选择。

Transformation Matrix Basics

SVG transformation matrix 是一个 3 × 3 矩阵,用于组合平移、缩放、旋转和倾斜。但在 SVG matrix(a,b,c,d,e,f) 语法中只写前六个值:

变换矩阵是 3x3 矩阵

参数典型用途SVG 符号
aX 轴缩放因子,或旋转角的余弦值sx / cos(α)
bY 轴 skew 因子,或旋转角的正弦值tan(α) / sin(α)
cX 轴 skew 因子,或旋转角的负正弦值tan(α) / -sin(α)
dY 轴缩放因子,或旋转角的余弦值sy / cos(α)
eX 轴平移tx
fY 轴平移ty

矩阵把点 (x prev, y prev) 转换为 (x new, y new):

使用变换矩阵计算坐标的公式

SVG 元素通过 transform 属性使用矩阵语法。因此,你向 matrix transformation function 提供 6 个值,用于设置平移、缩放、旋转和 skewing:

transform="matrix(a,b,c,d,e,f)"

如何使用 SVG Transformation Matrix

  1. 从 identity matrix 开始:matrix(1 0 0 1 0 0)
  2. 修改 ef,按 txty 平移元素。
  3. 修改 ad,沿 x 轴和 y 轴缩放。
  4. abcd 中使用 sine 和 cosine 值进行旋转。
  5. 根据目标轴使用 bc 进行 skewing。
  6. 当需要围绕 (0,0) 以外的 pivot point 缩放或旋转时,调整 ef

Translation Matrix

translation 是 SVG 中把对象所有点沿平行线移动相同距离的变换。它会平移元素坐标系统的原点。translation matrix 如下:

Translation matrix 公式

matrix(1,0,0,1,tx,ty)

translation matrix 结合 txty,使元素水平和垂直移动。它让对象沿 x 轴移动 tx,沿 y 轴移动 ty

下面示例展示原始蓝色圆沿 x 轴平移(红色)、沿 y 轴平移(橙色)以及同时沿两个轴平移(绿色):

 1<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
 2    <g fill="none">
 3        <!-- no translation -->
 4        <circle cx="15" cy="15" r="10" stroke="blue" />
 5        <!-- horizontal translation (tx = 30) -->
 6        <circle cx="15" cy="15" r="10" stroke="red" transform="matrix(1 0 0 1 30 0)" />
 7        <!-- vertical translation (ty = 25) -->
 8        <circle cx="15" cy="15" r="10" stroke="orange" transform="matrix(1 0 0 1 0 25)" />
 9        <!-- both horizontal and vertical translation (tx = 30, ty = 25) -->
10        <circle cx="15" cy="15" r="10" stroke="green" transform="matrix(1 0 0 1 30 25)" />
11    </g>
12</svg>

属性 transform="matrix(1,0,0,1,tx,ty)" 的作用是按下面公式改变对象坐标:

x(new) = a·x(prev) + c·y(prev) + e = x(prev) + tx
y(new) = b·x(prev) + d·y(prev) + f = y(prev) + ty

代码中,<g> 元素组合圆形,fill="none" 应用于 group 内每个圆。下图显示原始圆和三个平移副本:

四个圆展示 translation transformation

Scaling Matrix

Scaling 是使用缩放因子放大或缩小对象的 SVG transformation。scaling matrix 可沿坐标轴进行等比或非等比缩放。sxsyxy 轴缩放因子。如果 sxsy 大于 1,对象会放大;如果在 0 和 1 之间,对象会缩小。如果两个缩放因子不同,对象会产生拉伸或压缩效果。scaling matrix 如下:

Scaling matrix 公式

matrix(sx,0,0,sy,0,0)

下面示例展示原始蓝色矩形相对于原点 (0,0) 的等比缩放和非等比缩放(图 a 和 b),以及相对于点 (10,10) 的等比缩放(图 c):

1<svg viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg">
2    <!-- uniform scale is shown in fig.a -->
3    <g fill="none">
4        <rect x="10" y="10" width="20" height="20" stroke="blue" />
5        <rect x="10" y="10" width="20" height="20" stroke="red" transform="matrix(1.5,0,0,1.5,0,0)" />
6        <rect x="10" y="10" width="20" height="20" stroke="orange" transform="matrix(2,0,0,2,0,0)" />
7        <rect x="10" y="10" width="20" height="20" stroke="green" transform="matrix(0.7,0,0,0.7,0,0)" />
8    </g>
9</svg>

结果如下:

四个矩形展示 scaling transformation

上面的代码使用 scaling matrix。第一组显示等比缩放(fig. a),第二组显示非等比缩放(fig. b),第三组显示围绕点 (10, 10) 的等比缩放(fig. c)。

注意: 缩放相对于坐标系统原点 (0,0) 执行。如果 SVG 对象不在原点,缩放也会改变它的可见位置。这就是图 a 和图 b 中矩形看起来移动的原因。

要围绕特定 pivot point (cx, cy) 缩放,需要给缩放后的形状加入额外移动,使它回到 pivot point(fig. c)。组合 translation 和 scaling 的完整矩阵为:

matrix(sx,0,0,sy,cx·(1-sx),cy·(1-sy))

该矩阵会围绕 pivot point (cx, cy) 正确缩放对象,而不会产生额外位移。cx·(1-sx)cy·(1-sy) 系数提供必要的平移补偿,确保对象缩放后保持在原位置。以图 c 中的红色矩形为例,pivot point (cx, cy) 为 (10,10),即蓝色初始矩形的左上角:

cx·(1-sx)=10·(1-1.5)=10·(-0.5)=-5
cy·(1-sy)=10·(1-1.5)=10·(-0.5)=-5

Rotation Matrix

rotation matrix 使用旋转角的 sine 和 cosine:

Rotation matrix 公式

matrix(cos(α),sin(α),-sin(α),cos(α),0,0),其中 α 是围绕初始坐标系统中 (0,0) 点的角度。

下面示例展示初始蓝色矩形旋转 90°(绿色)、180°(灰色)、270°(teal)、-45°(红色)和 135°(橙色):

 1<svg viewBox="-50 -50 200 200" xmlns="http://www.w3.org/2000/svg">
 2    <g>
 3      <rect x="0" y="0" width="20" height="20" fill="blue" />
 4      <rect x="0" y="0" width="20" height="20" fill="green" transform="matrix(0,1,-1,0,0,0)" />
 5      <rect x="0" y="0" width="20" height="20" fill="grey" transform="matrix(-1,0,0,-1,0,0)" />
 6      <rect x="0" y="0" width="20" height="20" fill="teal" transform="matrix(0,-1,1,0,0,0)" />
 7      <rect x="0" y="0" width="20" height="20" fill="red" transform="matrix(0.7071,-0.7071,0.7071,0.7071,0,0)" />
 8      <rect x="0" y="0" width="20" height="20" fill="orange" transform="matrix(-0.7071,0.7071,-0.7071,-0.7071,0,0)" />
 9    </g>
10</svg>

注意: 正角度表示顺时针旋转,负角度表示逆时针旋转。

SVG rotation 的结果如下图:

六个矩形展示 rotation transformation

注意: 下面的矩阵会围绕 pivot point (cx, cy) 旋转对象:

matrix(cos(α), sin(α), -sin(α), cos(α), cx·(1-cos(α))+cy·sin(α), cy·(1-cos(α))-cx·sin(α))

cx·(1-cos(α))+cy·sin(α)cy·(1-cos(α))-cx·sin(α) 系数提供围绕 pivot point 旋转所需的平移补偿。以图 c 中红色矩形为例,pivot point (cx, cy) 是 (5,5),即蓝色初始矩形的左上角,红色矩形的角度为 -45°:

cos(-45°)=0.7071, sin(-45°)=-0.7071

cx·(1-cos(α))+cy·sin(α)=5·(1-0.7071)+5·(-0.7071)=-2
cy·(1-cos(α))-cx·sin(α)=5·(1-0.7071)-5·(-0.7071)=5

Skewing Matrix

Skewing 是让元素坐标系统的某个轴按角度 α 顺时针或逆时针倾斜的变换。SVG 元素可以通过 skewing matrix 倾斜:

沿 x 轴变换的 skew matrix 公式

matrix(1,0,tan(α),1,0,0) – 该 skew matrix 表示沿 x 轴按 α 度倾斜。

沿 y 轴变换的 skew matrix 公式

matrix(1,tan(α),0,1,0,0) – 该 skew matrix 表示沿 y 轴按 α 度倾斜。

下面展示带 skew transformations 的圆示例:

 1<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
 2    <g fill="none">
 3        <circle cx="20" cy="20" r="10" stroke="blue" />
 4        <!-- skew transformation along the x-axis by α=45° -->
 5        <circle cx="20" cy="20" r="10" stroke="red" transform="matrix(1,0,1,1,0,0)" />
 6    </g>
 7    <g fill="none" transform="translate(70)">
 8        <circle cx="20" cy="20" r="10" stroke="blue" />
 9        <!-- skew transformation along the y-axis by α=45° -->
10        <circle cx="20" cy="20" r="10" stroke="orange" transform="matrix(1,1,0,1,0,0)" />
11    </g>
12</svg>

渲染结果如下:

原始圆和应用 skew transformation 后的圆

注意: 角度 α 表示以度为单位的 skew transformation。使用 x-axis skew matrix 时,x 坐标改变而 y 坐标保持不变。使用 y-axis skew matrix 时,y 坐标改变而 x 坐标保持不变。

Common Mistakes and Fixes

问题原因解决方法
变换生效但对象意外移动变换相对于原点 (0,0) 应用在缩放或旋转前,把对象平移到目标 pivot point
围绕错误点旋转rotation matrix 没有补偿平移在一个矩阵中组合 translation → rotation → reverse translation
缩放改变了位置缩放时未调整平移值调整 ef,或围绕特定点缩放
Matrix 没有可见效果matrix 值错误或等于 identity matrix确认 matrix 值不同于 1 0 0 1 0 0
多个 transforms 相互覆盖matrix 替换了之前的 transform 操作把变换组合成单个 matrix,或按正确顺序应用
Skewing 异常bc 值错误确认 skew 值是有意设置,并匹配目标角度
变换难以调试matrix 值难以理解从简单变换(translate、scale)开始,逐步构建

Quick Recipes

Transformation Matrix Cheat Sheet

目标Matrix说明
无变换(identity)matrix(1 0 0 1 0 0)重置所有变换
平移 (tx, ty)matrix(1 0 0 1 tx ty)移动对象,不缩放或旋转
等比缩放 smatrix(s 0 0 s 0 0)相对于原点缩放
按 (sx, sy) 缩放matrix(sx 0 0 sy 0 0)非等比缩放
围绕点 (cx, cy) 缩放matrix(s 0 0 s cx*(1-s) cy*(1-s))保持中心点固定
围绕原点旋转 θmatrix(cosθ sinθ -sinθ cosθ 0 0)θ 以弧度计算
围绕点 (cx, cy) 旋转matrix(cosθ sinθ -sinθ cosθ cx-cx*cosθ+cy*sinθ cy-cx*sinθ-cy*cosθ)常见旋转场景
水平 skew θmatrix(1 0 tanθ 1 0 0)沿 x 轴倾斜
垂直 skew θmatrix(1 tanθ 0 1 0 0)沿 y 轴倾斜

六个 matrix 值作为一个 transform 一起工作,并在当前 SVG 坐标系统中解释。

实用 SVG 示例

按 (tx, ty) 平移对象

1<rect x="50" y="50" width="100" height="60" transform="matrix(1 0 0 1 40 30)" />

等比放大 2 倍

1<rect x="50" y="50" width="80" height="40" transform="matrix(2 0 0 2 0 0)" />

围绕中心缩放对象

1<rect x="50" y="50" width="100" height="60" transform="matrix(2 0 0 2 -100 -80)" />

围绕原点旋转 45°

1<rect x="50" y="50" width="100" height="60" transform="matrix(0.707 0.707 -0.707 0.707 0 0)" />

应用水平 skew

1<rect x="40" y="40" width="120" height="60" transform="matrix(1 0 0.5 1 0 0)" />

FAQ – SVG Transformation Matrix

SVG 中 matrix(a,b,c,d,e,f) 是什么意思?

matrix(a,b,c,d,e,f) 是 SVG transform function,用六个值存储缩放、skewing、旋转和平移。abcd 影响缩放、skew 和旋转;ef 移动元素。

SVG 中的 identity matrix 是什么?

identity matrix 是 matrix(1 0 0 1 0 0)。它让元素保持不变,是逐步构建 transformation matrix 的有用起点。

为什么 matrix transform 会让对象意外移动?

Matrix transformations 相对于当前坐标系统原点应用。对远离 (0,0) 的对象缩放或旋转时,如果 ef 没有补偿 pivot point,可见位置也会改变。

应该使用 matrix() 还是单独的 transform functions?

当希望 SVG 标记易读时,使用 translate()scale()rotate() 等单独函数。当值来自计算、由工具导出,或需要把多个变换合成一个 transform 时,使用 matrix()

规范和相关资源