一、基本介绍

1
2
3
4
5
6
7
transform # 变形

transition # 过渡

animation # 自定义动画

perspective # 指定透视距离,用于 3D 效果

二、transform

2.1 移动(translate)

  • 功能:让元素进行位移。水平向右为正,垂直向下为正,往前为正,

  • 语法:

1
2
3
4
5
6
7
8
9
10
11
translateX(x) # X 轴(水平)方向位移

translateY(y) # Y 轴(垂直)方向位移

translateZ(z) # Z 轴(前后)方向位移,需要设置 perspective 属性才生效

复合写法:

translate(x,y)

translate3d(x,y,z)
  • 单位:px,em,rem,百分比。

  • 演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>translate</title>
<style>
#container {
perspective: 800px;
perspective-origin: 50% 50%;
transition: transform 1s;
}

.square {
width: 100px;
height: 100px;
background-color: #69c;
margin: 30px auto;
}

.option {
margin: 0 auto;
font-size: 16px;
font-weight: bold;
width: 750px;
}

.option .range-control {
width: 721px;
}

</style>
</head>
<body>
<div id="container">
<div id="square" class="square"> </div>
</div>
<div id="option" class="option">
<p> translate X: <span id="translatex-span"> 0 </span> px </p>
<input type="range" min="-360" max="360" id="translatex" value="0" class="range-control" onchange="testTranslate()" />
<br/>
<p> translate Y: <span id="translatey-span"> 0 </span> px </p>
<input type="range" min="-360" max="360" id="translatey" value="0" class="range-control" onchange="testTranslate()" />
<br/>
<p> translate Z: <span id="translatez-span"> 0 </span> px </p>
<input type="range" min="-360" max="360" id="translatez" value="0" class="range-control" onchange="testTranslate()" />
<br/>
</div>
<script>
function testTranslate() {
let x = document.getElementById("translatex").value;
let y = document.getElementById("translatey").value;
let z = document.getElementById("translatez").value;

document.getElementById('square').style.transform = "translateX(" + x + "px) translateY(" + y + "px) translateZ(" + z + "px)";

document.getElementById('translatex-span').innerText = x;
document.getElementById('translatey-span').innerText = y;
document.getElementById('translatez-span').innerText = z;
}
</script>
</body>
</html>

2.2 旋转(rotate)

  • 功能:让元素绕中心点旋转。顺时为正,逆时为负。旋转中心点位置由 transform-origin 属性决定,默认以元素中心为旋转点。

  • 语法:

1
2
3
4
5
6
7
8
9
10
11
rotateX(x) # 绕 X 轴上的旋转

rotateY(y) # 绕 Y 轴上的旋转

rotateZ(z) # 绕 Z 轴上的旋转,不需要设置 perspective 属性

复合写法:

rotate(x,y)

rotate3d(x,y,z)
  • 单位:deg

  • 演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>rotate</title>
<style>
#container {
perspective: 800px;
perspective-origin: 50% 50%;
transition: transform 1s;
}

.square {
width: 100px;
height: 100px;
background-color: #69c;
margin: 30px auto;
}

.option {
margin: 0 auto;
font-size: 16px;
font-weight: bold;
width: 750px;
}

.option .range-control {
width: 721px;
}

</style>
</head>
<body>
<div id="container">
<div id="square" class="square"> </div>
</div>
<div id="option" class="option">
<p> rotate X: <span id="degx-span"> 0 </span> px </p>
<input type="range" min="-360" max="360" id="rotatex" value="0" class="range-control" onchange="testRotate()" />
<br/>
<p> rotate Y: <span id="degy-span"> 0 </span> px </p>
<input type="range" min="-360" max="360" id="rotatey" value="0" class="range-control" onchange="testRotate()" />
<br/>
<p> rotate Z: <span id="degz-span"> 0 </span> px </p>
<input type="range" min="-360" max="360" id="rotatez" value="0" class="range-control" onchange="testRotate()" />
<br/>
</div>
<script>
function testRotate() {
let x = document.getElementById("rotatex").value;
let y = document.getElementById("rotatey").value;
let z = document.getElementById("rotatez").value;

document.getElementById('square').style.transform = "rotateX(" + x + "deg) rotateY(" + y + "deg) rotateZ(" + z + "deg)";

document.getElementById('degx-span').innerText = x;
document.getElementById('degy-span').innerText = y;
document.getElementById('degz-span').innerText = z;
}
</script>
</body>
</html>

