🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # CSS3中的矩阵 CSS3中的矩阵指的是一个方法,书写为`matrix()`和`matrix3d()`,前者是元素2D平面的移动变换(transform),后者则是3D变换。2D变换矩阵为3 * 3, 如上面矩阵示意图;3D变换则是4 * 4的矩阵。 <br> <br> # 应用场景 * SVG * Canvas * transform * webgl <br> <br> # transform与坐标系统 transform 的rotate 其默认是绕着中心点旋转的,而这个中心点就是transform-origin属性对应的点,也是所有矩阵计算的一个重要依据点。 ![transform坐标系统](http://image.zhangxinxu.com/image/blog/201206/css-transforms-matrix2.png "transform坐标系统") 我们如果这样设置: ~~~ transform-origin: 50px 70px; ~~~ 则,中心点位置有中间移到了距离左侧50像素,顶部70像素的地方(参见下图),而此时的`(30, 30)`的坐标为白点所示的位置。 ![](https://box.kancloud.cn/e17fa1c8454d90a16eaac17e15878cc6_411x386.png) <br> <br> # matrix ~~~ transform: matrix(a,b,c,d,e,f); ~~~ ![](https://box.kancloud.cn/c70a6a4354bcefc1f42eaf09c957ed87_147x92.png) 注意书写方向是**竖着的**。 ## 计算 矩阵第m行与第n列交叉位置的那个值,等于第一个矩阵第m行与第二个矩阵第n列,对应位置的每个值的乘积之和。 ![](https://box.kancloud.cn/258199abf2bb4fbefc1255ddf8dd3ecb_533x170.png) 其中,`x`,`y`表示转换元素的所有坐标(变量)了。 `ax+cy+e`为变换后的水平坐标,`bx+dy+f`表示变换后的垂直位置。 ## transform ~~~ transform: matrix(a, b, c, d, 水平偏移距离, 垂直偏移距离); ~~~ ## scale ~~~ `matrix(sx, 0, 0, sy, 0, 0);`,等同于`scale(sx, sy)` ~~~ ## 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θ ~~~ # 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`轴,两者并无关联。 # 镜像对称 要实现API没有提供的功能,需要使用matrix方法。 镜像对称即找到图像的每个点在直线 y=kx 的对称点。则`matrix`表示就是: ~~~ matrix((1-k*k) / (1+k*k), 2k / (1 + k*k), 2k / (1 + k*k), (k*k - 1) / (1+k*k), 0, 0) ~~~ ![](https://box.kancloud.cn/e07864dfd6423823632b50e1191629c8_411x386.png) 证明: 点(x, y) 与 (x', y')所在的直线与 y = kx垂直,因为两条垂直的线的斜率乘积为-1,因此 (y-y') / (x-x') = -1/k ① 易知 点(x, y) 与 (x', y')所在直线与直线y=kx的交点平分为线段x'y' x,y 的中点,因此 ·(y+y') / 2 = k * (x +x') /2 ② <br> 联立①和②并整理 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;` <br> 再结合矩阵公式: `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);` <br> 分别将a、b、c、d代入 transform: matrix(a, b, c, d, 0, 0); > 因为 transform : rotate()旋转的角度为顺时针,计算k时要取相反数 # 3D变换中的矩阵 3D变换虽然只比2D多了一个D,但是复杂程度不只多了一个。从二维到三维,是从4到9;而在矩阵里头是从3*3变成4*4, 9到16了。 其实,本质上很多东西都与2D一致的,只是复杂度不一样而已。这里就举一个简单的3D缩放变换的例子。 对于3D缩放效果,其矩阵如下: ![](https://box.kancloud.cn/ea8e05c23b8f9a0f63be42298db33c51_209x123.png) ~~~ transform: matrix3d(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1) ~~~ # 参考资料 [理解CSS3 transform中的Matrix(矩阵) 张鑫旭-鑫空间-鑫生活](https://www.zhangxinxu.com/wordpress/2012/06/css3-transform-matrix-%E7%9F%A9%E9%98%B5/comment-page-1/#comments)