写法:transform:matrix(a,b,c,d,e,f)
在矩阵中:
结合坐标轴计算结果位:
偏移(translate)
利用矩阵实现transform:translate(30px,30px);
等同于transform:matrix(1,0,0,1,30,30)
现在,我们根据这个矩阵偏移元素的中心点,假设是(0, 0)
,即x=0
, y=0
。
于是,变换后的x
坐标就是ax+cy+e = 1*0+0*0+30 =30
, y
坐标就是bx+dy+f = 0*0+1*0+30 =30
.
于是,中心点坐标从(0, 0)
变成了→(30, 30)
。对照上面有个(30, 30)
的白点图,好好想象下,原来(0,0)
的位置,移到了白点的(30, 30)
处,
实际上transform: matrix(1, 0, 0, 1, 30, 30);
就等同于transform: translate(30px, 30px);
. 注意:translate
, rotate
等方法都是需要单位的,而matrix
方法e, f
参数的单位可以省略。
这里只需要关心后面两个参数就可以了,前面4个参数在偏移上是不需要考虑的。
旋转(rotate)
利用矩阵实现transform:rotate(α); //将元素旋转α度
等同于transform:matrix(cosα,sinα,-sinα,cosα,0,0)
结合矩阵公式,就有:
x'=cosα*x-sinα*y+0=cosα*x-sinα*y
y'=sinα*x+cosα*y+0=sinα*x+cosα*y
结合三角函数是可以推算出来的,
假设有一个点A(x,y),偏移之前与原点之间连线的角度是β,偏移角度是α,偏移之后的点位A'(x',y')。
A点与原点之间的长度不会变,设r,那么r就等于√(x²+y²),cosβ=x/√(x²+y²),sinβ=y/√(x²+y²)。
偏移之后:
A'的横坐标就为x'=r*cos(α+β)=r*(cosα*cosβ-sinα*sinβ),将上面的r、cosβ和sinβ代入化简就可以得到x'=cosα*x-sinα*y;
A'的纵坐标就为y'=r*sin(α+β)=r*(sinα*cosβ+cosα*sinβ),将上面的r、cosβ和sinβ代入化简就可以得到y'=sinα*x+cosα*y;
进而获得矩阵matrix(cosα,sinα,-sinα,cosα,0,0)。
缩放(scale)
利用矩阵实现transform:scale(1,1);
等同于transform:matrix(1,0,0,1,0,0)
缩放后的元素比例与原来一样,1:1, 而这几个参数中,有两个1, 这两个1就是缩放相关的参数。
其中,第一个缩放x轴,第二个缩放y轴。
用公式就很明白了,假设比例是s,则有matrix(s, 0, 0, s, 0, 0);,于是,套用公式,就有:
x' = ax+cy+e = s*x+0*y+0 = s*x;
y' = bx+dy+f = 0*x+s*y+0 = s*y;
也就是matrix(sx, 0, 0, sy, 0, 0);,等同于scale(sx, sy);
拉伸(skew)
利用矩阵实现transform:skew(θy,θx);
等同于transform:matrix(1,tan(θy),tan(θx),1,0,0)
拉伸也用到了三角函数,不过是tanθ,而且,其至于b, c两个参数相关,书写如下(注意y轴倾斜角度在前):
matrix(1,tan(θy),tan(θx),1,0,0)
套用矩阵公式计算结果为:
x' = x+y*tan(θx)+0 = x+y*tan(θx)
y' = x*tan(θy)+y+0 = x*tan(θy)+y
对应于skew(θx + "deg",θy+ "deg")这种写法。
其中,θx表示x轴倾斜的角度,θy表示y轴,两者并无关联。
镜像对称效果
另外还可以利用矩阵实现元素的镜像对称效果
transform:((1-k*k) / (1+k*k), 2k / (1 + k*k), 2k / (1 + k*k), (k*k - 1) / (1+k*k), 0, 0));
现已知一是垂直,二是中心点在轴线上,因此有:
(y-y') / (x - x') = -1/ k
(x + x') / 2 * k = (y + y')/2
把x'和y'提出来,就有:
x' = (1-k*k)/(k*k+1) *x + 2k/(k*k+1) *y;
y' = 2k/(k*k+1) *x + (k*k-1)/(k*k+1) *y;
再结合矩阵公式:
x' = ax+cy+e;
y' = bx+dy+f;
就可以得到:
a = (1-k*k)/(k*k+1);
b = 2k/(k*k+1);
c = 2k/(k*k+1);
d = (k*k-1)/(k*k+1);