神奇的 transform 改变元素形状,matrix3d 矩阵变换算法演示
笔记哥 /
04-24 /
20点赞 /
0评论 /
900阅读
CSS `transform` 属性中文翻译过来是 `变换`,始终觉得翻译差那么一点意思。它可以用来改变元素形状,比如旋转、缩放、移动、倾斜等,就是它可以把元素各种拿捏~
transform 特性是在不改变自身尺寸的情况下,对元素进行各种变形,元素自身的文档流位置还是会保留,语言有些空洞,下面看例子。
## 笛卡尔坐标
学习变换之前,先了解一下笛卡尔坐标系,:
>
>
> 在笛卡尔坐标系中,每个 `欧氏空间` 里的点都由横坐标和纵坐标这两个值来确定。在 CSS(和大部分的计算机图形学)中,原点 (0, 0) 在元素的左上角。每个点都使用数学上的向量符号 (x,y) 来描述。
>
>
> ![]()
>
> -- 摘自 MDN
>
意思就是 CSS 的坐标系都是从元素左上角开始的,与数学的坐标系稍有不同,Y 轴的箭头是相反的!!
## transform 的属性值
截至到文章编写时,CSS3 transform 属性值有如下 21 种:
`translate()` 设置 2D 位移。
`translate3d()` 设置 3D 位移。
`translateX()` 设置 X 轴位移。
`translateY()` 设置 Y 轴位移。
`translateZ()` 设置 Z 轴位移。
`skew()` 设置 2D 倾斜。
`skewX()` 设置水平方向倾斜。
`skewY()` 设置垂直方向倾斜。
`scale()` 设置 2D 缩放。
`scale3d()` 设置 3D 缩放。
`scaleX()` 设置 3D X 轴缩放。
`scaleY()` 设置 3D Y 轴缩放。
`scaleZ()` 设置 3D Z 轴缩放。
`rotate()` 设置 2D 旋转角度。
`rotate3d()` 设置 3D 旋转角度。
`rotateX()` 设置 3D X 轴旋转角度。
`rotateY()` 设置 3D Y 轴旋转角度。
`rotateZ()` 设置 3D Z 轴旋转角度。
`perspective()` 设置 3D 透视,值越大会感觉越远。
`matrix()` 2D 矩阵变换。
`matrix3d()` 3D 矩阵变换,最底层的矩阵操作方法。
**transform 的所有属性值都不会改变元素的自身的文档流位置!**
意思就是给元素施加的 transform 仅仅是元素形态上的变化,而不会改变元素自身的位置和大小!!!
### 3D 立方体
为了看出每种变换的效果,先用 CSS 绘制一个立方体。代码如下:
里面也用到了 transform 属性,可以先不管代码意思,只需要知道我们的目的就是绘制一个立方体出来就行。
```csharp
```
呈现效果:
![]()
### translate 位移
`translate` 位移变换,使用 `长度单位` 设置移动距离。虽然名称叫位移,但元素的自身占用的位置还是存在的,变换后的位置也不会占用文档流。
语法:
```csharp
transform: translate(tx, ty); /* 设置 2D 位移 */
transform: translate3d(tx, ty, tz); /* 设置 3D 位移 */
transform: translateX(tx); /* 设置 X 轴位移 */
transform: translateY(ty); /* 设置 Y 轴位移 */
transform: translateZ(tz); /* 设置 Z 轴位移 */
```
使用方式:
注意了本示例给一个盒子添加了多个 transform,仅为了演示使用方式,实际开发中只会生效一个 transform 属性:
```csharp
.box {
transform: translate(20px, 20px);
transform: translate3d(20px, -20px, 200px);
transform: translateX(20px);
transform: translateY(20px);
transform: translateZ(200px);
}
```
呈现效果:
![]()
CSS 的 3D 坐标系 Z 轴都是垂直于屏幕,所以 X 轴上的位移,会呈现近大远小的效果。
### skew 倾斜
`skew` 可以让元素扭成一个平行四边形一样,使用 `角度值` 设置倾斜角度。
语法:
```csharp
transform: skew(ax, ay); /* 设置 2D 倾斜*/
transform: skewX(ax); /* 设置水平方向倾斜*/
transform: skewY(ay); /* 设置垂直方向倾斜*/
```
使用方式:
```csharp
.box {
transform: skew(20deg, -20deg);
transform: skewX(20deg);
transform: skewY(-20deg);
transform: skew(20deg);
}
```
呈现效果:
![]()
### scale 缩放
元素的默认缩放倍率是 1,就是不进行任何缩放,小于 1 表所缩小倍数,大于 1 表示放大倍数,使用 `倍率值` 设置缩放倍率。
语法:
```csharp
transform: scale(sx, sy); /* 设置 2D 缩放 */
transform: scale3d(sx, sy, sz); /* 设置 3D 缩放 */
transform: scaleX(sx); /* 设置 3D X 轴缩放 */
transform: scaleY(sy); /* 设置 3D Y 轴缩放 */
transform: scaleZ(sz); /* 设置 3D Z 轴缩放 */
```
使用方式:
```csharp
.box {
transform: scale(1.1, 1.1);
transform: scale3d(1.2, 1.2, 1.2);
transform: scaleX(0.8);
transform: scaleY(0.8);
transform: scaleZ(2);
}
```
呈现效果:
![]()
### rotate 旋转
`rotate` 可以让元素旋转起来,使用 `角度值` 设置旋转角度,角度单位支持:
- `deg` 度数
- `rad` 弧度
- `grad` 梯度
- `turn` 圈数
一般就 deg 和 turn 比较常用。
语法:
```csharp
transform: rotate(a); /* 设置 2D 旋转角度 */
transform: rotate3d(x, y, z, a); /* 设置 3D 旋转角度 */
transform: rotateX(a); /* 设置 3D X 轴旋转角度 */
transform: rotateY(a); /* 设置 3D Y 轴旋转角度 */
transform: rotateZ(a); /* 设置 3D Z 轴旋转角度 */
```
使用方式:
```csharp
.box {
transform: rotate(45deg);
transform: rotate3d(1, 1, 1, -45deg);
transform: rotateX(0.15turn);
transform: rotateY(0.5rad);
transform: rotateZ(28grad);
}
```
呈现效果:
![]()
### perspective 透视距离
`perspective` 设置 Z 轴的坐标原点(0)离观察者的距离,值越大会感觉越远,使用 `距离单位`。设置为 0 表示 Z 轴贴在了屏幕上,看起来就像无限大一样!!
语法:
```csharp
transform: perspective(d); /* 设置 3D 透视,值越大会感觉越远 */
```
使用方式:
```csharp
.box {
transform: perspective(0);
transform: perspective(1000px);
transform: perspective(300px);
transform: perspective(143rem);
transform: perspective(6.5cm);
}
```
呈现效果:
![]()
## matrix 矩阵变换
矩阵变换是底层实现,旋转、缩放、移动、倾斜这些效果都是上层封装后的语法糖。
矩阵变换语法:
```csharp
transform: matrix(a, b, c, d, tx, ty); /* 2D 矩阵变换*/
transform: matrix3d( /* 3D 矩阵变换,最底层的矩阵操作方法 */
a1, b1, c1, d1, /* X轴的缩放和倾斜 */
a2, b2, c2, d2, /* Y轴的缩放和倾斜 */
a3, b3, c3, d3, /* Z轴的缩放和倾斜 */
a4, b4, c4, d4 /* X、Y、Z轴位移,d4 常量是 1*/
);
/*
matrix(a, b, c, d, tx, ty)
是
matrix3d(
a, b, 0, 0,
c, d, 0, 0,
0, 0, 1, 0,
tx, ty, 0, 1
)
的简写。
*/
```
### 2D 矩阵变换
矩阵算法梦回大学,具体原理就不详解了,有兴趣可以看看`线性代数`相关书籍,具体算法:
![]()
至于后面的 `0 0 1` 是什么,这个又跟 `齐次坐标系` 拉上关系了,有兴趣可参阅维基百科:[https://zh.wikipedia.org/wiki/齐次坐标](https://zh.wikipedia.org/wiki/%E9%BD%90%E6%AC%A1%E5%9D%90%E6%A0%87)
其中的 x,y 表示的元素中的每个像素点的 x,y 坐标,计算的结果则是变化后的 x,y 坐标。
使用方式:
```csharp
.box {
transform: matrix(1.2, 0, 0, 1.2, 0, 0);
/* 与 transform: scaleX(1.2) scaleY(1.2); 相同 */
transform: matrix(1, 0, 0.176327, 1, 0, 0);
/* 与 transform: skewX(10deg); 相同 */
transform: matrix(0.866025, 0.500000, -0.500000, 0.866025, 0, 0);
/* 与 transform: rotate(30deg); 相同 */
transform: matrix(1, 0, 0, 1, 10, 10);
/* 与 transform: translateX(10px) translateY(10px); 相同 */
}
```
呈现效果:
![]()
语法糖的换算规则:
| 变换类型 | 变换方法 | 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) |
### 3D 矩阵变换
2D 变换是 `3*3` 的矩阵,3D 则是 `4*4` 的矩阵,3D 比 2D 多出一个维度的空间,算法复杂度可不是 1+1 那么简单了。
3D 矩阵变换算法:
![]()
最终三维空间坐标:`(x'/w', y'/w', z'/w')`。
**3D 平移使用矩阵表示方法:**
```csharp
transform: matrix3d(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
translateX, translateY, translateZ, 1
);
```
**3D 缩放使用矩阵表示方法:**
```csharp
transform: matrix3d(
scaleX, 0, 0, 0,
0, scaleY, 0, 0,
0, 0, scaleZ, 0,
0, 0, 0, 1
);
```
**3D 倾斜使用矩阵表示方法:**
```csharp
transform: matrix3d(
1, tan(θ_yx), tan(θ_zx), 0,
tan(θ_xy), 1, tan(θ_zy), 0,
tan(θ_xz), tan(θ_yz), 1, 0,
0, 0, 0, 1
);
```
每个 `tanθ` 对应不同平面的倾斜角度。
**旋转使用矩阵表示方法:**
```csharp
/* 绕 Z 轴旋转( */
transform: matrix3d(
cos(angle), sin(angle), 0, 0,
−sin(angle), cos(angle), 0, 0,
0, 0, 1, -1/d,
0, 0, 0, 1
);
/* 绕 X 轴旋转( */
transform: matrix3d(
1, 0, 0, 0,
0, cos(angle), sin(angle), 0,
0, −sin(angle), cos(angle), 0,
0, 0, 0, 1
);
/* 绕 Y 轴旋转( */
transform: matrix3d(
cos(angle), 0, −sin(angle), 0,
0, 1, 0, 0,
sin(angle), 0, cos(angle), 0,
0, 0, 0, 1
);
```
**透视使用矩阵表示方法:**
```csharp
transform: matrix3d(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, -1/d,
0, 0, 0, 1
);
```
呈现效果:
![]()
## 与 transform 相关的属性
| 属性 | 作用 | 典型值 |
| --- | --- | --- |
| transform | 应用变换 | rotate(45deg) translateX(20px) |
| transform-origin | 设置变换原点 | left top, 50% 100% |
| transform-style | 保留子元素 3D 空间 | preserve-3d |
| perspective | 定义 3D 观察深度 | 1000px |
| perspective-origin | 设置观察者视角位置 | 20% 80% |
| backface-visibility | 控制背面可见性 | hidden |
这些属性用于设置与 transform 相关的效果,比如设置变换原点,是否应用 3D 空间,设置透视视角等,这里就不再一一演示,有兴趣可自行写一下例子看看效果。
## 总结
transform 提供的基础变换已足以满足日常需求,一些特殊的变化有可能会用上矩阵,不过这么多年的前端经验来看,能用上矩阵的场景几乎不可见。
由于 transform 不改变文档流的特性,所以在 CSS 动画中,此属性应用非常广泛。
参考资料
https://developer.mozilla.org/zh-CN/docs/Web/CSS/transform-function/matrix
1
2
3
4
5
6
本文来自投稿,不代表本站立场,如若转载,请注明出处:http//www.knowhub.vip/share/2/2540
- 热门的技术博文分享
- 1 . ESP实现Web服务器
- 2 . 从零到一:打造高效的金仓社区 API 集成到 MCP 服务方案
- 3 . 使用C#构建一个同时问多个LLM并总结的小工具
- 4 . .NET 原生驾驭 AI 新基建实战系列Milvus ── 大规模 AI 应用的向量数据库首选
- 5 . 在Avalonia/C#中使用依赖注入过程记录
- 6 . [设计模式/Java] 设计模式之工厂方法模式
- 7 . 5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
- 8 . SQL 中的各种连接 JOIN 的区别总结!
- 9 . JavaScript 中防抖和节流的多种实现方式及应用场景
- 10 . SaltStack 远程命令执行中文乱码问题
- 11 . 推荐10个 DeepSeek 神级提示词,建议搜藏起来使用
- 12 . C#基础:枚举、数组、类型、函数等解析
- 13 . VMware平台的Ubuntu部署完全分布式Hadoop环境
- 14 . C# 多项目打包时如何将项目引用转为包依赖
- 15 . Chrome 135 版本开发者工具(DevTools)更新内容
- 16 . 从零创建npm依赖,只需执行一条命令
- 17 . 关于 Newtonsoft.Json 和 System.Text.Json 混用导致的的序列化不识别的问题
- 18 . 大模型微调实战之训练数据集准备的艺术与科学
- 19 . Windows快速安装MongoDB之Mongo实战
- 20 . 探索 C# 14 新功能:实用特性为编程带来便利
- 相关联分享
- CSS position定位布局全解析
- CSS float 浮动布局应用场景
- JavaScript 3 种书写位置及 script 标签的正确存放位置
- JavaScript 的各种调试方法
- 细说 CSS grid 网格布局子元素相关属性
- 神奇的 transform 改变元素形状,matrix3d 矩阵变换算法演示
- CSS 选择器的优先级
- 移动端适配的视口元标签(meta)常见使用场景
- CSS @media 媒体查询不要只会视口宽度适配详解
- CSS 动画之过渡属性 transition 改变用户体验
- 纯 CSS 使用 column 属性实现瀑布流布局
- CSS offset 路径动画演示
- CSS flex 弹性盒子与 grid 网格布局区别及应用场景
- CSS Flex弹性盒子布局全解析
- Web前端入门之CSS 单位详解
- 浏览器如何确定最终的CSS属性值?解析计算优先级与规则
- 多图细说 CSS grid 网格布局父元素容器相关属性
- CSS 循环动画 animation 效果解析和演示
- Web前端入门之CSS中11种颜色写法全解析
- Web前端入门:CSS元素外观属性(边框、阴影、轮廓、透明度)
- 深入理解 CSS 变量 var() :实现主题换肤与代码功能
- CSS background 元素背景图用法全解
- Web前端入门:CSS常见布局的多种实现方式详解