挑战 transform() 2D
讲在先:今天只讲 2D 的部分~~~
transform()
定义与语法
transform
属性允许你旋转、缩放、倾斜、平移给定元素。这是通过修改 CSS 视觉格式化模型的坐标空间实现的。视觉格式化模型
的英文是 Visual formatting model,简单来说就是一种规则,这个规则描述了浏览器如何获取 、处理和展示 DOM 树。在这个模型中,DOM 树的每个元素都产生 0 个或多个盒子(box)。我们常说的块级元素、内联元素、包含块等等具体又复杂的定义都可以在视觉格式化模型中找到。坐标空间
:显然最常用的坐标模型是笛卡尔坐标
和齐次坐标
。笛卡尔坐标就是平时用到的 x 轴、y 轴、z 轴。但是 CSS 中的 y 轴方向和中学数学 y 轴方向相反。如果坐标原点是浏览器窗口左上角,那 y 轴正半轴向下、x 轴正半轴向右,如下图(来自MDN)。
transform
的值none
:不应用任何变换函数值
:就是下面要介绍的transform-function
。如果只有一个函数,表示应用单个变化函数。如果多个函数,应用多个变化函数。
transform-function
旋转
rotate()
- 这里说的是 2D 平面的旋转,也就是仅包含 x 轴和 y 轴的平面。旋转就是元素围绕一个固定点转动一定角度并且保持元素原来的形状。其中,这个固定点就是下面要讲的
transform-origin()
。默认情况下,元素围绕中心旋转。 rotate()
接受一个角度
类型的参数。如果角度为正,元素就是顺时针旋转。为负就逆时针旋转。如果恰好是 180°,这样的旋转就是点反演。- CSS 中的角度可以参考官网,中文翻译的 : ), 主要有
deg
,grad
,rad
,turn
四种。 .container {
width: 200px; height: 200px;
margin: auto; border: 5px dashed salmon;
margin-top: 100px; position: relative;
}
.container::before {
content: '不转动'; position: absolute; }
.box {
height: 100%; width: 100%; position: absolute;
}
.rotate60 {
background-color: palegreen; transform: rotate(70deg);
}
.rotateMinus30 {
background-color: skyblue; transform: rotate(-50deg);
}
70deg
-50deg
- 当存在多个变换函数时,顺序不一样,最后的效果也不一样。下面的红色
div
先translate
后rotate
,海绿色div
先rotate
后translate
。为什么不一样?因为rotate
之后,div
的坐标空间改变了。本来 x 轴是水平方向,translate
就会使元素沿水平方向移动。现在 x 轴转动 45°,元素自然沿着转动后 45°方向移动。
- 这里说的是 2D 平面的旋转,也就是仅包含 x 轴和 y 轴的平面。旋转就是元素围绕一个固定点转动一定角度并且保持元素原来的形状。其中,这个固定点就是下面要讲的
缩放
scale()
- 缩放在 2D 平面内改变元素的大小。缩放由向量形式定义的,所以可以同事分别设置 X 轴和 Y 轴的缩放。当缩放值在
[-1, 1]
外,元素会放大;否则元素缩小。如果缩放值为负,那么元素相当于transform-origin()
作镜像变换后再缩放。 - 可以看一个例子。
hover
按钮之后,实现按钮变小的效果。 .box {
border: 1px solid skyblue;
background: skyblue;
transition: transform .5s linear 0s;
margin-left: 100px;
}
.box:hover {transform: scale(.8);
}
- 缩放在 2D 平面内改变元素的大小。缩放由向量形式定义的,所以可以同事分别设置 X 轴和 Y 轴的缩放。当缩放值在
扭曲
skew()
- 定义了一个元素在 2D 上的倾斜变换。元素的每一个点都会在水平和垂直方向上转动一定的角度。每一个点的坐标都会根据变换的角度和离
transform-origin()
的距离调整,因此,一个点离transform-origin()
越远,变化的程度越大。 语法
skew(ax)
: 在 x 轴的倾斜角度。skew(ax, ay)
: 在 x 轴和 y 轴倾斜的角度。
先看一个例子吧。粉色的
div
进行了transform: skew(45deg);
的变换。为什么这个变换是这个效果?不是转动45deg
吗,为什么好像转动了-45deg
一样?- 我们首先明白
skew
操作时如何应用到元素上的每一个点(x, y, z)
的。因为skew
只在 2D 平面操作,所以点坐标可以简化为(x, y, 0)
。 MDN 的文档 介绍skew
操作的矩阵变化就是下面的左矩阵。其中ax
是沿 x 轴变换的角度(这个例子中的45deg
),ay
是沿 y 轴变换的角度。根据矩阵运算,一个 33 的矩阵和另一个 31 的矩阵相乘的结果是 3*1 的矩阵,即点变换后的位置(x', y', z')
。 [ 1 t a n ( a x ) 0 t a n ( a y ) 1 0 0 0 0 ] ∗ [ x y z ] \begin{bmatrix} 1 & tan(ax) & 0 \\ tan(ay) & 1 & 0 \\ 0 & 0 & 0 \end{bmatrix} * \begin{bmatrix} x \\ y \\ z \end{bmatrix} ⎣⎡1tan(ay)0tan(ax)10000⎦⎤∗⎣⎡xyz⎦⎤
x' = 1*x + tan(ax)*y + 0*z
y' = x*tan(ay) + 1*y + 0*z
z' = 0*x + 0*y + 0*z
因为不涉及 y 轴变化,所以
ay = 0, tan(ay) = 0
, 又因为ax = 45°, tan(45°) = 1
。上面的方程就可以简化为x' = x + y
y' = y
z' = 0
- 这下一目了然了?,点的 y 轴坐标未变化,x 轴的坐标移动了一部分。所以 y 轴正半轴的点向右移,因为 y 坐标为正;y 轴负半轴的点向左移,因为 y 坐标为负。是不是和下图的结果一模一样啊?。
- 我们首先明白
- 定义了一个元素在 2D 上的倾斜变换。元素的每一个点都会在水平和垂直方向上转动一定的角度。每一个点的坐标都会根据变换的角度和离
移动
translate()
- 水平和/或垂直方向上重新定位元素。由二维向量构成,向量的坐标定义了元素在每个方向上移动多少。接受长度类型的数据作为参数,可以是百分数。当值为百分数时,要相对于
transform-box
属性计算(⚠:该属性浏览器还在支持中…结果可能和你想的不一样)。 语法
- 一个参数:只有一个值时表示 x 轴方向的移动,y 方向的移动为 0。比如
translate(20px)
等同于translate(20px, 0)
。 - 两个参数:分别表示 x 轴方向和 y 轴方向的移动。
- 一个参数:只有一个值时表示 x 轴方向的移动,y 方向的移动为 0。比如
先看一个例子。点击红色方块(宽高均
100px
,padding=25px
,border=25px
, 右margin
是10px
)进行transform: translate(10px, 20%);
的变换。可以看到,x 坐标增加了10
, y 坐标增加了40 = ((100+2*25+2*25) * 20%)
- 水平和/或垂直方向上重新定位元素。由二维向量构成,向量的坐标定义了元素在每个方向上移动多少。接受长度类型的数据作为参数,可以是百分数。当值为百分数时,要相对于
transform-origin()
可以设置变换的原(
origin
)。原就是一个点,整个变换都围绕着这个点应用。例如,rotate()
的原就是旋转中心。效果上,可以按下面步骤理解- 第一步,将
transform-origin()
设置的原移动到真正的原(0, 0)
- 第二步,应用变换
- 第三步,将
(0, 0)
的原移动会它最初的地方。
- 第一步,将
语法
一个值
:原在 x 轴的偏离。- 可以是长度加单位,比如
20px
,也可以是百分数,比如30%
。这样的值表示原离元素左边界的长度。如果为 0,表示原就在元素的左边界上。 - 还有关键字
left
,right
,center
表示原在元素的左边界、右边界、中心。在 y 轴的偏移关键字top
,bottom
,center
分别表示原在元素的上边界、下边界、中心。
- 可以是长度加单位,比如
两个值
:原分别在 x 轴和 y 轴的偏离。
rotate()
rotate()
默认转动原是0, 0
,改变原可以看到下面的效果。每个蓝色方块都转动 360 度,但是原却个个都不同。
scale
scale
默认变换中心也是(0, 0)
。我们可以将原移动到左上看看效果。深绿色的方块是浅绿色方块经过scale(1.5)
变换得到的,
还没有评论,来说两句吧...