Web进阶:Day2
Date: January 4, 2023
Summary: 空间转换、动画
空间转换
**空间:**是从坐标轴角度定义的。 x 、y 和z三条坐标轴构成了一个立体空间,z轴位置与视线方向相同
空间转换也叫3D转换
属性:transform
语法:
transform: translate3d(x, y, z);
transform: translateX(值);
transform: translateY(值);
transform: translateZ(值);
取值(正负均可)
像素单位数值、百分比
案例:
-
Code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>空间位移</title> <style> .box { width: 200px; height: 200px; margin: 100px auto; background-color: pink; transition: all 0.5s; } .box:hover { /* transform: translate3d(50px, 100px, 200px); */ transform: translateX(100px); transform: translateY(100px); transform: translateZ(100px); } </style> </head> <body> <div class="box"></div> </body> </html>
透视
透视概念
透视距离也称为视距,所谓的视距就是人的眼睛到屏幕的距离
属性(添加给父级)
perspective: 值;
取值:像素单位数值, 数值一般在800 – 1200
透视距离也称为视距,所谓的视距就是人的眼睛到屏幕的距离。
作用
空间转换时,为元素添加近大远小、近实远虚的视觉效果
案例:
<style>
body {
/* 为了实现透视的效果,需要设置一下父级 */
/* perspective 是为了设置人眼和屏幕的距离 */
perspective: 1000px;
/* perspective: 200px; */
/* perspective: 10000px; */
}
.box {
width: 200px;
height: 200px;
margin: 100px auto;
background-color: pink;
transition: all 0.5s;
}
.box:hover{
transform: translateZ(200px);
/* transform: translateZ(-200px); */
}
</style>
空间旋转
语法:
/*沿着Z轴转*/
transform: rotateZ(值);
transform: rotateX(值);
transform: rotateY(值);
案例:X轴负向旋转
-
Code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>空间旋转-X轴</title> <style> .box { width: 300px; margin: 100px auto; } img { width: 300px; transition: all 2s; } .box { /* 透视效果:近大远小,近实远虚 */ perspective: 1000px; } .box img:hover { transform: rotateX(60deg); transform: rotateX(-60deg); } </style> </head> <body> <div class="box"> <img src="./images/hero.jpeg" alt=""> </div> </body> </html>
**注意:**需要添加视距perspective, 效果更好
左手法则
左手法则
判断旋转方向:
- 左手握住旋转轴
- 拇指指向正值方向
- 手指弯曲方向为旋转正值方向
拓展:了解
rotate3d(x, y, z, 角度度数) :用来设置自定义旋转轴的位置及旋转的角度
x,y,z 取值为0-1之间的数字
立体呈现
思考:使用perspective透视属性能否呈现立体图形?
答:不能,perspective只增加近大远小、近实远虚的视觉效果。
实现方法
添加 transform-style: preserve-3d;
使子元素处于真正的3d空间
默认值flat,表示子元素处于2D平面内呈现
呈现立体图形步骤
- 盒子父元素添加 transform-style: preserve-3d;
- 按需求设置子盒子的位置(位移或旋转)
-
Code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>立体呈现</title> <style> .cube { position: relative; width: 200px; height: 200px; margin: 100px auto; background-color: pink; transition: all 2s; transform-style: preserve-3d; } .cube div { position: absolute; width: 200px; height: 200px; /* 将位置定在左上角开始 */ left: 0; top: 0; } .front { background-color: orange; /* 向我走近200px 没有设置perspective 仅为让橙色在绿色上面 */ transform: translateZ(200px); } .back { background-color: green; } /* cube hover 为了看空间感效果 */ .cube:hover { transform: rotateY(90deg); } </style> </head> <body> <div class="cube"> <div class="front">前面</div> <div class="back">后面</div> </div> </body> </html>
注意:
- 空间内,转换元素都有自已独立的坐标轴,互不干扰
3D导航
思考:绿色和橙色盒子是如何摆放的?
搭建立方体
绿色盒子是立方体的前面
橙色盒子是立方体的上面
结论: 绿色和橙色部分共需要3个标签
1个父级标签
绿色和橙色共2个标签(子级)
实现思路
- 搭建立方体:绿色盒子是立方体的前面,橙色盒子是立方体的上面
- 添加hover状态旋转切换效果
实现思路
-
搭建立方体
li标签添加立体呈现属性`transform-style: preserve-3d;` 添加旋转属性(为了便于观察效果,案例完成后删除即可)
a标签
调节位置
-
搭建立方体
调节a标签的位置
a标签定位(子绝父相)英文部分添加旋转和位移样式
中文部分添加位移样式
- 过渡效果
鼠标滑过li, 添加空间旋转样式
li添加过渡属性
注意: 案例完成后,删除li的旋转样式。
-
Code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>3D导航</title> <style> ul { margin: 0; padding: 0; list-style: none; } .navs { width: 300px; height: 40px; margin: 50px auto; } .navs li { position: relative; float: left; width: 100px; height: 40px; line-height: 40px; transition: all .5s; transform-style: preserve-3d; /* 旋转: 让大家在写代码的过程中看到立体盒子 */ /* transform: rotateX(-20deg) rotateY(30deg); */ /* 测试缩放效果 */ /* 三个方向都进行缩放 */ /* transform: scale3d(0.5, 1.1, 2); */ } .navs li a { position: absolute; left: 0; top: 0; display: block; width: 100%; height: 100%; text-align: center; text-decoration: none; color: #fff; } .navs li a:first-child { background-color: green; transform: translateZ(20px); } .navs li a:last-child { background-color: orange; /* 躺平x轴旋转 立方体的顶部,位移z(确保看到这个盒子) */ transform: rotateX(90deg) translateZ(20px); } /* li:hover 立方体旋转 */ .navs li:hover { transform: rotateX(-90deg); } </style> </head> <body> <div class="navs"> <ul> <li> <a href="#">首页</a> <a href="#">Index</a> </li> <li> <a href="#">登录</a> <a href="#">Login</a> </li> <li> <a href="#">注册</a> <a href="#">Register</a> </li> </ul> </div> </body> </html>
空间缩放
使用scale实现空间缩放效果
语法:
transform: scaleX(倍数);
transform: scaleY(倍数);
transform: scaleZ(倍数);
transform: scale3d(x, y, z);
注:代码在上面例子中
动画
动画基础
思考:过渡可以实现什么效果?
答:实现2个状态间的变化过程
动画效果:
实现多个状态间的变化过程,动画过程可控(重复播放、最终画面、是否暂停)
动画原理:
动画的本质是快速切换大量图片时在人脑中形成的具有连续性的画面
构成动画的最小单元:帧或动画帧
实现步骤:
-
定义动画
@keyframes 动画名称 { from {} to {} } @keyframes 动画名称 { 0% {} 10% {} 50% {} 100% {} }
-
使用动画
animation: 动画名称 动画花费时长
动画属性:
animation : 动画名称 动画时长 速度曲线 延迟时间 重复次数 动画方向 执行完毕时状态
注意:
动画名称和动画时长必须赋值
取值不分先后顺序
如果有2个时间值,第一个时间表示动画时长,第二个时间表示延迟时间
当然,我们这里也可以将属性拆分使用
复合写法案例:
-
Code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>动画实现步骤</title> <style> .box { width: 200px; height: 100px; background-color: pink; /* 使用动画 */ animation: change 1s; } /* 一. 定义动画:从200变大到600 */ /* @keyframes change { from { width: 200px; } to { width: 600px; } } */ /* 二. 定义动画:200 到 500*300 到 800*500 */ /* 百分比指的是动画总时长的占比 */ @keyframes change { 0% { width: 200px; } 50% { width: 500px; height: 300px; } 100% { width: 800px; height: 500px; } } </style> </head> <body> <div class="box"></div> </body> </html>
拆分写法案例:
-
Code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>animation拆分写法</title> <style> .box { width: 200px; height: 100px; background-color: pink; animation-name: change; animation-duration: 1s; animation-iteration-count: infinite; } .box:hover { /* 鼠标移入的时候暂停动画 */ animation-play-state: paused; } @keyframes change { from { width: 200px; } to { width: 600px; } } </style> </head> <body> <div class="box"></div> </body> </html>
逐帧动画
目标:使用steps实现逐帧动画
补间动画与逐帧动画:
注意:一般的动画都是补间动画
逐帧动画:帧动画。开发中,一般配合精灵图实现动画效果。
animation-timing-function: steps(N);
将动画过程等分成N份
-
Code :
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>精灵动画</title> <style> .box { /* 1680/12 : 保证显示区域的尺寸和一个精灵小图的尺寸相同 */ width: 140px; height: 140px; /* border: 1px solid #000; */ background-image: url(./images/bg.png); /* 12: 净零小图的个数 */ animation: move 1s steps(12) infinite, run 1s forwards ; } @keyframes move { /* from { background-position: 0 0; } */ to { /* 1680: 精灵图的宽度 */ background-position: -1680px 0; } } /* 定义一个盒子移动的动画 800px */ @keyframes run { /* 动画的开始状态和盒子的默认样式相同的, 可以省略开始状态的代码 */ /* from { transform: translateX(0); } */ to { transform: translateX(800px); } } </style> </head> <body> <div class="box"></div> </body> </html>
精灵动画制作步骤
准备显示区域
设置盒子尺寸是一张小图的尺寸,背景图为当前精灵图
定义动画
改变背景图的位置(移动的距离就是精灵图的宽度)
使用动画
添加速度曲线steps(N),N与精灵图上小图个数相同
添加无限重复效果
综合案例
走马灯(无缝动画的做法)
目标:使用animation实现逐帧图片位移效果
关键点:
把开头三张图片复制一份,放到尾部
当播放结束时,程序就会自动重新放映,从头开始,从而形成一种循环的感觉
-
Code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <style> * { padding: 0; margin: 0; } li { list-style: none; } img { width: 200px; } .box { width: 600px; height: 112px; border: 5px solid #000; margin: 100px auto; overflow: hidden; } .box ul { width: 2000px; animation: move 5s infinite linear; } .box li { float: left; } /* 定义动画:位移, ul 左侧使用 x -1400 */ @keyframes move { to { transform: translateX(-1400px); } } /* 用户鼠标移入box,动画暂停 */ .box:hover ul { animation-play-state: paused; } </style> </head> <body> <div class="box"> <ul> <li><img src="./images/1.jpg" alt="" /></li> <li><img src="./images/2.jpg" alt="" /></li> <li><img src="./images/3.jpg" alt="" /></li> <li><img src="./images/4.jpg" alt="" /></li> <li><img src="./images/5.jpg" alt="" /></li> <li><img src="./images/6.jpg" alt="" /></li> <li><img src="./images/7.jpg" alt="" /></li> <!-- 第567移动的时候,显示区域不能留白 --> <li><img src="./images/1.jpg" alt="" /></li> <li><img src="./images/2.jpg" alt="" /></li> <li><img src="./images/3.jpg" alt="" /></li> </ul> </div> </body> </html>
全民出游季
知识点:
- 制作背景图
注意点:
- html和body的高度都要写上100%
- 图片的background-size需要做到cover
-
Code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="./css/index.css"> </head> <body> <!-- 云彩图片 --> <div class="cloud"> <img src="./images/yun1.png" alt=""> <img src="./images/yun2.png" alt=""> <img src="./images/yun3.png" alt=""> </div> </body> </html>
* { margin: 0; padding: 0; } /* 注意:html的默认高度和浏览器不是一样大的 */ html { height: 100%; } body { height: 100%; background: url(./../images/f1_1.jpg) no-repeat center; /* 缩放背景图 */ /* 图片等比例缩放, 当宽度或高度和盒子尺寸相等, 图片就不再缩放 */ /* background-size: contain; */ /* 图片等比例缩放, 图片完全覆盖到整个盒子, 可能会导致图片显示不全 */ background-size: cover; } /* 1. img 引入图片, 控制位置 2. 定义动画,使用动画 */ .cloud img { position: absolute; left: 50%; top: 0; } .cloud img:nth-child(1) { margin-left: -300px; top: 20px; animation: cloud 1s infinite alternate; } .cloud img:nth-child(2) { margin-left: 400px; top: 100px; /* 这里的0.2s指延迟时间 */ animation: cloud 1s infinite alternate 0.2s; } .cloud img:nth-child(3) { margin-left: -550px; top: 200px; animation: cloud 1s infinite alternate 0.4s; } /* 云彩动画 */ @keyframes cloud { to { transform: translateX(20px); } }