一、基本介绍
1 2 3 4 5 6 7
| transform # 变形
transition # 过渡
animation # 自定义动画
perspective # 指定透视距离,用于 3D 效果
|
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)
|
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)
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)
|
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)
|
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
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
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 效果。
该属性主要设置在父级元素上。
六、参考资料