1. transform
SVG
的transform
属性可实现元素位移(translate
)、缩放(scale
)、旋转(rotate
)、斜切(skew
),它与CSS
中的transform
概念上有很大的相似之处,但也有不同之处,如下:
WARNING
对svg
的元素应用transform
属性,相当于复制了一份基于viewbox
所创建的的坐标系统,后续所有的变形操作将在此 坐标系统上完成。如:位移(translate
)是对坐标系统的位移,而不是对元素的位置;缩放(scale
)是对坐标系统进行的缩放,而不是对元素的缩放……这便是svg transform
与css transform
的不同之处。
2. 位移
语法 translate(<tx> [<ty>])
- tx: 水平方向位移
- ty: 垂直方向位移,缺省值为0
- 源码
<!-- 位移前 -->
<circle cx="50" cy="50" r="30" stroke="red" stroke-dasharray="5 5" fill="none"></circle>
<!-- 位移后 -->
<circle cx="50" cy="50" r="30" fill="red" transform="translate(100,50)"></circle>
2
3
4
3. 缩放
语法 scale(<sx> <sy>)
- sx: 水平方向缩放
- sy: 垂直方向缩放,缺省值=sx
- 源码
<!-- 缩放前 -->
<circle cx="50" cy="100" r="30" stroke="red" stroke-dasharray="5 5" fill="none"></circle>
<!-- 缩放后 -->
<circle cx="50" cy="100" r="30" fill="red" transform="scale(2)" fill-opacity="0.3"></circle>
2
3
4
WARNING
因为缩放是针对整个坐标系统,所以缩放后,圆心坐标位置发生了改变。大部分情况下,我们希望缩放能围绕圆形进行缩放(类似CSS
中的transform-origin
),可通过下面这种方式
translate(cx, cy) scale(1.5) translate(-cx, -cy)
来实现
- 源码
<circle cx="50" cy="100" r="30" stroke="red" stroke-dasharray="5 5" fill="none"></circle>
<circle cx="50" cy="100" r="30" fill="red" transform="translate(50, 100) scale(1.5) translate(-50, -100)" fill-opacity="0.3"></circle>
2
4. 旋转
语法: rotate(<rotate-angle> [<cx> <cy>])
- rotate-angle: 旋转角度
- cx,cy: 旋转中心
- 源码
<!-- 围绕坐标原点旋转 -->
<rect x="30" y="50" width="100" height="50" stroke="red" stroke-dasharray="5 5" fill="none"></rect>
<rect x="30" y="50" width="100" height="50" transform="rotate(15)" fill="red" fill-opacity="0.3"></rect>
<!-- 围绕矩形左上角旋转 -->
<rect x="180" y="50" width="100" height="50" stroke="red" stroke-dasharrya="5 5" fill="none"></rect>
<rect x="180" y="50" width="100" height="50" transform="rotate(15, 180, 50)" fill="red" fill-opacity="0.3"></rect>
<!-- 围绕矩形中心旋转 -->
<!-- 方法一 -->
<rect x="350" y="50" width="100" height="50" stroke="red" stroke-dasharrya="5 5" fill="none"></rect>
<rect x="350" y="50" width="100" height="50" transform="rotate(15, 400, 75)" fill="red" fill-opacity="0.3"></rect>
<!-- 方法二 -->
<!-- <rect x="350" y="50" width="100" height="50" transform="translate(400, 75) rotate(15) translate(-400, -75)" fill="red" fill-opacity="0.3"></rect> -->
2
3
4
5
6
7
8
9
10
11
12
13
14
5. 斜切
语法: skewX(<skew-angle>) skewY(<skew-angle>)
- skewX(<skew-angle>): 水平方向斜切角度
- skewY(<skew-angle>): 垂直方向斜切角度
- 源码
<!-- 围绕坐标原点斜切效果 -->
<rect x="30" y="75" width="100" height="50" stroke="red" stroke-dasharray="5 5" fill="none"></rect>
<rect x="30" y="75" width="100" height="50" transform="skewX(15) skewY(15)" fill="red" fill-opacity="0.3"></rect>
<!-- 围绕矩形左上角斜切效果 -->
<rect x="180" y="75" width="100" height="50" stroke="red" stroke-dasharrya="5 5" fill="none"></rect>
<rect x="180" y="75" width="100" height="50" transform="translate(180, 50) skewX(15) skewY(15) translate(-180, -50)" fill="red" fill-opacity="0.3"></rect>
<!-- 围绕矩形中心斜切效果 -->
<rect x="350" y="75" width="100" height="50" stroke="red" stroke-dasharrya="5 5" fill="none"></rect>
<rect x="350" y="75" width="100" height="50" transform="translate(400, 75) skewX(15) skewY(15) translate(-400, -75)" fill="red" fill-opacity="0.3"></rect>
2
3
4
5
6
7
8
9
10
11
6. transform叠加
tranform
可叠加使用,比如:先(对坐标系)进行位移再进行旋转。需要强调的是后面(对坐标系)的旋转操作是在(对坐标系)位移后的基础上进行的。
WARNING
transform
叠加并不满足交换律,示例中先位移再旋转的效果并不等于先旋转再位移的效果。这个特性跟CSS
中的transform
是一致的。这种特性如果有线性代数的背景知识很好理解:物体在空间内发生运动,可以通过变换矩阵相乘来实现,而矩阵相乘不满足交换律
7. CSS控制transform
使用CSS
也可以对SVG
图形进行控制。可以方便的使用transform-origin
属性来设置比如:旋转中心点,而且通过CSS
可以对SVG
实行3D变换。
7.1 CSS transform 2D
WARNING
注意:使用CSS transform-origin
来设置中心点时,渲染是相对于SVG
坐标系统进行计算的,而不是相对于元素!
- SVG
<!-- transform-origin在元素的左上角 -->
<rect id="target1" x="100" y="70" width="100" height="50"></rect>
<!-- transform-origin在元素的中心 -->
<rect id="target2" x="300" y="70" width="100" height="50" fill="blue"></rect>
2
3
4
5
- CSS
#target1 {
/* (元素x轴坐标,元素y轴坐标) */
transform-origin: 100px 70px;
transform: rotate(30deg);
}
#target2 {
/* (元素x轴坐标 + 元素宽/2,元素y轴坐标 + 元素高/2) */
transform-origin: 350px 95px;
transform: rotate(30deg);
}
2
3
4
5
6
7
8
9
10