CSS3中的矩阵CSS3中的矩阵指的是一个方法,书写为matrix()
和matrix3d()
,前者是元素2D平面的移动变换(transform),后者则是3D变换。2D变换矩阵为3*3, 如上面矩阵示意图;3D变换则是4*4的矩阵。
有些迷糊?恩,我也觉得上面讲述有些不合时宜。那好,我们先看看其他东西,层层渐进——transform
属性。
具体关于transform
属性具体内容可以点击这里补个课。稍微熟悉的人都知道,transform中有这么几个属性方法:
.trans_skew { transform: skew(35deg); }.trans_scale { transform:scale(1, 0.5); }.trans_rotate { transform:rotate(45deg); }.trans_translate { transform:translate(10px, 20px); }
斜拉(skew),缩放(scale),旋转(rotate)以及位移(translate)。
那你有没有想过,为什么transform:rotate(45deg);
会让元素旋转45°, 其后面运作的机理是什么呢?
下面这张图可以解释上面的疑问:
无论是旋转还是拉伸什么的,本质上都是应用的matrix()
方法实现的(修改matrix()
方法固定几个值),只是类似于transform:rotate
这种表现形式,我们更容易理解,记忆与上手。
换句话说,理解transform
中matrix()
矩阵方法有利于透彻理解CSS3的transform
属性,这就与那80%的也会应用但只知表象的人拉开了差距!
OK,现在上面提到的CSS3矩阵解释应该说得通了。
虽然题目写的是“transform
中的Matrix
”,实际上,在CSS3以及HTML5的世界里,这玩意还是涉猎蛮广的,如SVG
以及canvas
.事实上,关于矩阵,我之前曾经介绍过,是在介绍IE浏览器下的Matrix矩阵滤镜的时候说过,IE的滤镜矩阵与CSS中的矩阵虽然写法上差异较大,但是,矩阵计算的原来是一致的。只是之前的介绍主要是IE下的旋转与缩放,同时也不是很深入,因此还有有些局限的。
transform
与坐标系统用过transform
旋转的人可以发现了,其默认是绕着中心点旋转的,而这个中心点就是transform-origin
属性对应的点,也是所有矩阵计算的一个重要依据点(下图参考自dev.Opera.com)。
当我们通过transform-origin
属性进行设置的时候,矩阵相关计算也随之发生改变。反应到实际图形效果上就是,旋转拉伸的中心点变了!
举例来说,如果偶们设置:
-webkit-transform-origin: bottom left;
则,坐标中心点就是左下角位置。于是动画(例如图片收缩)就是基于图片的左下角这一点了:
上图效果可以点击这里查看(Chrome浏览器)。
再举个稍微难理解的例子,我们如果这样设置:
transform-origin: 50px 70px;
则,中心点位置有中间移到了距离左侧50像素,顶部70像素的地方(参见下图),而此时的(30, 30)
的坐标为白点所示的位置(这个位置后面会用到)。
仔细看看,是不是很快就理解了哈~~
CSS3transform
的matrix()
方法写法如下:
transform: matrix(a,b,c,d,e,f);
吓住了吧,这多参数,一个巴掌都数不过来。好吧,如果你把a~f
这6个参数想象成女神的名词,你会觉得,世界不过如此嘛~~
实际上,这6参数,对应的矩阵就是:
注意书写方向是竖着的。
上面提过,矩阵可以想象成古代的士兵方阵,要让其发生变化,只有与另外一个士兵阵火拼就可以了,即使这是个小阵。
反应在这里就是如下转换公式:
其中,x
,y
表示转换元素的所有坐标(变量)了。那后面的ax+cy+e
怎么来的呢?//zxx:大学时候线性代数知识,懂的人这里可以直接跳过
很简单,3*3矩阵每一行的第1个值与后面1*3的第1个值相乘,第2个值与第2个相乘,第3个与第3个,然后相加,如下图同色标注:
那ax+cy+e
的意义是什么?记住了,ax+cy+e
为变换后的水平坐标,bx+dy+f
表示变换后的垂直位置。
又迷糊了?不急,一个简单例子就明白了。
假设矩阵参数如下:
transform: matrix(1, 0, 0, 1, 30, 30); /* a=1, b=0, c=0, d=1, e=30, f=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)
处,怎么样,是不是往右下方同时偏移了30像素哈!!
实际上transform: matrix(1, 0, 0, 1, 30, 30);
就等同于transform: translate(30px, 30px);
. 注意:translate
,rotate
等方法都是需要单位的,而matrix
方法e, f
参数的单位可以省略。
一例胜万语,您可以狠狠地点击这里:matrix(1,0,0,1,30,30)实例demo
在现代浏览器下,会有类似下面动图的效果:
效果只是表象的,我想到了一个更好的idea去表现矩阵到底是如何变换的,您可以狠狠地点击这里:matrix分解变换演示
为了提高性能,demo中每个单元分解成了5px * 5px
的区域。演示分两步,先是演示每个单元的位置是如何计算的,接着动画表现其位置的偏移。
这个demo所做的工作就是把浏览器瞬间完成的计算和渲染变成了可控的分步显示,这样,大家就可以很直观地看出,这个矩阵计算到底是如何起作用的。下图为正在演示过程中的截图:
//zxx:由于默认100毫秒间隔不断渲染,因此如果你电脑CPU或是浏览器hold不住,可以取消“自动演示”的勾选,然后,点击左边的按钮手动分步查看。
总结聪明的你可能以及意识到了,尼玛matrix表现偏移就是:
transform: matrix(与我无关, 哪位, 怎么不去高考, 打麻将去吧,水平偏移距离, 垂直偏移距离);
你只要关心后面两个参数就可以了,至于前面4个参数,是牛是马,是男是女都没有关系的。
偏移是matrix效果中最简单,最容易理解的,因此,上面很详尽地对此进行展开说明。下面,为了进一步加深对matrix的理解,会简单讲下matrix矩阵与缩放,旋转以及拉伸效果。
缩放(scale)上面的偏移只要关心最后两个参数,这个缩放也是只要关心两个参数。哪两个呢?
如果你足够明察秋毫,应该已经知道了,因为上面多次出现的:
transform: matrix(1, 0, 0, 1, 30, 30);
已经出卖了。
发现没,matrix(1, 0, 0, 1,
的元素比例与原来一样,1:1, 而这几个参数中,有两个30, 30);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)
;
好了,至此,无需多说了……
眼见为实,因此demo还是要滴,您可以狠狠地点击这里:matrix矩阵与缩放demo
为了避免元素比例放大时候遮盖上面的文本框以及描述位子,因此,将元素的坐标原点迁至了左上角。
旋转(rotate)旋转相比前面两个要更高级些,要用到(可能勾起学生时代阴影的)三角函数。
方法以及参数使用如下(假设角度为θ
):
matrix(cosθ,sinθ,-sinθ,cosθ,0,0)
结合矩阵公式,就有:
x' = x*cosθ-y*sinθ+0 = x*cosθ-y*sinθy' = x*sinθ+y*cosθ+0 = x*sinθ+y*cosθ
这个与IEMatrix滤镜中的旋转是有些类似的(M11表示矩阵第1行第1个(参数a),M21表示矩阵第2行第一个(参数b)……):
filter:PRogid:DXImageTransform.Microsoft.Matrix(M11=cosθ,M21=sinθ,M12=-sinθ,M22=cosθ');
哎呀呀,四个参数,我记不住啊!莫慌,我们可以这样子记忆:CS-SC:初三-上床,对称结构,这下忘不了了吧~~
您可以狠狠地点击这里:transform matrix矩阵与旋转demo
不过,说句老实话,就旋转而言,rotate(θdeg)
这种书写形式要比matrix
简单多了,首先记忆简单,其次,无需计算。例如,旋转30°,前者直接:
transform:rotate(30deg);
而使用matrix
表示则还要计算cos
,sin
值:
transform: matrix(0.866025,0.500000,-0.500000,0.866025,0,0);
拉伸(skew)拉伸也用到了三角函数,不过是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
轴,两者并无关联。
还是靠实例说话吧,您可以狠狠地点击这里:matrix矩阵与拉伸demo
在Chrome下可以很动态地查看不同倾斜角度对应的拉伸的效果:
新闻热点
疑难解答