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

几何意义

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

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

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

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

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

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

简单理解:某个点的位置为(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); 是传递的基向量的坐标。

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

连续变换是矩阵相乘

矩阵应用

javascript 复制代码
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()) 旋转,拉伸,平移变换,本质上都是通过 Matrix() 方法实现的。CSS 提供 Transform:rotate这种方式是一种语法糖。方便写更容易维护的代码,并且操作简单。

线性变换

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

仿射变换 = 线性变换 + 平移变换 仿射变换矩阵中: 基向量的变化: **坐标原点的变化: **

平移计算

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

css 复制代码
#mydiv{ 	transform: matrix(1, 0, 0, 1, 150, 150); 	}

相当于transform: translate(150px,150px)。点(220px,220px)的坐标 齐次坐标能区分是一个向量还是一个点 从普通坐标转换成齐次坐标时 如果(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表示就是:

scss 复制代码
matrix((1 - k * k) / (1 + k * k), 2k / (1 + k * k), 2k / (1 + k * k), (k * k - 1) / (1 + k * k), 0, 0)

通过 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 transform: matrix(1.0606, 1.0606, -1.0606, 1.0606, 0, 1)

常用参数参考

参考

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

相关推荐
王大师王文峰11 小时前
HTML 入门到进阶:语义化标签、表单与多媒体一篇打通【语义化布局、表单校验、video/audio、Canvas、无障碍与 SEO】
前端·css·node.js·html·css3·jquery·html5
晓得迷路了1 天前
栗子前端技术周刊第 150 期 - Stack Overflow 开发者调查结果、TanStack Start 1.0...
javascript·css·后端
ShineWinsu3 天前
对于CSS:弹性布局(Flexbox)的解析
前端·css·面试·浏览器·web·网页·弹性布局
云老大-阿里云国际站代理商3 天前
华为云国际站渠道代理商:CSS查询很慢但CPU不高?磁盘I/O、JVM与分片问题怎么排查
css·jvm·华为云
定栓3 天前
Webpack迁到Vite第三节:Less 与 CSS 处理
css·webpack·less
ShineWinsu3 天前
对于JavaScript:初识JavaScript以及输入输出
java·开发语言·前端·javascript·css·面试·html
码银3 天前
【web】基于HTML/CSS,JavaScript + Three.js做3D流程图
前端·css·html
keyipatience4 天前
JavaScript学习(1)书写位置,变量、数据类型、运算符
开发语言·前端·javascript·css·学习
酷炫码神4 天前
Day 2|CSS 盒模型:把昨天的骨架,变成能看的页面
前端·css
oicola4 天前
Ant Design v5 vs Tailwind CSS:组件库与样式框架的终极对决
前端·css