变换操作
transform 属性允许你对 SVG 元素进行平移、缩放、旋转和倾斜等变换。这些变换是基于元素自身的坐标系。
变换基础
SVG 的 transform 属性支持以下变换函数:
translate(tx, ty)- 平移scale(sx, sy)- 缩放rotate(angle, cx, cy)- 旋转skewX(angle)- X 轴倾斜skewY(angle)- Y 轴倾斜matrix(a, b, c, d, e, f)- 矩阵变换
基本语法
xml
<rect x="10" y="10" width="50" height="50" transform="translate(20, 30)" />平移 translate
平移变换,将元素沿 x 轴移动 tx,沿 y 轴移动 ty。
语法
xml
translate(tx, [ty])tx: x 轴方向的位移ty: y 轴方向的位移(可选,默认为 0)
示例
xml
<svg width="200" height="100">
<rect x="10" y="10" width="50" height="50" fill="blue" />
<rect x="10" y="10" width="50" height="50" fill="lightblue" transform="translate(70, 10)" />
</svg>缩放 scale
缩放变换。如果只提供一个参数 sx,则在 x 和 y 方向上等比缩放。如果提供 sy,则分别在 x 和 y 方向上缩放。缩放的中心点默认为 (0,0)。
语法
xml
scale(sx, [sy])sx: x 轴方向的缩放比例sy: y 轴方向的缩放比例(可选,默认等于sx)
示例
xml
<svg width="200" height="100">
<rect x="20" y="20" width="50" height="50" fill="green" transform="scale(1.5)" />
</svg>缩放中心点
默认情况下,缩放以原点 (0, 0) 为中心。如果需要以元素中心为缩放中心,需要结合 translate:
xml
<svg width="200" height="200">
<!-- 以元素中心为缩放中心 -->
<rect x="75" y="75" width="50" height="50" fill="red"
transform="translate(100, 100) scale(1.5) translate(-100, -100)" />
</svg>旋转 rotate
旋转变换。angle 是旋转角度。可选的 (cx, cy) 是旋转中心点,默认为元素坐标系的原点 (0, 0)。
语法
xml
rotate(angle, [cx, cy])angle: 旋转角度(度)cx: 旋转中心的 x 坐标(可选)cy: 旋转中心的 y 坐标(可选)
示例
xml
<svg width="200" height="100">
<rect x="70" y="20" width="50" height="50" fill="purple" transform="rotate(45, 95, 45)" />
</svg>以元素中心旋转
xml
<svg width="200" height="200">
<!-- 以元素中心旋转 45 度 -->
<rect x="75" y="75" width="50" height="50" fill="orange"
transform="rotate(45, 100, 100)" />
</svg>倾斜 skew
倾斜变换,分别沿 x 轴和 y 轴倾斜指定的角度。
skewX
沿 x 轴倾斜:
xml
skewX(angle)skewY
沿 y 轴倾斜:
xml
skewY(angle)示例
xml
<svg width="200" height="100">
<rect x="20" y="20" width="50" height="50" fill="orange" transform="skewX(20)" />
</svg>矩阵变换 matrix
matrix 是最强大的变换,它使用一个 3x3 的变换矩阵来描述坐标变换。由于 SVG 中的变换是仿射变换,第三列总是 (0, 0, 1),所以只需要提供 6 个参数。
语法
xml
matrix(a, b, c, d, e, f)变换公式:
code
x' = a*x + c*y + e
y' = b*x + d*y + f这允许你组合任意的平移、缩放、旋转和倾斜。
示例
xml
<svg width="200" height="100">
<rect x="10" y="10" width="50" height="50" fill="red" transform="matrix(1, 0.5, -0.5, 1, 30, 10)" />
</svg>常见变换的矩阵表示
- 平移:
matrix(1, 0, 0, 1, tx, ty) - 缩放:
matrix(sx, 0, 0, sy, 0, 0) - 旋转:
matrix(cos(θ), sin(θ), -sin(θ), cos(θ), 0, 0) - 倾斜:
matrix(1, tan(θy), tan(θx), 1, 0, 0)
组合变换
可以同时应用多个变换,用空格隔开。变换会从右到左依次应用。这意味着最右边的变换最先作用于元素。
语法
xml
transform="transform1 transform2 transform3 ..."执行顺序
变换按照从右到左的顺序执行:
xml
<!-- 先缩放1.2倍,再旋转30度,最后平移 (100, 0) -->
<rect transform="translate(100, 0) rotate(30) scale(1.2)" />示例
xml
<svg width="200" height="100">
<!-- 先缩放1.2倍,再旋转30度,最后平移 (100, 0) -->
<rect x="10" y="10" width="50" height="50" fill="red" transform="translate(100, 0) rotate(30) scale(1.2)" />
</svg>变换原点
默认情况下,变换以元素坐标系的原点 (0, 0) 为中心。可以通过以下方式改变变换原点:
方法 1: 使用 transform-origin (CSS)
xml
<svg width="200" height="200">
<style>
.center-transform {
transform-origin: center center;
}
</style>
<rect class="center-transform" x="75" y="75" width="50" height="50" fill="blue" transform="rotate(45)" />
</svg>方法 2: 使用 translate 组合
xml
<svg width="200" height="200">
<!-- 以元素中心 (100, 100) 为旋转中心 -->
<rect x="75" y="75" width="50" height="50" fill="red"
transform="translate(100, 100) rotate(45) translate(-100, -100)" />
</svg>方法 3: 使用 rotate 的中心参数
xml
<svg width="200" height="200">
<!-- 以 (100, 100) 为旋转中心 -->
<rect x="75" y="75" width="50" height="50" fill="green" transform="rotate(45, 100, 100)" />
</svg>实际应用示例
旋转时钟
html
<svg width="200" height="200">
<circle cx="100" cy="100" r="90" fill="none" stroke="black" stroke-width="2"/>
<!-- 时针 -->
<line x1="100" y1="100" x2="100" y2="50" stroke="black" stroke-width="4"
transform="rotate(0, 100, 100)">
<animateTransform
attributeName="transform"
type="rotate"
from="0 100 100"
to="360 100 100"
dur="43200s"
repeatCount="indefinite"/>
</line>
<!-- 分针 -->
<line x1="100" y1="100" x2="100" y2="30" stroke="black" stroke-width="2"
transform="rotate(0, 100, 100)">
<animateTransform
attributeName="transform"
type="rotate"
from="0 100 100"
to="360 100 100"
dur="3600s"
repeatCount="indefinite"/>
</line>
</svg>缩放动画
html
<svg width="200" height="200">
<rect x="75" y="75" width="50" height="50" fill="blue">
<animateTransform
attributeName="transform"
type="scale"
values="1;1.5;1"
dur="2s"
repeatCount="indefinite"/>
</rect>
</svg>组合变换动画
html
<svg width="200" height="200">
<rect x="75" y="75" width="50" height="50" fill="purple">
<animateTransform
attributeName="transform"
type="translate"
values="0,0;50,50;0,0"
dur="3s"
repeatCount="indefinite"
additive="sum"/>
<animateTransform
attributeName="transform"
type="rotate"
values="0 100 100;360 100 100;0 100 100"
dur="3s"
repeatCount="indefinite"
additive="sum"/>
</rect>
</svg>常见问题
1. 变换会累积吗?
是的,如果元素有多个 transform 属性或动画,变换会累积。可以使用 additive="replace" 来替换而不是累积。
2. transform 和 CSS transform 有什么区别?
- SVG 的
transform是属性,CSS 的transform是样式 - SVG 的 transform 不支持
transform-origin属性 - SVG 的 transform 可以使用 SMIL 动画
3. 如何实现以元素中心为变换原点?
使用 translate 组合:
xml
transform="translate(cx, cy) rotate(angle) translate(-cx, -cy)"