CSS transform 的基本原理(2)
小试牛刀
上一篇讲了一些变换矩阵相关的东西,反正我是觉得挺有趣的。但,有什么用呢?
来介绍一个简单的应用吧,如果你须要用 CSS 的 transform 完成一个水平翻转, 你会怎么做呢?2D 变换中只提供了缩放、斜切、旋转、平移四个操作,并没有水平翻转。 这时候就可以使用 matrix 属性。
按上一篇所说的方法,我们考虑水平翻转会对单位向量产生什么影响。其实就是 x 轴的单位向量,方向取了个反。所以水平翻转的变换矩阵是
相应的 CSS 代码就是
当然,机智的朋友可能会说,直接用 3D 变换中的旋转操作,180° 刚好就是水平翻转嘛, 也没有必要用到 matrix 属性啊。确实没错,这也是水平翻转操作名称的由来,而且, 这种用高维空间解决低维空间的思想,也非常酷。
但这样,又带来了一个新的问题。如果有个需求,是要把一个 3 维空间从左手系翻转成右手系呢 (好啦,我知道根本没什么可能碰到这种需求,只是举个例子),考虑 transform 提供的 3D 变换操作,同样是这 4 个: 缩放、斜切、旋转、平移。这些操作,并没有翻转空间的效果, 而且 CSS 也没有提供 4 维变换的接口(不过即使提供了 4 维的接口,弄明白如何使用能够对应 3 维的翻转,要花的时间估计不比这些线性代数少),不能像之前那样用降维打击的方式完成了。
不过相信看到这里,应该都能很简单的使用 matrix3d 属性解决这个问题了。
3D 变换
matrix3d 和 matrix 其实非常像,只不过这个矩阵,是一个 4 * 4 矩阵,而且 16 个位置都开放给开发者设置(matrix 只有 6 个参数,而不是 9 个)。参数是按列填入矩阵的。 也就是说
对应的矩阵为
同样的,a4、b4、c4 三个参数用来做平移操作。你看,用矩阵还有一个好处, 就是升高维度并不需要什么额外的工作去理解 transform 的机制,都只是变换矩阵而已。
变换合并
在一个 transform 属性中,是可以定义多个变换的,比如说下面这个样式,是完全合法的。
这个变换操作就是先顺时针旋转 30° 再逆时针旋转 10°。不过这么写实在太傻逼了, 直接写 rotate(20deg) 效果其实也是一样的。
这说明,其实多个线性变换,是可以合并的,或者说找到一个等价的线性变换来代替它。 而且不一定要求变换是同一类型,任意的都可以,毕竟之前说过,说到底,都是 matrix 的语法糖而已。那变换的合并,又是怎么一回事呢。
考虑两个变换,他们的变换矩阵分别是这样:
那么我们先进行变换 1,再进行变换 2,那么按照上一篇给出的公式,对于点 (x, y), 变换后的坐标可以由下面这个式子求出
由于矩阵乘法是满足结合律的(注意,并不满足交换率),那么上式可以变形为
式子最左侧括号中的两个矩阵相乘的结果,就是两次连续变换的等价变换矩阵。 最终作用在变换目标元素上的,就是这个等价的变换矩阵。幸运的是我们并不需要自己去合并变换矩阵, 只要在单个 transform 中使用连续的几个基础变换,剩下的就交给浏览器就好了。
但感觉还是没啥用啊
确实,左手系变右手系这种需求,平时的开发中应该很难遇到了。就算有,多半还是用 webGL 来做轻松一些,性能也更好。
但 CSS 变换自有适合它发挥的地方,还是期待下一期吧。