2.3 缩放(scale)

  • 功能:让元素以中心点进行缩放

  • 语法:

1
2
3
4
5
6
7
8
9
10
11
scaleX(x) # X 轴(水平)方向缩放

scaleY(y) # Y 轴(垂直)方向缩放

scaleZ(z) # Z 轴(前后)方向缩放,用于 3D 效果

复合写法:

scale(x,y)

scale3d(x,y,z)
  • 单位:无

  • 演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>scale</title>
<style>
#container {
perspective: 800px;
perspective-origin: 50% 50%;
transition: transform 1s;
}

.square {
width: 100px;
height: 100px;
background-color: #69c;
margin: 30px auto;
}

.option {
margin: 0 auto;
font-size: 16px;
font-weight: bold;
width: 750px;
}

.option .range-control {
width: 721px;
}

</style>
</head>
<body>
<div id="container">
<div id="square" class="square">
</div>
</div>
<div id="option" class="option">
<p> scale X: <span id="scalex-span"> 1 </span> </p>
<input type="range" min="0" max="2" step="0.1" id="scalex" value="1" class="range-control" onchange="testScale()" />
<br/>
<p> scale Y: <span id="scaley-span"> 1 </span> </p>
<input type="range" min="0" max="2" step="0.1" id="scaley" value="1" class="range-control" onchange="testScale()" />
<br/>
<p> scale Z: <span id="scalez-span"> 1 </span> </p>
<input type="range" min="0" max="2" step="0.1" id="scalez" value="1" class="range-control" onchange="testScale()" />
<br/>
</div>
<script>
function testScale() {
let x = document.getElementById("scalex").value;
let y = document.getElementById("scaley").value;
let z = document.getElementById("scalez").value;

document.getElementById('square').style.transform = "scaleX(" + x + ") scaleY(" + y + ") scaleZ(" + z + ")";

document.getElementById('scalex-span').innerText = x;
document.getElementById('scaley-span').innerText = y;
document.getElementById('scalez-span').innerText = z;
}
</script>
</body>
</html>

由于演示的 div 是 2D 平面,因此位于 3D 空间也无法查看其在 Z 轴方向缩放的效果。

2.4 扭曲(skew)

  • 功能:让元素绕中心点进行扭曲。顺时为正,逆时为负。

  • 语法:

1
2
3
4
5
6
7
skewX(x) # X 轴(水平)方向扭曲

skewY(y) # Y 轴(垂直)方向扭曲

复合写法:

skew(x,y)
  • 单位:deg

  • 演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>skew</title>
<style>
#container {
perspective: 800px;
perspective-origin: 50% 50%;
transition: transform 1s;
}

.square {
width: 100px;
height: 100px;
background-color: #69c;
margin: 30px auto;
}

.option {
margin: 0 auto;
font-size: 16px;
font-weight: bold;
width: 750px;
}

.option .range-control {
width: 721px;
}

</style>
</head>
<body>
<div class="container">
<div id="square" class="square">
</div>
</div>
<div id="option" class="option">
<p> skew X: <span id="skewx-span"> 0 </span> deg </p>
<input type="range" min="-360" max="360" id="skewx" value="0" class="range-control" onchange="testSkew()" />
<br/>
<p> skew Y: <span id="skewy-span"> 0 </span> deg </p>
<input type="range" min="-360" max="360" id="skewy" value="0" class="range-control" onchange="testSkew()" />
<br/>
</div>
<script>
function testSkew() {
let x = document.getElementById("skewx").value;
let y = document.getElementById("skewy").value;

document.getElementById('square').style.transform = "skewX(" + x + "deg) skewY(" + y + "deg)";

document.getElementById('skewx-span').innerText = x;
document.getElementById('skewy-span').innerText = y;
}
</script>
</body>
</html>

2.5 矩阵变形:matrix()

上述 4 种动画方式功能的底层都是通过 matrix() 实现的

1
2
3
4
5
6
7
translate(tx,ty)==matrix(1,0,0,1,tx,ty)

scale(sx,sy)==matrix(sx,0,0,sy,0,0)

rotate(θ)==matrix(cosθ,sinθ,-sinθ,cosθ,0,0)

skew(θx,θy)==matrix(1,tan(θy),tan(θx),1,0,0)

掌握上述4种即可。

三、transition

  • 功能:在一定的时间内平滑地把属性值从起始状态改到结束状态

  • 语法:transition 属性 耗时 速度曲线 延时

  • 默认值:all 0s ease 0s;

  • 演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>transition</title>
<style>
.container {
width: 600px;
margin: 0 auto;
}

.progress-bar {
height: 40px;
width: 40px;
background-color: #69c;
}

.progress-bar:hover {
width: 600px;
}

#bar1 {
transition: width 5s linear;
}

#bar2 {
transition: width 5s ease;
}

#bar3 {
transition: width 5s ease-in;
}

#bar4 {
transition: width 5s ease-out;
}

#bar5 {
transition: width 5s ease-in-out;
}
</style>
</head>
<body>
<div class="container">
<p> linear </p>
<div class="progress-bar" id="bar1"> </div>
<p> ease </p>
<div class="progress-bar" id="bar2"> </div>
<p> ease-in </p>
<div class="progress-bar" id="bar3"> </div>
<p> ease-out </p>
<div class="progress-bar" id="bar4"> </div>
<p> ease-in-out </p>
<div class="progress-bar" id="bar5"> </div>
</div>
</body>
</html>

四、animation

  • 功能:让元素实现动画效果,效果比前两个属性更强大。

  • 语法:animation 动画名称 持续时间 速度曲线 延时 循环次数 方向 动画结束状态 动画状态

  • 演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>transition</title>
<style>
.container {
width: 400px;
height: 60px;
text-align: center;
margin: 50px auto;
}

i {
display: inline-block;
width: 10px;
height: 50px;
background-color: #69c;
animation: change 1s infinite;
}

i:nth-of-type(1) {
animation-delay:0.1s;
}

i:nth-of-type(2) {
animation-delay:0.2s;
}

i:nth-of-type(3) {
animation-delay:0.3s;
}

i:nth-of-type(4) {
animation-delay:0.4s;
}

i:nth-of-type(5) {
animation-delay:0.5s;
}

@keyframes change {
20% {
transform: scaleY(0.3);
}
100% {
transform: scaleY(1);
}
}

</style>
</head>
<body>
<div class="container">
<i></i>
<i></i>
<i></i>
<i></i>
<i></i>
</div>
</body>
</html>

五、perspective

  • 功能:指定观察者与「z=0」平面的距离,使具有三维位置变换的元素产生透视效果。

根据下图理解:

其中,中间矩形表示浏览器,矩形左侧表示观察者观察视点,矩形右侧表示浏览器中的图像世界(2D/3D)。

  • 演示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>perspective</title>
<style>
.container {
transition: transform 1s;
}

.container h2 {
text-align:center;
}

.square {
width: 100px;
height: 100px;
background-color: #69c;
margin: 30px auto;
}

.perspective {
perspective:800px;
}

.square2 {
width: 100px;
height: 100px;
background-color: #69c;
margin: 30px auto;
transform:rotateX(45deg);
}
</style>
</head>
<body>
<div class="container">
<h2>原图</h2>
<div class="square">
</div>
</div>
<div class="container">
<h2>未设置 perspective,rotateX(45deg)</h2>
<div class="square square2">
</div>
</div>
<div class="container perspective">
<h2>设置 perspective,rotateX(45deg)</h2>
<div class="square square2">
</div>
</div>
</body>
</html>

未设置 perspective 属性,元素即便 X 轴旋转 45 度后,左右两边的线还是平行的,未体现 3D 效果。

设置 perspective 属性,元素进过旋转角度后查看的效果产生 3D 效果。

该属性主要设置在父级元素上。

六、参考资料