目标:使用 3d 空间转换、动画丰富网页元素的呈现方式。
一、空间转换
1、空间转换简介
- 空间:是从坐标轴角度定义的 X 、Y 和 Z 三条坐标轴构成了一个立体空间,Z 轴位置与视线方向相同
- 空间转换也叫 3D 转换
- 属性:transform
2、平移
/* 使用 translate3d,小括号里面必须逗号隔开三个数 */
/* 如果只写 1 个或 2 个,不起作用 */
transform: translate3d(x, y, z);
/* 沿 X 轴方向 */
transform: translateX();
/* 沿 Y 轴方向 */
transform: translateY();
/* 沿 Z 轴方向 */
transform: translateZ();
(1)取值与平面转换相同,像素值、百分比。
(2)使用 translate3d,三个参数都必须写,且用逗号隔开。
(3)默认情况下,Z 轴平移没有效果,原因:电脑屏幕默认是平面,无法显示 Z 轴平移效果,需要配合视距才能看到效果。
3、视距
作用:指定了观察者与 Z = 0 平面的距离,为元素添加透视效果,父级元素添加了视距,子级元素的 Z 轴平移(translateZ())就能看到效果。
透视效果:近大远小、近实远虚。
属性:添加给父级,取值范围 800-1200。
perspective: 视距;
<head>
<title>透视效果</title>
<style>
/* 视距属性必须添加给 直接父级 */
.father {
perspective: 1000px;
/* perspective: 10000px; */
/* perspective: 100px; */
}
.son {
width: 200px;
height: 200px;
margin: 100px auto;
background-color: pink;
transition: all 0.5s;
}
.son:hover {
/* transform: translateZ(-300px); */
transform: translateZ(300px);
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
4、旋转
- Z 轴:rotateZ()
沿 Z 轴旋转,Z 轴和平面旋转的中心点重叠,所以旋转效果和平面相同。
- X 轴:rotateX()
沿 X 轴旋转。
- Y 轴:rotateY()
沿 Y 轴旋转。
注意:平面旋转只有一个 rotate(),沿中心点旋转,默认情况,Z 轴经过平面的中心点,所以旋转效果相同。但是平面可以通过 transform-origin 修改中心点。
5、左手法则
作用:根据旋转方向确定取值正负。
使用:左手握住旋转轴, 拇指指向正值方向, 其他四个手指弯曲方向为旋转正值方向。
6、rotate3d(了解)
- rotate3d(x, y, z, 角度度数) :用来设置自定义旋转轴的位置及旋转的角度
- x,y,z 取值为0-1之间的数字
7、立体呈现
作用:设置元素的子元素是位于 3D 空间中还是平面中。
属性名:transform-style
属性值:
- flat:子级处于平面中,默认值
- preserve-3d:子级处于 3D 空间
通过一个案例什么是子级处于 3D 空间中,先看效果图:
<head>
<title>立体呈现</title>
<style>
.cube {
/* background-color: pink; */
position: relative;
width: 200px;
height: 200px;
margin: 100px auto;
transition: all 2s;
/* 设置子级位于 3D 空间中 */
transform-style: preserve-3d;
/* 添加视距, 还能看到近大远小的效果 */
/* perspective: 1000px; */
}
.cube div {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 200px;
}
.front {
background-color: orange;
/* 设置向 Z 轴正方向平移 100px, 不旋转, 看不到效果 */
transform: translateZ(100px);
}
.back {
background-color: green;
/* 设置向 Z 轴负方向平移 100px, 不旋转, 看不到效果 */
transform: translateZ(-100px);
}
/* 鼠标悬停, 沿 Y 轴旋转, 能清楚的看到 front 和 back 元素 */
.cube:hover {
transform: rotateY(90deg);
}
</style>
</head>
<body>
<div class="cube">
<div class="front">前面</div>
<div class="back">后面</div>
</div>
</body>
8、小案例-3d导航
案例步骤
- 搭建立方体
- 绿色是立方体的前面
- 橙色是立方体的上面
- 鼠标悬停,立方体旋转
具体代码如下:
<head>
<title>3D导航</title>
<style>
ul {
margin: 0;
padding: 0;
list-style: none;
}
.nav {
width: 300px;
height: 40px;
margin: 50px auto;
}
.nav ul {
display: flex;
}
/* li 是立方体, 所以 transform-style: perserve-3d 属性添加给 li */
.nav li {
position: relative;
width: 100px;
height: 40px;
line-height: 40px;
transition: all 0.5s;
transform-style: preserve-3d;
}
.nav li a {
position: absolute;
left: 0;
top: 0;
display: block;
width: 100%;
height: 100%;
color: #fff;
text-align: center;
/* 去掉下划线 */
text-decoration: none;
}
/* 立方体每个面都有独立的坐标轴,互不影响 */
.nav li a:first-child {
background-color: green;
/* 绿色的面要当立方体前面, 向 Z 轴正方向平移高度的一半,即20px */
transform: translateZ(20px);
}
.nav li a:last-child {
background-color: orange;
/* 先沿 X 轴旋转 90 度, 将橙色的面放平, 再往上平移 20px */
/* 注意: 因为旋转会改变坐标轴, 此时的竖直轴是 Z 轴, 所以设置 translateZ(20px), 而不是 translateY(20px) */
transform: rotateX(90deg) translateZ(20px);
}
.nav li:hover {
transform: rotateX(-90deg);
}
</style>
</head>
<body>
<div class="nav">
<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>
(1)立方体每个面都有独立的坐标轴,互不影响。
(2)旋转 rotate 会改变坐标轴,如果使用多重转换,先旋转,再平移的时候,要注意旋转后的坐标轴。比如:此案例中,橘色面先旋转 90deg,此时竖直方向变成了 Z 轴,不再是 Y 轴了,向上平移 20px 就是 translateZ(20px)。
9、缩放
transform: scale3d(x, y, z);
transform: scaleX();
transform: scaleY();
transform: scaleZ();
(1)如果使用 scale3d 进行缩放,三个参数都必须填写,如果只填写 1个 或 2个 都不起作用。
(2)参数值, 大于 1 表示放大,小于 1 表示缩小。
二、动画
- 过渡:实现两个状态间的变化过程
- 动画:实现多个状态间的变化过程,动画过程可控(重复播放、最终画面、是否暂停)
1、动画实现步骤
(1)定义动画
/* 方式一:动画只有 2 个节点, 可以使用 from 和 to 表示开始和结束 */
@keyframes 动画名称 {
from {}
to {}
}
/* 方式二:动画很多个节点时,使用此方法 */
@keyframes 动画名称 {
0% {}
10% {}
......
100% {}
}
(2)使用动画
对需要使用动画效果的元素添加:animation: 动画名称 动画花费时长 ...
属性。
animation: 动画名称 动画花费时长 ...;
2、animation复合属性
提示:
- 动画名称和动画时长必须赋值
- 取值不分先后顺序
- 如果有两个时间值,第一个时间表示动画时长,第二个时间表示延迟时间
animation 拆分写法
小案例-走马灯效果
<head>
<title>走马灯</title>
<style>
* {
padding: 0;
margin: 0;
}
li {
list-style: none;
}
img {
display: block;
width: 200px;
}
.box {
margin: 100px auto;
width: 600px;
height: 112px;
border: 5px solid #000;
overflow: hidden;
}
.box ul {
display: flex;
animation: move 6s infinite linear;
}
/* 定义位移动画,ul使用动画,鼠标悬停暂停动画 */
@keyframes move {
0% {
transform: translate(0);
}
100% {
transform: translate(-1400px);
}
}
/* 鼠标悬停到 box, 但是动画是在 ul 上, 所以是 .box:hover ul {} */
.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>
<!-- 替身:填补显示区域的露白, 最后一帧和第一帧一样, 当动画播放完, 第一帧瞬间替换最后一帧, 实现无限循环效果 -->
<!-- 具体宽度和张数, 根据实际情况 -->
<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>
无缝东海原理果:需要填补显示区域的露白,具体填补的宽度和张数,根据实际情况。
3、精灵动画
精灵动画也叫逐帧动画,动画的核心使用 animation-timing-function: step(数字)
属性。
使用精灵图和动画,实现如下效果:
制作步骤
- 准备显示区域
盒子尺寸与一张精灵小图尺寸相同。
- 定义动画
移动背景图,移动距离 = 精灵图宽度。
- 使用动画
steps(N),N 与精灵小图个数相同 (steps(数字) 是速度曲线的逐帧动画)。
<head>
<title>精灵动画</title>
<style>
div {
margin: 200px;
width: 140px;
height: 140px;
border: 1px solid #000;
background-image: url(./images/bg.png);
/* 精灵图是 12 张小图, 这里分 12 帧, 每一帧通过移动背景图位置, 展示一张精灵图, 实现跑步的效果 */
animation: run 1s steps(12) infinite;
}
@keyframes run {
from {
background-position: 0 0;
}
/* 动画结束, 移动背景图位置 */
to {
background-position: -1680px 0;
}
}
</style>
</head>
<body>
<div></div>
</body>
4、多组动画
animation:
动画一,
动画二,
... ...
;
每一组动画都是一套完整的动画,动画名称、动画时长、重复次数、动画执行方向等。
<head>
<title>多组动画</title>
<style>
body {
background-color: #eee;
}
div {
margin: 200px;
width: 140px;
height: 140px;
/* border: 1px solid #000; */
background-image: url(./images/bg.png);
animation:
run 1s steps(12) infinite,
move 3s forwards linear infinite;
}
/* 当动画的开始状态样式 跟 盒子默认样式相同,可以省略动画开始状态的代码 */
@keyframes run {
/* from {
background-position: 0 0;
} */
to {
background-position: -1680px 0;
}
}
@keyframes move {
/* 0% {
transform: translate(0);
} */
100% {
transform: translate(500px);
}
}
</style>
</head>
<body>
<div></div>
</body>
当动画的开始状态样式 跟 盒子默认样式相同,可以省略动画开始状态的代码
三、综合案例-全民出游
通过今日所学,完成如下页面动画效果:
想要完整代码的,点击这里获取Day11综合案例完整代码。完全免费,仅供学习参考使用。