事先说明,本文范畴尚限制在2D的transform中。
对于css3的transform属性,真是爱不释手,有了这个特性,各种特效轻松搞定。引用一句歌词“旋转,跳跃,我不停歇”。transform就是这么时尚,就是这么任性。当然他任性的地方不只是在功能方面,还有在使用方面。我们看一下W3C官网中关于transform 2D的使用介绍。
看着有点多,首先先来分类一下:一个matrix,三个translate,三个scale,三个skew,一个rotate。而三个translate中又分为针对于XY,X,Y三样。对于这几个操作之间的关系,我画了一张图来粗暴的展现。
看到这也许有人疑惑为什么matrix会在其他所有操作的最顶端,其实除了matrix的其他操作都是属于对matrix的一个拓展,什么意思呢?translate、scale、skew和rotate这几个操作都是拿出来给不懂matrix原理的人用的,怕你不懂原理,所以封装了几个方法出来,让你便捷的使用matrix方法。何以证明?有兴趣的童鞋可以去查看该元素的样式(注:不是class规则,是计算后的样式),或者输出该元素的transform属性。看看是不是得到都是统一的matrix的结果,类似于:
matrix(1, 0.466307658154999, 0, 1, 0, 0)
不罗嗦了,既然这是个操作最终都是归于matrix,那么他们之间的关系是什么呢?如果我用矩阵的知识告诉大家是如何计算的,就不符合本文的标题了,而且这类文章已经有很多了,我也就不献丑了,还是坚持标题的原则:简单粗暴的解释。
首先说translate,翻译过来就是“转移”。首先解释一下translate的语法:
transform:translate(25px,26px)
,意思是向右向下各位移25像素和26像素,然后我们转换为matrix的语法来看这行语句:
transform: matrix(1, 0, 0, 1, 25, 26);
眼尖的童鞋应该已经发现问题了,最后的25和26就代表了X轴和Y轴的位移有兴趣的童鞋可以自己去尝试分别的X位移和Y位移,这里不拿来占篇幅了,当然这里还要强调一下transform的初始值,也就是没有任何转换的时候matrix的默认值是:transform: matrix(1, 0, 0, 1, 0, 0);,以免下面的解释大家看不懂。
然后再就是scale,我习惯翻译成“缩放”,这样翻译也是对应于他的功能:缩放组件。演示一下语法:
transform:scale(1.1,1.2);
同样我们看一下转换成matrix格式的语句:
transform: matrix(1.1, 0, 0, 1.2, 0, 0);
显而易见,这里的X的缩放和Y轴的缩放分别对应matrix中的第一个值和第四个值,他们的值对应的所表达的意思是放大多少倍。还是一样,针对于X轴和Y轴的单独测试就不做了。
我们再来看看skew,我给翻译成“倾斜”,skew的功能就是让组件倾斜一定的角度,可以用来画平行四边形,向之前有见过“带惯性运动”的就是通过这个实现的,演示Skew用单个来演示比较靠谱
transform: skewX(45deg); transform: skewY(45deg);
对应matrix格式的语句是:
transform: matrix(1, 0, 1, 1, 0, 0); transform: matrix(1, 1, 0, 1, 0, 0);
发现问题了吗?X向倾斜对应的是改变第三个值,Y向倾斜对应的是改变第2个值,然后我来解释一下这个值的意思,这个值就是需要偏转的角度的tan值,需要旋转45°角,对应的就是1了,有兴趣可以试试其他值来验证。
到此,我们就了解了matrix的六个值分别代表的意义:
第一个元素:X轴放大倍数
第二个元素:Y向倾斜角度的tan值
第三个元素:X向倾斜角度的tan值
第四个元素:Y轴放大的备注
第五个元素:向右偏移的像素大小
第六个元素:向下偏移的像素大小。
说到这里还不算完,还有一个ratate没有解释,在解释之前先看一个插图:
这两幅图看起来效果差不多是吗?确实差不多,不过不同的地方在于上面的图是通过rotate实现的,而下面的图是通过skew实现的,就是旋转45度角了,分别拿两个生成后的样式来看:
transform: matrix(0.707106781186548, 0.707106781186548, -0.707106781186548, 0.707106781186548, 0, 0); transform: matrix(1, 0.466307658154999, 0.466307658154999, 1, 0, 0);
看到这,很多人的疑问就出来了,这一堆小数点分别是什么?上面的0.7指的是 根号2 分之一,也就是cos45°或者sin45°,那么这两种计算方式究竟是怎么回事呢?这得回到matrix实现的原理上去解释,我简单的说下transform的原理:首先寻找一个中心点(默认是最中间),然后计算每个像素相对于该点的坐标(100*100的左上角就是-50,50),然后获取matrix传入的六个值和0,0,1组成一个新的矩阵,再和原坐标组成的矩阵进行运算得到一个新的矩阵,然后再在新的矩阵中获取新的X坐标和新的Y坐标。
好吧,说成这样已经不简单了,有点偏离我的标题,还是简单粗暴来解释了,上面matrix替换为:(a,b,c,d,e,f)六个值,然后根据中心点计算每个像素的相对坐标,然后计算新的坐标,新坐标的计算公式为:
x‘ = a * x + c * y + e; y‘ = b * x + d * y + f;在rotate的时候传入的分别是cosθ,sinθ,sinθ和cosθ,而skew传入的值则是:cosθ/consθ
, sinθ/cosθ , sinθ/cosθ , cosθ/cosθ。所以这也是为什么在使用skew进行旋转的时候图像会放大了根号2倍。
其实正常情况下,使用前面说的六种计算方式来使用matrix公式就够用了本文最后面这部分仅是为了文章的完整性而写,却反倒失去了简单粗暴的原则。