从矩阵与空间操作的关系理解CSS3的transform(科普文)
注:文中图片取材于线性代数的本质并加以合适的修改!推荐大家去观看这套视频,另外这套视频毕竟是一套数学性质的视频,不包含css的相关讲述,这篇文章将借鉴这套视频的思路为你讲述css变换的原理。
- 矩阵
- 概述
- 向量
- 什么是向量
- 基向量
- 线性变换
- 如何用数值描述线性变换
- 回到 CSS 的 transform
矩阵概述
矩阵,是线性代数中涉及的内容,线性代数在科学领域有很多应用的场景,如下:
很多同学在大学时期都学过一本叫做线性代数的书,如果没猜错的话,你们的老师在教学的时候大多都是概念性的灌输,比如矩阵乘法如何运算,加法如何运算,大家只要记住就ok了,但是大部分同学都不理解,为什么矩阵的乘法要这样算?矩阵乘法的意义是什么?,特别是我们搞计算机的,如果有做过 2D/3D 变换的同学一定听说过矩阵,比如在前端的CSS中,使用 transform
做 2D/3D 的变换,其中就应用到了矩阵的知识,这篇文章并不是一篇数学性质的文章,所以大家不要怕看了之后会感觉一阵眩晕,这篇文章的目的在于:从矩阵与空间之间的关系讲述为什么矩阵可以应用在空间操作(变换)。
先看一段 css 代码:
/* 2D */
transform: matrix(1, 0, 0, 1, 0, 0);
/* 3D */
transform: matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
上面两行 css 代码其实什么变换都不会做,因为那是变换的默认状态,即没有变换。但是其中使用到了 matrix
,翻译成中文叫做:矩阵。如果有深入研究过 css 的同学对这两行代码也许不陌生,但是大多数人在使用 transform
变换时很少直接使用 matrix
矩阵,除非你不想让人看懂你在做些什么鸟变换...,所以更多的时候,我们会使用类似如下语法:
transform: translateX(100px) rotateZ(30deg);
如上代码所示,一目了然,要做什么变换大家一看就知道了。但其实,这只是一个语法糖,其底层依然使用的是 matrix
。
如果想要理解矩阵为何可以应用到 2D/3D 变换,那么只从数值水平的角度理解是不够的,你需要从几何的角度去理解矩阵,这存在着根本性的差异。而这,也就是本篇文章的真正意义。
不过,这需要我们先了解一些必要的基本概念,这些概念至关重要,首先就是向量
向量
什么是向量?既然矩阵是线性代数的一部分,那么就不得不提到 向量,因为向量是线性代数最基础、最根源的组成部分,所以我们要先搞清楚,向量是什么?我说过,这篇文章不会很“数学”,所以大家不要被吓到。用一句话描述向量是什么:
向量:空间中的箭头
这个在大家的印象里应该很好理解,这个箭头由两个因素决定:方向
和 长度
,我们先把目光局限在二维空间下,如图:
上图中,在一个坐标系中画了四个不同长度和方向的箭头,每个箭头从原点发出,他们代表了二维空间中的四个向量,在线性代数中,向量通常以原点作为起点。
如果你已经理解了“向量是空间中的箭头”这种观点,下面我们再进一步,我们重新用一句话来描述向量:
向量:是有序的数字列表
假设大家对坐标系的概念都有所了解,我们还是把目光局限在二维空间,在坐标系中任意选取单位长度,这样我们就能够使用一个一个的刻度来标刻这个坐标系,选取特定的方向为x/y轴的正方向,那么不难看出,每一个向量,都可以用唯一的一个坐标来表示,同样的,坐标系中的每一个坐标都对应着一个唯一的箭头(向量),如下图:
在坐标系中,由于坐标通常用来标示一个点,如 P(2, 8)
表示点 P 的坐标为 (2, 8)
,为了区分点和向量,在表示向量时,我们通常把坐标竖着写,然后用一对儿中括号来描述,如上图中的:
在三维空间也是一样的道理,如下图,我就不做重复的解释,唯一不同的是,每一个向量由 x/y/z 三个数字组成的坐标来表示:
对于向量,你只需要知道它是“空间中的箭头”或者“有序的数字列表”这就足够了,怎么样?不难理解吧,我们继续往下看,在坐标系中存在一种特殊的向量,我们称之为 基向量。
基向量
基向量,也叫单位向量,是单位长度为1的向量,如下图中:i帽
和 j帽
就是这个二维坐标系的基向量: