blog
blog copied to clipboard
学习 SVG(二)—— 变换
学习 SVG(二)—— 变换
这篇我们来学习一下 SVG 中的变换效果,有点类似 CSS 的 transform,但是 SVG 的变换是属性。
效果列表
| 变换 | 描述 |
|---|---|
| translate(x, y) | 按照指定的 x 和 y 值移动用户坐标系统。如果没有指定 y 值,默认 0。 |
| scale(factor1, factor2) | 使用指定的 factor1 和 factor2 乘以所有的用户坐标系统。比例值可以是小数或者负数。 |
| scale(factor) | 和 scale(factor, factor) 相同。 |
| rotate(angle) | 旋转用户坐标,中心点为 (0, 0)。 |
| rotate(angle, x, y) | 旋转用户坐标,中心点为 (x, y)。 |
| skewX(angle) | 根据指定的 angle 倾斜所有 x 坐标。 |
| skewY(angle) | 根据指定的 angle 倾斜所有 y 坐标。 |
| matrix(a b c d e f) | 设置 6 个值变换矩阵。 |
变换序列
当一个形状上应用了多个变换效果的时候,我们可以认为它将会经过一个变换序列以得到最终的呈现。变换序列中各变换项的顺序对最终的形状呈现有影响。
我们接着先来看一个例子:
<rect width="50" height="50" x="10" y="10" transform="translate(10, 20) scale(2)" style="stroke: black; fill: none" />
<rect width="50" height="50" x="10" y="10" transform="scale(2) translate(10, 20)" style="stroke: red; fill: none" />
这是最终效果:

上图中的网格间距 10 (像素),左上角顶点为原点 (0, 0)。
先应用移动(translate)的黑框矩形最终的位置在 (30, 40) 处,而先应用放大(scale)的红框矩形最终的位置在 (40, 60) 处。这表明了多个变换效果的不同顺序对于形状的最终效果有影响。
坐标轴变换
首先我们先明确下面 4 点:
- translate 效果并不是移动形状本身,而是移动坐标系;
- scale 效果并不是缩放形状本身,而是缩放坐标系;
- rotate 效果并不是旋转形状本身,而是旋转坐标系;
- skewX,skewY 效果并不是倾斜形状本身,而是倾斜坐标系。
其实在形状上应用的变换效果都不是直接作用在形状上,而是对整个坐标系的变换。
这样我们就可以解释上面的例子了:
黑框
- 黑框矩形的原始顶点都在 (10, 10) 处;
- 黑框矩形的移动效果
translate(10, 20)使其坐标系移动 (10, 20),其自身仍在移动后的坐标系 (10, 10) 处; - 黑框矩形的放大效果
scale(2)使其坐标系放大 2 倍,(10, 10) 的顶点落在了放大前坐标系的 (20, 20)处; - 黑框矩形最终落在原坐标系 (10 + 10 + 10, 10 + 20 + 10),即 (30, 40) 处。
红框
- 红框矩形的原始顶点都在 (10, 10) 处;
- 红框矩形的放大效果
scale(2)使其坐标系放大 2 倍,(10, 10) 的顶点落在了放大前坐标系的 (20, 20)处; - 红框矩形的移动效果
translate(10, 20)使其坐标系移动 (10, 20),由于其坐标系已被放大,移动的距离相当于原坐标系 (20, 40) 的距离; - 红框矩形最终落在原坐标系 (10 + 10 + 20, 10 + 10 + 40),即 (40, 60) 处。
变换矩阵
文章一开始的表格中,我们提到了变换矩阵,通过使用 matrix(a b c d e f) 能够达到自定义的变换效果。我们可以通过一个简单公式获取最终的新坐标 x2 和 y2:
x2 = ax + cy + e
y2 = bx + dy + f
矩阵图:
| a c e |
| b d f |
| 0 0 1 |
由于只有 2D 变换,矩阵的第三行值是固定的,所以 matrix 的参数只有 6 个。