介绍一下css的Matrix(矩阵)

15,404次阅读
没有评论

共计 3027 个字符,预计需要花费 8 分钟才能阅读完成。

关于 Matrix

我们先看看 chatGpt 是如何介绍矩阵的。

矩阵是数学中的一个概念,它是由数字按照矩形排列而成的矩形阵列。矩阵由行和列组成,行表示矩阵的水平方向,列表示矩阵的垂直方向。

一个矩阵可以用以下形式表示:

A = [a11, a12, a13, ..., a1n]
    [a21, a22, a23, ..., a2n]
    [a31, a32, a33, ..., a3n]
    ...
    [am1, am2, am3, ..., amn]

其中,a11, a12, a13, ..., a1n 表示第一行的元素,a21, a22, a23, ..., a2n 表示第二行的元素,以此类推,am1, am2, am3, ..., amn 表示第 m 行的元素。

矩阵的大小由行数和列数决定,如果一个矩阵有 m 行和 n 列,我们称其为 m×n 的矩阵。

矩阵在数学和计算机科学中有广泛的应用,例如线性代数、图形学、机器学习等领域。矩阵可以进行加法、减法、乘法等运算,还可以表示向量、线性方程组、线性变换等概念。

在 CSS 中,矩阵也被用于表示 2D 变换效果,如平移、缩放、旋转和错切等。通过矩阵的乘法运算,可以将多个变换效果组合在一起,实现复杂的变换效果。

CSS3 transform 的 matrix()

transform: matrix(a,b,c,d,e,f);

实际上,这 6 参数,对应的矩阵就是:

介绍一下 css 的 Matrix(矩阵)

注意书写方向是竖着的。

假如矩阵要变化,例如偏移,旋转或者变形或者其他的中心点是 xy,那么矩阵变化如下

介绍一下 css 的 Matrix(矩阵)

其中,x, y 表示转换元素的所有坐标(变量)了。那后面的 ax+cy+ e 怎么来的呢?
很简单,3 3 矩阵每一行的第 1 个值与后面 1 3 的第 1 个值相乘,第 2 个值与第 2 个相乘,第 3 个与第 3 个,然后相加,如下图同色标注:

介绍一下 css 的 Matrix(矩阵)

那 ax+cy+ e 的意义是什么?

ax+cy+ e 为变换后的水平坐标,

bx+dy+ f 表示变换后的垂直位置。

矩阵偏移

关于偏移,假如是如下矩阵

transform: matrix(1, 0, 0, 1, 60, 60); /* a=1, b=0, c=0, d=1, e=60, f=60 */

现在,我们根据这个矩阵偏移元素的中心点,假设是(0, 0),即 x =0, y=0。

于是,变换后的

x 坐标就是 ax+cy+e = 10+00+60 =60,

y 坐标就是 bx+dy+f = 00+10+60 =60.

于是,中心点坐标从 (0, 0) 变成了→(60, 60)。

也就是相当于

transform: translate(60px, 60px);

注意:translate, rotate 等方法都是需要单位的,而 matrix 方法 e, f 参数的单位可以省略。

矩阵缩放(scale)

发现没,matrix(1, 0, 0, 1, 60, 60); 的元素比例与原来一样,1:1, 而这几个参数中,有两个 1,

没错,这两个 1 就是缩放相关的参数。

其中,第一个缩放 x 轴,第二个缩放 y 轴。

用公式就很明白了,假设比例是 s,则有 matrix(s, 0, 0, s, 0, 0);,于是,套用公式,就有:

x’ = ax+cy+e = sx+0y+0 = s*x;

y’ = bx+dy+f = 0x+sy+0 = s*y;

也就是

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θ

假如

transform:rotate(30deg);

转换成矩阵就是

transform: matrix(0.866025,0.500000,-0.500000,0.866025,0,0);

矩阵拉伸(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 轴,两者并无关联。

矩阵 matrix 实现镜像渐变

镜像主要是指 transform 里面其他属性实现不了的功能,轴围绕的那个点就是 CSS3 中 transform 变换的中心点,
因为该轴永远经过原点,因此,任意对称轴都可以用 y = k * x 表示。则 matrix 表示就是:

matrix((1-k*k) / (1+k*k), 2k / (1 + k*k), 2k / (1 + k*k), (k*k - 1) / (1+k*k), 0, 0)

这个如何得到的呢?

一是垂直,二是中心点在轴线上,因此有:

(y-y') / (x - x') = -1/ k → ky-ky'= -x+x'
(x + x') / 2 * k = (y + y')/2 → kx+kx'= y+y'

很简单的,把 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;

再结合矩阵公式:

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);

也就是上面 matrix 方法中的参数值啦!

3D 变换中的矩阵

3D 变换虽然只比 2D 多了一个 D,但是复杂程度不只多了一个。从二维到三维,是从 4 到 9;而在矩阵里头是从 3 3 变成 4 4, 9 到 16 了。

其实,本质上很多东西都与 2D 一致的,只是复杂度不一样而已。这里就举一个简单的 3D 缩放变换的例子。

transform: matrix3d(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1)

psd.js 里面的字体矩阵旋转

psd.js 解析的字体如下:

transform: {
tx: 243.2087255915381,
ty: 662.7336218363249,
xx: 0.3848003848003848,
xy: 0,
yx: 0,
yy: 0.38469353200135453,
}

要将这些属性值转换为 CSS 中的 matrix,可以按照以下方式进行计算:

const transform = {
  tx: 243.2087255915381,
  ty: 662.7336218363249,
  xx: 0.3848003848003848,
  xy: 0,
  yx: 0,
  yy: 0.38469353200135453,
};

const matrixValue = `matrix(${transform.xx}, ${transform.xy}, ${transform.yx}, ${transform.yy}, ${transform.tx}, ${transform.ty})`;
console.log(matrixValue);

在上面的代码中,我们使用 transform 对象中的属性值构建了 matrix 字符串。${transform.xx} 表示水平方向上的缩放比例,${transform.xy} 表示水平方向上的错切值,${transform.yx} 表示垂直方向上的错切值,${transform.yy} 表示垂直方向上的缩放比例,${transform.tx} 表示水平方向上的平移量,${transform.ty} 表示垂直方向上的平移量。

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于1970-01-01发表,共计3027字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)