首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

从矩阵的角度看CSS3动画

前端页面中实现一个动画效果,目前常用的方法有借助SVG、CSS的transform属性或者在requestAnimationFrame回调中通过javascript的动态调用,改变canvas上下文属性或元素属性实现。其中transform属性最为广泛使用,适当的组合其scale、translate、rotate、skew等值并结合animation属性,便可做出绚丽的动画效果。而martix似乎因其参数的不够直观且涉及数学原理而难以理解,最终落得个少有问津,本文试图解释`Matrix`背后的数学原理然后使用martix等效实现scale、translate、rotate、skew的效果。值得一提的是,因动画的直观性,前端的动画示例也将有助于我们从几何角度理解矩阵与线性变换。

每年剁手节除了沉浸在疯狂购物带来的快感中之外,你也一定曾被各大电商双十一主会场绚丽的页面动画所惊艳。也许他们有的是视频、有的是GIF图,但毕竟体积大,除此之外,也一定运用了大量CSS3动画。毕竟,一般基于性能考虑,为了达到相同的效果,「能用CSS解决的,绝对不用JS」。说到CSS3动画,也许,CSS3的各个属性,对你来说已经是如数家珍,各种动效也是手到擒来。但我们追求的是不仅要会用,更重要的是知道为什么可以这么用。所谓知其然,知其所以然。而以下CSS3常用属性表达式便是本文核心——逐层揭开开发者友好的高度抽象整合的动画方法。

通过观察以上表达式,我们不难得知问题的核心便是矩阵与线性变换以及如何确定相应的矩阵表达式。

首先,因肉眼存在视觉暂留这一生理现象,当多帧静止的画面以一定的速度(如每秒60张——常见的屏幕刷新频率)连续播放时,肉眼会产生画面动起来的视觉错觉,而这便形成了动画。众所周知,体由面、面由线、线由点所构成,因此画面动起来这种现象,我们可以换种说法——画面中的无数个点一起通过某种作用,从一个位置运动到另一个位置。

故而,对于线性的变换,我们只要知道画面中任意一个点是如何运动的,就可以通过描述该点的运动来反应整个画面的运动情况。 企鹅从左移动到右边,是组成企鹅换面的所有点一起在相同时间点从左运动到右边

联系日常生活,我们生活在三维空间中,我们所熟知的这个三维世界包含着各种动物、植物、微生物等等,我们在这个空间中展开各种各样的生产生活活动,伟大的科学家们发现并总结了人类及自然界的诸多活动规律,并将其用物理、数学等学科语言一一描述。如早晨从家走到公司去上班,我们可以用所熟知的如路程S、位移X、平均速度v=

t

S

等描述这一运动行为。与之类似:矩阵(Martix)描述向量空间中的线性变换。

具体如何描述,要先从向量说起。向量,可以是高中物理力学以及解析几何中常见的矢量,可以是一个具体的函数,也可以是经抽象后更一般的向量概念。我们可以从更易于人们理解的向量几何模型出发,借助更加可视化的几何向量切入。我们知道,描绘图形图像等几何问题的有力工具便是使用坐标系。在坐标系中,我们常用小括号横向书写的方式表示点,如点G(4,6)和点O(0,0)。用中括号竖向书写的方式示向量,如:

的坐标就是一个2行1列的非方矩阵,也就是说向量可以表示为矩阵。更近一步,又如质子、中子以及电子构成原子,原子组成分子类似。我们常以线性无关的两个向量,如x,y方向的单位向量作为二维空间的基向量,基向量的各种线性组合构成诸如等在内的二维空间中的所有向量,如

那什么是线性?线性给人的第一形象的主观印象可能就是一条直线。不失一般性,对于如何描述直线,我们初中就学过——一次函数:。其中k,b是常数,。至此,我们便简单直观地从我们最为熟悉的初等函数的角度理解了线性的几何意义——直线。但是,从代数层面上而言,线性要满足以下两条性质。

1.可加性:可加性可以理解为,自变量单独作用的结果与自变量共同作用的结果相同。

2.数乘性:数乘性可以理解为,因变量与自变量等比例变化。

,其中a为常数

如果同时满足可加性与数乘性(比例性),我们就认为是线性的。这两条性质是线性变化的基础,因为矩阵加法、矩阵数乘基本构成了线性变换的全部,所以理解可加性和数乘性至关重要。所以从代数层面上看,此时,并不是严格的线性函数,因为如果:

则:

显然,当,,不满足可加性。

显然,当时,不满足数乘性。故才是最简单的线性函数,其表示一过圆点的直线。

以上,简单介绍了动画的形成、向量、矩阵、线性等基本概念。一言以蔽之,向量,是线性空间的基本元素,所有满足可加性与数乘性的向量集合构成了向量空间,可以将向量坐标表示为矩阵,通过矩阵描述线性变换

前面我们说到,确定一组基向量后,那么由该组基向量所构成的线性空间内的所有向量均可用该组基向量的线性组合表示。由于变换是线性的,所以我们只需要知道该组基向量经线性变换后被变换到了哪里,就可以知道任何一个向量经变换后的坐标表示。比如,旋转变换到,追踪基向量i,j的坐标变化

,因此,我们用矩阵描述这一逆时针旋转的变换。我们不难看出,其中第一列为基向量i,第二列为基向量j变换后坐标。

又比如,将图形放大为原来2倍的线性变换表示为也就是说,基向量的值被放大了2倍。

所以,此时,再回过头看CSS3相对应的属性,通过相同的方法,由图我们不难得到以下表达式:

旋转

斜切

二维空间中CSS属性对应的线性变换

我们看到,以上表达式既有矩阵加法又有矩阵乘法,且与开头给出的表达式相比,似乎缺失了一个维度。其实,为了统一形式、快速运算,我们引入齐次坐标,将平移、缩放、旋转等变换合成到一个矩阵中,从而消除运算中的加减法,只保留乘法。故而,以上表达式在引入齐次坐标统一形式后形成了开头看到的形式统一的矩阵。简单理解,齐次坐标就是把现有的二维空间升纬到三维空间去看,而多出的那一维度对于二维空间而言并用不到,所以并不会有任何影响。另外,我们注意到,线性变化要求坐标原点保持不变,translate变换实际上移动了坐标原点,而升维之后便可以在高维度通过线性变换完成低维度的仿射变换,这也是升维的一个重要原因。更形象的从几何上来如图所示:

martix属性对应关系

到这里,在当我们看到martix(a,b,c,d,x,y)时,我们就可以很清楚的知道,a,b,c,d 组成的2行2列的方阵控制着旋转缩放等,x和y则决定其在对应方向的位移。如 transform: martix(2,0,0,3,0,0)我们便可以一眼看穿其意为横向放大2倍,竖向放大3倍。当然,martix也可以轻松实现镜像翻转等效果。

CSS使用起来虽然简单,有人不以其为一门语言,但是仔细深挖背后的原理还是有一定难度。惭愧于未在学校学好线性代数相关内容,以上内容均是想弄清transform: martix(a,b,c,d,e,f)模糊的用法到底为何而去相当于重新学习线代后的简单理解,难免有出错与不足之处,而其中内容很多,一些概念而非三言两语所能解释清晰,如果你也感兴趣,请参阅参考资料内容学习,如果时间有限,请以《线性代数的本质》视频内容为主,非常推荐!

参考资料:

https://www.bilibili.com/video/av6731067/

http://open.163.com/special/opencourse/daishu.html

https://book.douban.com/subject/26651221/

https://zh.wikipedia.org/wiki/Wikipedia:%E9%A6%96%E9%A1%B5

https://www.geogebra.org/

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180331G1B5PW00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券