css3中transform matrix矩阵各个参数的说明

一、从最简单的情况入手


假设我们的布局和样式如下:

<style>	
#wrap div{
    position:absolute;width:100px;height:50px;
}
#new{
    -webkit-transform-origin: left top;
    -webkit-transform:matrix(1,0,0,1,20,20);
}
</style>
<body>
<div id="wrap" style="position:relative;margin-top:200px;margin-left:200px;">	
  <div id="old" style="background-color:yellow;">原来的图</div>	
  <div id="new" style="background-color:red;" > </div>
</div>
</body>

我们会看到如下效果:

blob.png

这种情况是最简单的变换,即位移变换translate。

假设matrix的参数分别用是:a,b,c,d,e,f

那么translate变换就等同于:matrix(1,0,0,1,e,f)

e就表示水平方向的位移,f表示竖直方向的位移。

注意:网页里面的x、y坐标都是从左上角开始计算的。

二、深入一点点


我们再来变换那么一点点,代码如下:

-webkit-transform:matrix(0.5,0,0,0.5,0,0);

你会看见如下效果

blob.png

也就是说缩放scale就等同于 matrix(a,0,0,d,0,0)

到底为什么,我们马上来说

三、分析


matrix变换会将这六个参数形成一个矩阵M

a  c  e
b  d  f
0  0  1

假设原始图像上的某个点A为(x,y)

变换之后的某个点A1为(x1,y1)

在处理的时候系统会把原始图像上的每一个点生成一个矩阵P,如下

x
y
1

那么系统会将这个matrix矩阵M与原始矩阵P相乘

这里贴一个乘法公式

blob.png

那么我们变换后得到的矩阵Q如下:

a*x+c*y+e
b*x+d*y+f
1

得到了这个矩阵,我们就知道了变换后的点A1的坐标与变换前的坐标A之间的关系

x1 = a*x+c*y+e
y1 = b*x+d*y+f

我们给这个方程式命名为G

那么现在我们再来看看之前的两张特殊情况吧

1.第一种特殊情况 a=d=1(不缩放)b=c=0(不倾斜)   —–> translate 位移

带入上面的方程式G,我们可以得到

x1 = x+e
y1 = y+f

这也就是说变换后的点A1坐标为(x+e,y+f),而A的坐标为(x,y),那么就是一个简单的平移,平移的向量为(e,f)

我们可以得出:

transform:matrix(1,0,0,1,e,f) === transform:translate(e,f)

2.第二种特殊情况 b=c=0(不倾斜)e=f=0(不平移)    —–> scale 缩放

带入上面的方程式G,我们可以得到

x1 = a*x
y1 = d*y

这也就是说变换后的点A1的x方向缩放了a倍,y方向缩放了d倍,这个缩放,可以是放大(a或d大于1),也可以是缩小(a或者d小于1)

所以我们可以得出:

transform:matrix(a,0,0,d,0,0) === transform:scale(a,d)

3.第三种特殊情况解释起来就比较麻烦了

这里画一个图来帮助大家理解

blob.png

我们还是假设变量 a=d=1(不缩放)e=f=0(不平移) —-> skew 倾斜

带入上面的方程式G,我们可以得到

x1 = x+c*y
y1 = b*x+y

在上面的辅助图中我取的参数如下:

-webkit-transform:matrix(1,0.5,0.5,1,0,0);

那么变换后的方程可以进一步简化为

x1 = x+0.5*y
y1 = 0.5*x+y

标记这个方程组为G1

如上图我们可以知道,OA所在的指向方程为y=0

带入上面的G1方程组,我们可以得到A点(x,y)在变换后得到的A1点的坐标为

x1 = x
y1 = 0.5*x

即A1点的坐标为(x,0.5x)

细心的朋友或许发现了A1点的 纵坐标y1/横坐标x1 的值恰好等于0.5,或许你明白了什么,说明你很聪明

还是让我来把这个秘密来点透吧

这个b=0.5就表示y轴正方向倾斜的高度与A点x轴坐标的比值,而这个c=0.5就表示x轴正方向倾斜的高度与A点y轴坐标的比值

这两个值官方的来说是三角形的正切值(弧度

那么,接下来重点来了。。。

稍微有点css3基础的朋友都知道,transform的skew(x,y)中的两个参数是用角度(deg)来表示的,分别表示x轴倾斜的角度和y轴倾斜的角度

看到这里,你或许会问,前面两种特殊情况用matrix表示的方法都可以转化为特殊属性表示,那这种情况下该怎么转换呢??

根据上面的图,我们明显可以知道,x轴倾斜的角度就是 线段AA1/线段OA 的反正切角度值,也就是matrix参数中b的反正切角度值

用js来操作的话,具体的计算公式如下:

#水平方向的倾斜角度
Math.atan(b)*180/Math.PI
#竖直方向的倾斜角度
Math.atan(b)*180/Math.PI

那么我们现在就可以用skew来表示matrix矩阵了

-webkit-transform:matrix(1,b,c,1,0,0); 
#等价于如下的形式
-webkit-transform:skew(Math.atan(b)*180/Math.PI,Math.atan(c)*180/Math.PI);

但请注意:css中这样写是不行的,因为css中不支持计算的功能,这里只是简单的列出matrix中b,c两个参数与skew中参数之间的关系,使用的时候可以用js来设置,也可以先计算好了再用。

这个例子里面我们如果用skew的形式写的话,参数应该是下面的形式

# 注释:26.565是 Math.atan(0.5)*180/Math.PI计算而来的
-webkit-transform:skew(26.565deg,26.565deg);

下面来看看效果是不是一样吧

blob.png

matrix的形式

blob.png

skew的形式

可以看见,两个图形的倾斜角度,正如我们前面所说的,一模一样,可喜可贺,可喜可贺啊

最后的问题就是transform-origin的设置了

这个属性的设置只是改变了变换后图形的位置,而形状大小倾斜不会做任何的变换

四、总结一下


说了这么多,这篇文章也该结尾了,最后来总结一下:

1.matrix必须设置六个参数,假设为a,b,c,d,e,f

2.a,d参数表示图形的缩放比例,可正可负

3.b,c参数表示图形的倾斜角度沿坐标系的正方向的正切值

4.e,f参数表示图形x,y方向的平移值

五、值得注意的事


  1. transform中的各单一属性如果重复,属性并不会被覆盖,而是叠加,而且这个叠加方式并不是单纯的相加相减

    例如:如下的三个skew水平方向的倾斜是被叠加了,但是叠加的计算方式并不是单纯的相加那么简单,具体是什么计算公式,有空再来研究

    blob.png

2. 如上所说的三个转换关系并不能完全等同的转换

   例如:有的朋友看了上述的解释后会认为如下的两个属性是相等的,其实是不对的

-webkit-transform:matrix(0.5,1.732,1.732,0.5,10,20); 
-webkit-transform:scale(0.5,0.5) skew(60deg,60deg) translate(10px,20px);

  还是记住那句话,这里的属性叠加不是简单的相加相减



打赏作者

发表评论

邮箱地址不会被公开。 必填项已用*标注