使用 CSS3 Transform 的 Matrix 实现镜像翻转

几何意义

SVG 是一种矢量图形,放大可以不失真。

线性代数的 数值操作 和 几何直观

几何直观:更容易在不同场景中引入概念来解决问题。如:sinA

向量可以是任何东西,只要保证向量相加和数字和向量相乘有意义即可。
向量相加和向量数乘贯彻向量的始终。
向量是一个箭头(有方向,有距离),一个点,二维平面是一个坐标。

数乘就是向量的缩放,2*[2,3]

i 是 x 轴的基向量
j 是 y 轴的基向量
坐标【2,-3】是标量,将基向量拉长。[2,-3]相当于经过缩放的向量的和,2i+(-3)j

使用 CSS3 Transform 的 Matrix 实现镜像翻转

使用 CSS3 Transform 的 Matrix 实现镜像翻转

使用 CSS3 Transform 的 Matrix 实现镜像翻转

使用 CSS3 Transform 的 Matrix 实现镜像翻转

简单理解:某个点的位置为(2,3)。开始时在i(1,0)方向走两步,在j(0,1)方向走3 步。后来逆时针旋转 90 度,变成在 i 上走(0,1)上走 2 步,在 j(-1,,0)上走3 步。
matrix(0, -1, 1, 0, 0, 0); 是传递的基向量的坐标。

线性变换是指定变换后的基向量的坐标,然后根据坐标进行对应的数乘运算。
一个矩阵就是对空间的一种线性变换。

连续变换是矩阵相乘

矩阵应用

transform: translate(10px, 10px); => transform: matrix(1, 0, 0, 1, 10, 10);

transform: scale(1, 0.5); => transform: matrix(1, 0, 0, 0.5, 0, 0);

transform: rotate(45deg); => matrix(cos45,sin45,-sin45,cos45,0,0) => transform: matrix(0.866025,0.500000,-0.500000,0.866025,0,0);

transform: skew(30deg, 30deg); => matrix(1,tan(θy),tan(θx),1,0,0)
 => transform: matrix(1, 0.57735, 0.57735, 1, 0, 0);
变换类型 变换方法 matrix 写法
平移 translate(translateX, translateY) matrix(1, 0, 0, 1, translateX, translateY)
缩放 scale(scaleX, scaleY) matrix(scaleX, 0, 0, scaleY, 0, 0)
斜拉 skew(angleX, angleY) matrix(1, tan(angleY), tan(angleX), 1, 0, 0)
旋转 rotate(angle) matrix(cos(angle), sin(angle), -sin(angle), cos(angle), 0, 0)

matrix(scaleX(), skewY(), skewX(), scaleY(), translateX(), translateY())
使用 CSS3 Transform 的 Matrix 实现镜像翻转
旋转,拉伸,平移变换,本质上都是通过 Matrix() 方法实现的。CSS 提供 Transform:rotate这种方式是一种语法糖。方便写更容易维护的代码,并且操作简单。
使用 CSS3 Transform 的 Matrix 实现镜像翻转

线性变换

线性变换两个要求:直线依然是直线,原点保持固定不变。意思是:保持网格线平行且等距分布。缩放,旋转可以实现。也就是 a,b,c,d四个参数。但是平移需要移动坐标原点,所以引入了 e,f两个参数分别是坐标原点的变化。

使用 CSS3 Transform 的 Matrix 实现镜像翻转
仿射变换 = 线性变换 + 平移变换
仿射变换矩阵中:使用 CSS3 Transform 的 Matrix 实现镜像翻转
基向量的变化:使用 CSS3 Transform 的 Matrix 实现镜像翻转
**坐标原点的变化: **使用 CSS3 Transform 的 Matrix 实现镜像翻转

平移计算

CSS3 transform matrix矩阵偏移分解实例页面

#mydiv{ 	transform: matrix(1, 0, 0, 1, 150, 150); 	}

相当于transform: translate(150px,150px)。点(220px,220px)的坐标
使用 CSS3 Transform 的 Matrix 实现镜像翻转
齐次坐标能区分是一个向量还是一个点
从普通坐标转换成齐次坐标时
如果(x,y,z)是个点,则变为(x,y,z,1);
如果(x,y,z)是个向量,则变为(x,y,z,0)
反之成立

使用场景

  1. 当使用 transform 不满足需求,没有提供对应的接口,需要使用更复杂的变换操作,可以使用 matrix。如:镜像对称效果。
  2. 当位移,变换操作较多,计算较复杂时,使用 tansform 不方便,可以新建一个 6 个参数的数组,所有操作计算结束后,将数组作为参数传递给 Matrix()。 【连续变换:矩阵相乘】

镜像对称

任意对称轴都可以用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)

使用 CSS3 Transform 的 Matrix 实现镜像翻转
通过 2 个方程

  1. 垂直的两条线斜率相乘等于-1 :(y – y’) / (x – x’) = -1 / k → ky – ky’ = -x + x’
  2. 因为镜像,所以中点在轴线上: (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)

只需要知道对称轴的斜率 k ,就可以算出来matrix 中 a,b,c,d的值,如果对称轴不经过坐标轴原点,使用 e,f 进行平移。
踩了两个坑:

  1. 斜率的计算需要是y的变化量/x的变化量、符号不要搞错了:(y – y’) / (x – x’) 或者 (y’- y) / (x’ – x)
  2. 数学中的y=x在web开发中需要注意y轴是向下的,和数学中的y轴相反

复合变换

复合变换是连续进行多个变换。
比如:放大 1.5 倍并旋转 45°。
transform: rotate(45deg) scale(1.5);
旋转矩阵表示为向量,[cos(a) sin(a) -sin(a) cos(a) 0 0]其中_a_是角度。为了缩放,我们需要使用矩阵[sx 0 0 sy 0 0]
使用 CSS3 Transform 的 Matrix 实现镜像翻转
transform: matrix(1.0606, 1.0606, -1.0606, 1.0606, 0, 1)

常用参数参考
使用 CSS3 Transform 的 Matrix 实现镜像翻转

参考

Understanding the CSS Transforms Matrix
理解CSS3 transform中的Matrix(矩阵)
仿射变换及其变换矩阵的理解
线性映射的矩阵的例子

原文链接:https://juejin.cn/post/7321543529268199436 作者:夕阳下的橘子

(0)
上一篇 2024年1月9日 上午10:05
下一篇 2024年1月9日 上午10:16

相关推荐

发表回复

登录后才能评论