SVG中的缩放的语法就比较单纯了,就scale(sx[, sy])
, sx
表示横坐标缩放比例,sy
表示纵坐标缩放比例。其中sy
是可缺省的,如果缺失,表示使用和sx
一样的值,也就是等比例缩放。其中,sx
和sy
两个参数可以逗号分隔,也可以使用空格分隔。这和CSS3中的使用有所不同,两外,SVG transform
属性值缩放是不支持scaleX
, scaleY
这些鬼的。
同样的,CSS控制的transform和SVG元素属性控制的transform的坐标系统是不一样的。一个默认元素中心(下图左),一个是SVG画布左上角(下图右),于是(from css-tricks):
因此,当我们对SVG元素scale缩放时候,发现位置也有出乎我们意料,就应该知道是怎么回事了。
rotate
旋转虽然也是迥异坐标,但是其参数自带偏移参数,我们我们移个花接个木,还是可以得到我们想要的结果。但是,scale
缩放这里,就要悲惨很多了,没有自带偏移参数,于是,当我们要实现SVG元素居中缩放的效果,还需要使用translate
手动偏移。
怎么个手动偏移法呢?即使先translate其中心点位置到元素的中心坐标位置,然后缩放,然后坐标再反方向还原回去。例如,某元素中心点坐标是(95, 75)
, 垂直缩放1.5倍的效果则是:
对应的CSS代码就简单多了,直接:
然后最终效果都是一样的:
使用Gif原理示意如下:
先来了解下CSS中的斜切,斜切,如果单纯切一个方向,我们可以看成把矩形变成了平行四边形,其总面积不变化。
以纯X轴变换举例,skewX(-45deg)
则下面这样子(灰色方块为原始位置):
skewX(45deg)
则下面这样子:
对于SVG的skew斜切变换,表现效果原理是一样的。但是,使用的语法却相当有意思。
在前面的一些变换中,例如位移、缩放之类是不支持translateX
, scaleX
这种CSS常见用法的,但是这里的skew
却有点让人哭笑不得:不支持skew(x[, y])
这种语法,而只能是skewX
或者skewY
.
别问我为什么?我只是大自然的搬运工,我不生产语法。
因此,没有:
只有:
同样的,由于变换中心点的差异,CSS实现的变换和SVG属性变换往往最后的位置是不一样的:
不仅如此,如果元素的中心点不是就是SVG的左上角,则skewX(α1) skewX(α2)
的最终位置和skewX(α1 + α2)
是不一样的(位移和旋转不会这样子)。
正如demo所示,CSS的和SVG的位置差异很大:
SVG的连续变换和一次性变换的位置也是不一样的:
可能有人要疑问,为何连续斜切变换和一次性变换位置会不一样?其实原因很简单,因为斜切的角度和元素偏移大小并不是线性的,比方说,从70到80度和80度到90度之间的位移大小(虽然都是10度的变化区间)是显然不是一个档次的。因此,分开多次连续斜切最终的坐标偏移要比一次性偏移来得小。
最后,和缩放一样,你想要让SVG元素中心点斜切,可以先translate
偏移,在skew
变换。就不重复举例演示了。
像缩放、斜切这些SVG变换,想要如CSS transform-origin:50% 50%
一样的中心点变换效果,需要事先位移,我们有没有其他办法呢?
这里有两个思路可供大家参考下。
1. 原始中心位置乃SVG左上角
拿45度旋转举例,我们可以把元素默认就放在中心点和SVG左上角重合的位置上,参见下面的gif演示:
于是,我们原来的3步曲就变成了2步曲:
2. 通过viewBox调整
我们可以把元素默认挂在左上角,然后,通过viewBox
做手脚,让元素呈现的位置并不是真正的左上角,例如应用viewBox='-140 -105 280 210'
,则变化如下示意图:
此时,我们只需要让元素旋转就可以了,无需额外的做translate
位移,见下gif: