svg坐标系统与变换

733 阅读4分钟

svg与canvas坐标轴

svg的坐标系统和canvas的坐标系统的一致的,左上角是坐标原点,向有是x轴正方向,向下是y轴正方向。如图:

1660876576488.png
webgl的坐标原点在画板中心位置,他是一个右手坐标系,坐标轴示意图如下:

image.png

svg变换

svg变换和css变换基本相同,下面逐个进行介绍

平移

语法和css一样,transform="translate(x,y)",只是有一点需要注意transform不能内联到svg的style里面,这是无效的,必须是元素的属性,如: <rect x="5" y="5" width="300" height="200" transform="translate(30,20)" style="stroke:black;stroke-width: 10;fill:brown;"></rect>

缩放

语法同css:transform="scale(x,y)"这没什么好讲的,这是常用属性。
如果同时使用translate和scale属性,在默认情况下svg和css的表现是不同的。

1660881989769.png在这方面css还是强大的可以改变缩放的中心位置,当给css加上:transform-origin: top left;svg和css表现就一致了。也就是说svg 的缩放默认是以左上角为启示位置,css可以改变起始位置。

旋转

在默认情况下svg旋转是旋转的画布,例如:

    <svg width="1000" height="1000">
        <rect x="500" y="50" width="300" height="200"  style="stroke:black;stroke-width: 10;fill:brown;"></rect>
        <rect x="500" y="50" width="300" height="200" transform="rotate(45)" style="stroke:black;stroke-width: 10;fill:brown;"></rect>
    </svg>

image.png 可以看到svg默认情况下是相对于画布左上角的旋转,css就比较符合人习惯,相对于元素中心旋转。svg旋转的全部语法是:rotate(angle,centerX,centerY),是可以定义中心位置的。

倾斜

语法:skewX(angle),skewY(angle)
<svg width="1000" height="1000"> <rect x="10" y="10" width="300" height="200" transform="skewX(10)" style="stroke:black;stroke-width: 10;fill:brown;"></rect> </svg>

image.png 可以这样理解在垂直的方向出现角度,下一个小节矩阵就会明白,其实个根据angle倾斜所有的x坐标。

矩阵

以上的各种变换其实都是由矩阵实现的,矩阵在计算机图像学里面相当重要,下面详细介绍一下svg中的变换矩阵,即使在css中也有应用,这个是可以触类旁通的,这里假设都学过线性代数,都懂的矩阵的基本知识。
可以这么理解,一阶矩阵表示一维坐标系统,也就是一条直线。二阶矩阵表示一个平面,三阶矩阵表示空间,svg坐标变换都是二维的,但是需要用3阶矩阵进行计算,这是因为使用二阶矩阵来计算无法改变坐标原点,说的更科幻一点,如果真的存在四维空间,上帝使用矩阵方程对我们空间随意变换,只要不进行降维打击,我们永远无法感知到。(时间并不是一个维度,时间其实是运动的集合),扯的有点远了。 线性变换的特点是不改变坐标原点,并且变换都是线性的。线性变换是指:如果两个向量相加,只改变一个变量的大小,相加的结果是线性的。 如果在svg中的坐标是(3,5),那么他的矩阵表示就是 1660987978698.png,1可以理解为z方向上的单位向量。svg的变换矩阵的语法有6个参数,语法如下:matrix( a b c d e f);其实后面还有三个(0 0 1),对于所有的变换矩阵这三个是不会变化的。svg的矩阵如下: image.png 语法是简写形式。

平移矩阵

1660988464337.png例如将点(3,5)平移,那么平移过程如下:

image.png举个例子:

    <svg width="1000" height="1000">
        <rect x="10" y="10" width="300" height="200" transform="matrix(1,0,0,1,60,0)" style="stroke:black;stroke-width: 10;fill:brown;"></rect>
    </svg>

表示向有平移60个单位。

旋转矩阵

旋转其实是旋转坐标轴的z轴,这样就在xy平面旋转的效果。绕z轴旋转,如果r表示旋转半径,α表示原始角度,θ表示旋转角度,旋转前坐标(x,y),旋转后坐标(x1,y1)。有如下等式:
r= y/sinα = x/cosα = y1/sin(α+θ) = x1/cos(α+θ)
由该公式可推到出
x1 = xcosθ - ysinθ
y1 = xsinθ + ycosθ
写成矩阵的形式就是:

image.png 可以看到旋转只是矩阵变换的一种特殊情况。有一点要注意由于svg的旋转不是图像本身的旋转,而是整个坐标轴的旋转,图像旋转后有可能跑到图像外面。写成svg的语法就是matrix(cosθ,sinθ,-sinθ,cosθ,0,0)

矩阵总结

偏移矩阵这里就不介绍了比较简单,这里总结一下用的时候就会一目了然,

image.png
a c e对应x坐标,b d f对应y坐标,a d表示缩放,c d表示偏移,e f控制平移。例如c就是相对于y做偏移。

和css变换的异同

上面说了第一点不同,css变换是相对于元素中心位置的,svg变换是相对于坐标原点的。 css是支持3D变换的。例如在变换外层元素加上perspective(透视距离),css可以出现3D变换效果,(其实css的3D变换可以单独写篇文章)这方面svg是不行的。但是神奇的地方在于,css给的矩阵是6个参数,而不是8个,这就说明css中的矩阵变换和svg是相通的,要想使用css3D变换必须用rotatex,也许工作组人员认为,不会有程序原写3D变换的矩阵吧,确实有点难了。

结束语

本片文章介绍了svg,css,webgl的坐标系统,以及变换关键字和矩阵的关系。svg的矩阵详解,希望对大家有所帮助。