使用 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(矩阵) 仿射变换及其变换矩阵的理解 线性映射的矩阵的例子

相关推荐
GDAL17 分钟前
Tailwind CSS Flex 布局深入全面教程
前端·css·tailwindcss
KLW7532 分钟前
vue v-if和v-show比较
前端·css·css3
幻影星空VR元宇宙1 小时前
9D VR体验馆设备投资解析与7D互动影院的市场前景
css·百慕大冒险·幻影星空
漂流瓶jz11 小时前
PostCSS完全指南:功能/配置/插件/SourceMap/AST/插件开发/自定义语法
前端·javascript·css
栀秋66614 小时前
Tailwind CSS:用“类名编程”重构你的前端开发体验
前端·css
霍理迪15 小时前
CSS盒模型布局规则
前端·javascript·css
程序员龙语16 小时前
CSS 高级选择器应用
前端·css
程序员修心16 小时前
CSS文本样式全解析:11个核心属性详解
前端·css
苹果电脑的鑫鑫19 小时前
Css画圆弧的方法
前端·css
worxfr20 小时前
CSS Flexbox 布局完全指南
前端·css