基本概念
css中transform属性值是一个或多个transform-function值。对于二维平面的变换,transform-function包括scale,rotate、translate、skew和matrix。我们目前只讨论二维变换的情形。matrix是最为基本的一个函数,其它函数其实都是可以用matrix来替代的。先看看除了matrix以外的其它四个函数。
这四个方法可以分为两类,scale,rotate、skew属于线性变换,所谓线性变换,可以理解为原点保持不变且平面上任何一条直线变换后仍然为直线的变换。只有translate不属于线性变换。
scale、rotate和translate理解起来比较直观,无非就是缩放、旋转和平移。但是容易被忽略的是,缩放和旋转是以哪个点为原点进行的。根据经验,原点就是元素的中心点(50%, 50%),这也是默认的。但其实可以通过transform-origin设置。
对于99%的场景,知道scale、rotate和translate就够用了,甚至不需要知道transform-origin。但是,为了完全理解transform,我们继续往下。
skew() 是什么
先看看MDN文档的定义:
skew() 函数定义了一个元素在二维平面上的倾斜转换
看了之后一头雾水,什么叫做倾斜?倾斜和旋转有何不同?后面又有一句是这样说的:
这种转换是一种剪切映射(横切),它在水平和垂直方向上将单元内的每个点扭曲一定的角度。
这个就更抽象了,扭曲一定角度是什么意思?
先从语法上看:skew(ax, ay)
,它接收两个参数,分别表示沿横坐标和纵坐标扭曲元素的角度。也可以拆开来写,即skew(ax, ay)
等于skewX(ax)
和skewY(ay)
。想要搞懂skew,就要搞懂参数ax、ay与元素坐标变换之间的对应关系,也就是“扭曲”的过程。
先画一个长宽为100px的div,以transform-origin为原点,建立笛卡尔坐标系。前面提到过transform-origin的默认值就是元素的中心点(50%, 50%)。再画两条红线,代表坐标系的X轴和Y轴,红线交叉点就是坐标原点,如下图:
使用transform: skewX(45deg);
:
虚线代表变换前的,可以看到,skewX
实际上是保持y坐标不变,将x坐标移动一定的距离。假设某个点移动前为A,移动后后B。A向x轴作垂直线,交点为C,直线CA以C为原点逆时针旋转45度。B点就在旋转后的直线上。skewY也是相同的计算规则。
可以看到skew是在满足线性变换的前提下对坐标上的每个点进行x轴或y轴方向上的移动。如果对元素两个轴方向上偏移恰当的角度,是可以达到旋转的效果的,例如transform: skew(45deg, -45deg);
:
旋转后效果上体积变大了。但如果把skew和scale结合起来,就可以模拟rotate()方法了: transform: skew(45deg, -45deg) scale(0.75);
,效果如下:
这和transform: rotate(45deg);
的效果是一致的。
理解matrix()
matrix函数的语法是这样
matrix(a, b, c, d, tx, ty)
复制代码
其中a, b, c, d分别代表函数scaleX(), skewY(), skewX(), scaleY(),它们共同代表一个线性变换。
tx和ty表示位移,分别代表translateX(), translateY() 。
例如transform: matrix(1, 0, 0, 1, 10, 10);
就等同于transform: translate(10px, 10px);
因为skew为0,scale为1,只有最后两个参数起作用。再比如transform: matrix(2,0,0,2,0,0);
等同于transform: scale(2);
。如果是实现skew或rotate的效果就会复杂一点,但是方法也是改变对应的参数。上面提到过,rotate是可以用skew和scale来实现,所以大家很容易猜到要实现rotate应该设置的a,b,c,d四个参数。matrix的六个参数涵盖了scale,skew,translate,rotate。这就是为什么matrix可以替代其它二维变换方法,并且能够通过不同的组合实现更多复杂的变换。这就是对matrix的感性认知。
接下来从数学的角度来分析matrix
假定我们用向量的终点来表示平面中的点,即向量(x, y)表示点(x, y)。在坐标系中确定两个基向量i(1, 0), j(0, 1)。那么平面坐标中任意一个点都可以用a*i + b*j
表示, 其中a、b为任意实数: