乐趣区

关于前端:前端-深入理解-transform-函数的计算原理-②

前排提醒:本篇为该系列第二篇,内容绝对于第一篇来说比较简单,各位可当休闲读物来看。

《前端 · 深刻了解 transform 函数的计算原理 ①》

接上回书讲到,咱们晓得了 transform 函数中的四大类共九个计算函数的工作原理。

既然除去 matrix 以外的八个具体形变函数,都能够用 matrix 来表白,那么这样是否意味着,只有有具体的参数,就能够用 matrix 来代替其余所有计算函数。也就是说,其实只用 matrix 就能够玩转 transform

那么怎么玩?

在本篇,咱们要做的指标只有一个:代码压缩。

开展来讲,是针对 transform 函数的代码压缩。

首先,为什么要做这件事件呢?

起因有二:
第一,transform 函数反对函数接续应用,所以常常能够看到开发者在代码中写入十分长的函数链条,诸如:

transform="rotate(-10 50 100) translate(-36,45.5) matrix(1,2,3,4,5,6) skewX(40) scale(1 0.5)"

其实这一长串要做的事件只有一个,那就是把一个元素,从状态 A,变成状态 B

当元素数量上来当前,这种简短的代码写法,无异于对加载和渲染产生额定耗费。而且代码浏览起来也非常不美观。

上一篇讲过,transform 中的多函数工作原理为矩阵乘法,所以这么长一串,其实只须要一个 matrix 就能够解决(这里保留了两位小数):

transform="matrix(1.33,1.80,2.38,2.46,-38.19,66.30)"

是不是看起来难受多了?

交给浏览器的运算步骤缩小了,前端代码文件体积升高了,视觉上看起来也规整很多,一举多得。

第二,显式的 transform 函数序列很容易让很多不喜爱动脑的“致敬者”轻易获取到变换逻辑。而因为矩阵乘法运算难以倒推出后果,这种隐式的压缩写法,等同于加密解决。

综上,咱们要做的,其实就是实现矩阵乘法。

办法很简略:
① 将各个变动函数转化为对应的 matrix 模式
② 将各个 matrix 按程序连乘,失去最终后果

最初这个有且仅有一个的变动矩阵,就是咱们用来替换“函数链”的那个惟一的 matrix()

第一步就不多说了,上一篇讲地十分细。关键在于第二步,不过矩阵乘法自身,对于理工科学生来说,大学一年级甚至高中三年级都学过,其实也不难。

这里给广大读者开展列一下公式,间接套用即可:

$$
\begin{aligned}
M_{result} &= M_{1}·M_{2} \\
&= \begin{pmatrix}
a_{1} & c_{1} & e_{1} \\
b_{1} & d_{1} & f_{1} \\
0 & 0 & 1 \\
\end{pmatrix}
·\begin{pmatrix}
a_{2} & c_{2} & e_{2} \\
b_{2} & d_{2} & f_{2} \\
0 & 0 & 1 \\
\end{pmatrix} \\
&= \begin{pmatrix}
a_{1}*a_{2}+c_{1}*b_{2}+e_{1}*0 & a_{1}*c_{2}+c_{1}*d_{2}+e_{1}*0 & a_{1}*e_{2}+c_{1}*f_{2}+e_{1}*1 \\
b_{1}*a_{2}+d_{1}*b_{2}+f_{1}*0 & b_{1}*c_{2}+d_{1}*d_{2}+f_{1}*0 & b_{1}*e_{2}+d_{1}*f_{2}+f_{1}*1 \\
0*a_{2}+0*b_{2}+1*0 & 0*c_{2}+0*d_{2}+1*0 & 0*e_{2}+0*f_{2}+1*1 \\
\end{pmatrix} \\
&= \begin{pmatrix}
a_{1}*a_{2}+c_{1}*b_{2} & a_{1}*c_{2}+c_{1}*d_{2} & a_{1}*e_{2}+c_{1}*f_{2}+e_{1} \\
b_{1}*a_{2}+d_{1}*b_{2} & b_{1}*c_{2}+d_{1}*d_{2} & b_{1}*e_{2}+d_{1}*f_{2}+f_{1} \\
0 & 0 & 1 \\
\end{pmatrix} \\
\end{aligned}
$$

python 写,外围就是这一行:

m_result = {'a': m1['a'] * m2['a'] + m1['c'] * m2['b'], 'b': m1['b'] * m2['a'] + m1['d'] * m2['b'],
            'c': m1['a'] * m2['c'] + m1['c'] * m2['d'], 'd': m1['b'] * m2['c'] + m1['d'] * m2['d'],
            'e': m1['a'] * m2['e'] + m1['c'] * m2['f'] + m1['e'],
            'f': m1['b'] * m2['e'] + m1['d'] * m2['f'] + m1['f']}

初始默认为 matrix(1, 0, 0, 1, 0, 0),只有将每个函数接续连乘,就能够最终计算出后果。

实测后果如下,各位可自行验证:

<svg width="100%" height="100%">
   <circle cx="100" cy="100" r="10" fill="red" transform="rotate(-10 50 100) translate(-36,45.5) matrix(1,2,3,4,5,6) skewX(40) scale(1 0.5)"></circle>
   <circle cx="100" cy="100" r="10" fill="green" transform="matrix(1.33,1.80,2.38,2.46,-38.19,66.30)"></circle>
</svg>

其实代码压缩在前端畛域十分常见,不同语言也有不同的压缩形式。出于一个比拟重要的细节解决,撰写此文跟大家分享。

好啦,本篇就先这样。

退出移动版