上一篇介绍了transform变形属性,其实一系列变形函数的本质都是matrix矩阵运算,本篇就来看看究竟是怎么运算后产生各种变形效果的。
先看看容易点的2D矩阵matrix,共有6个参数matrix(a, b, c, d, e, f),各参数在矩阵中的位置:
元素原本的XY轴坐标经matrix变换后,新坐标为x1,y1。计算公式如下:
这是线性代数里最简单的内容了,虽然难一点的线性代数的知识全还给老师了,但这点应该不难理解,横行乘竖行。
以translate位移举例。想将其在XY轴上相对原点位置位移,很简单translate(tx, ty);
即可。你也可以用matrix实现。原点坐标为xy,经translate位移后新坐标需要为x1=x+tx,y1=y+ty。根据上图,等价于matrix(1,0,0,1,tx,ty);
。例如translate(50px, 100px);
等价于matrix(1,0,0,1,50,100);
同理scale缩放后新坐标需要为x1=x*sx,y1=y*sy,因此等价于matrix(sx,0,0,sy,0,0);
。例如scale(0.5, 1.5);
等价于matrix(0.5,0,0,1.5,0,0);
位移和缩放比较简单,rotate旋转将元素旋转一个角度稍微复杂点。旋转后各像素的新坐标需要为x1=cos(a)*x-sin(a)*y,y1=sin(a)*x+cos(a)*y,因此等价于matrix(cos(a),sin(a),-sin(a),cos(a),0,0);
。例如rotate(45deg);
等价于matrix(0.53,0.85,-0.85,0.53,0,0);
(cos(45)=0.53,sin(45)=0.85)
skew扭曲后各像素新坐标需要为x1=x+tan(ax)*y,y1=tan(ay)*x+y,因此等价于matrix(1,tan(ay),tan(ax),1,0,0);
。例如skew(45deg);
等价于matrix(1, 0, 1, 1, 0, 0);
(tan(45)=1)
弄了个表:
transform | matrix |
---|---|
translate(tx, ty); | matrix(1, 0, 0, 1, tx, ty); |
scale(sx, sy); | matrix(sx, 0, 0, sy, 0, 0); |
rotate(a); | matrix(cos(a), sin(a), -sin(a), cos(a), 0, 0); |
skew(ax, ay); | matrix(1, tan(ay), tan(ax), 1, 0, 0); |
有了2D矩阵matrix的基础后,再看3D矩阵matrix3d能稍微容易理解点。不废话了直接W3C上图
translate3d(tx,ty,tz)等价于matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,tx,ty,tz,1)
matrix3d(sx,0,0,0,0,sy,0,0,0,0,sz,0,0,0,0,1)
rotate3d(x,y,z,a)真是得搬出高中数学书好好复习一下了,第四个参数alpha用于sc和sq中
等价于…你自己从上到下,从左到右依次将参数搬入matrix3d中吧。当然除非是库函数需要,否则我严重怀疑是否会有人放着rotate3d不用,偏要去挑战用matrix3d模拟rotate3d。
总结
你可能会疑惑,谁会放着现成的transform内置函数不用,去用matrix/matrix3d?除非你故意不想让他人看懂代码,你可以将
transform: rotate(15deg) translate(230) scale(1.5,2.6) skew(220deg,-150deg) translate(230px);
写成
transform: matrix(1.06,1.84,0.54,2.8,466px,482px);
保证你的代码谁也看不懂谁也改不了,知识产权那是妥妥的,公司辞退谁都不会辞退到你。但恕我才疏学浅,除了满足个人好奇心,体会到一点智力上的优越感外,实际项目中似乎确实没什么卵用…本篇您就当看个乐呵。