空间转换
目标:使用transform属性实现元素在空间内的位移、旋转、缩放等效果
- 空间:是从坐标轴角度定义的。x 、y 和z三条坐标轴构成了一个立体空间,z轴位置与视线方向相同。
- 空间转换也叫 3 D转换
- 属性:transform
-
语法
- transform: translate3d(x, y, z);
- transform: translateX(值);
- transform: translateY(值);
- transform: translateZ(值);
-
取值(正负均可)
- 像素单位数值
- 百分比
目标:使用perspective属性实现透视效果
-
思考:生活中,同一个物体,观察距离不同,视觉上有什么区别?
- 答:近大远小、近清楚远模糊
-
思考:默认情况下,为什么无法观察到Z轴位移效果?
- 答:Z轴是视线方向,移动效果应该是距离的远或近,电脑屏幕是平面,默认无法观察远近效果
-
属性(添加给父级)
- perspective:值;
- 取值:像素单位数值,数值一般在 800 – 1200 。
-
作用
- 空间转换时,为元素添加近大远小、近实远虚的视觉效果
- 属性(添加给父级)
- perspective:值;
- 透视距离也称为视距,所谓的视距就是人的眼睛到屏幕的距离。
目标:使用rotate实现元素空间旋转效果
- 语法
- transform:rotateZ(值);
- transform:rotateX(值);
- transform:rotateY(值);
- 左手法则
- 判断旋转方向: 左手握住旋转轴, 拇指指向正值方向, 手指弯曲方向为旋转正值方向
- 拓展
- rotate3d(x, y, z, 角度度数) :用来设置自定义旋转轴的位置及旋转的角度
- x,y,z取值为 0 - 1 之间的数字
立体呈现
目标: 使用transform-style: preserve-3d呈现立体图形
-
思考:使用perspective透视属性能否呈现立体图形?
- 答:不能,perspective只增加近大远小、近实远虚的视觉效果。
-
实现方法
- 添加transform-style: preserve-3d;
- 使子元素处于真正的 3 d空间
-
呈现立体图形步骤
- 盒子父元素添加transform-style: preserve-3d;
- 按需求设置子盒子的位置(位移或旋转)
-
注意
- 空间内,转换元素都有自已独立的坐标轴,互不干扰
- 空间内,转换元素都有自已独立的坐标轴,互不干扰
<!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>
<style>
.box {
position: relative;
width: 200px;
height: 200px;
margin: 100px auto;
transition: all 2s;
transform-style: preserve-3d;
}
.box div {
width: 200px;
height: 200px;
}
.box .front{
background-color: orange;
/* 拉开空间距离 */
transform: translateZ(200px);
}
.box .back{
position: absolute;
top: 0;
left: 0;
background-color: greenyellow;
}
.box:hover{
transform: rotateY(180deg);
}
</style>
</head>
<body>
<div class="box">
<div class="front"></div>
<div class="back"></div>
</div>
</body>
</html>
3D导航
目标:使用立体呈现技巧实现 3 D导航效果
- 观察:绿色和橙色盒子是如何摆放的?
思考:绿色和橙色盒子是如何摆放的?
- 搭建立方体
- 绿色盒子是立方体的前面
- 橙色盒子是立方体的上面
结论:绿色和橙色部分共需要 3 个标签
- 1 个父级标签
- 绿色和橙色共 2 个标签(子级)
目标:使用立体呈现技巧实现 3 D导航效果
实现思路
- 搭建立方体:绿色盒子是立方体的前面,橙色盒子是立方体的上面
- 添加hover状态旋转切换效果
实现思路
- 搭建立方体
- li标签
- 添加立体呈现属性transform-style: preserve-3d;
- 添加旋转属性(为了便于观察效果,案例完成后删除即可)
- a标签
- 调节位置
- li标签
实现思路
1.搭建立方体
- 调节a标签的位置
- a标签定位(子绝父相)
- 英文部分添加旋转和位移样式
- 中文部分添加位移样式
实现思路
2.过渡效果
- 鼠标滑过li,添加空间旋转样式
- li添加过渡属性
注意:案例完成后,删除li的旋转样式。
空间缩放
目标:使用scale实现空间缩放效果
- 语法
- transform: scaleX(倍数);
- transform: scaleY(倍数);
- transform: scaleZ(倍数);
- transform: scale3d(x, y, z);
<!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>
动画
目标:使用animation添加动画效果
- 思考:过渡可以实现什么效果?
- 答:实现 2 个状态间的变化过程
- 动画效果:实现多个状态间的变化过程,动画过程可控(重复播放、最终画面、是否暂停)
- 动画的本质是快速切换大量图片时在人脑中形成的具有连续性的画面
- 构成动画的最小单元:帧或动画帧
动画的实现步骤
目标:使用animation添加动画效果
实现步骤:
-
定义动画
keyframes -->关键帧
-
使用动画
动画属性
目标:使用animation相关属性控制动画执行过程
<!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>
<style>
div{
width: 50px;
height: 50px;
background-color: pink;
/* 使用动画 */
animation: move 5s;
}
/* 动画序列 */
/* 1. 可以做多个状态的变化 keyframe 关键帧 */
/* 2. 里面的百分比要是整数 */
/* 3. 里面的百分比就是 总的时间(我们这个案例5s)的划分 25*5 --1.25s*/
/* 定义动画 */
@keyframes move{
0% {
transform: translate(0, 0);
}
25% {
transform: translate(600px, 0);
}
50% {
transform: translate(600px, 500px);
}
75% {
transform: translate(0, 500px);
}
100% {
transform: translate(0, 0);
}
}
</style>
</head>
<body>
<div></div>
</body>
</html>
注意:
- 动画名称和动画时长必须赋值
- 取值不分先后顺序
- 如果有 2 个时间值,第一个时间表示动画时长,第二个时间表示延迟时间
动画简写属性
animation: name duration timing-function delay iteration-count direction fill-mode;
animation:动画名称 持续时间 运动曲线 何时开始 播放次数 是否反方向 动画起始或者结束的状态
波纹放大案例
<!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>
<style>
.box {
position: relative;
width: 500px;
height: 500px;
background-color: pink;
margin: 100px auto;
}
.circle {
position: absolute;
top: 100px;
left: 100px;
}
.circle .dotted{
width: 8px;
height: 8px;
background-color: #fff;
border-radius: 50%;
}
/* pulse 开头 */
.circle div[class^="pulse"] {
/* 保证小波纹在父盒子里面水平垂直居中,放大之后就会从中心向四周发散 */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 8px;
height: 8px;
box-shadow: 0 0 12px #fff;
border-radius: 50%;
animation: pulse 1.2s linear infinite;
}
.circle div.pulse2{
animation-delay: 0.4s;
}
.circle div.pulse3{
animation-delay: 0.8s;
}
@keyframes pulse{
0% {
}
70% {
width: 40px;
height: 40px;
}
100% {
width: 70px;
height: 70px;
opacity: 0;
}
}
.cc{
top: 250px;
left: 250px;
}
.rb{
top: 400px;
left: 400px;
}
</style>
</head>
<body>
<div class="box">
<div class="circle">
<div class="dotted"></div>
<div class="pulse1"></div>
<div class="pulse2"></div>
<div class="pulse3"></div>
</div>
<div class="circle cc">
<div class="dotted"></div>
<div class="pulse1"></div>
<div class="pulse2"></div>
<div class="pulse3"></div>
</div>
<div class="circle rb">
<div class="dotted"></div>
<div class="pulse1"></div>
<div class="pulse2"></div>
<div class="pulse3"></div>
</div>
</div>
</body>
</html>
目标:使用steps实现逐帧动画
打字机效果
<!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>
<style>
div{
overflow: hidden;
width: 0;
font-size: 20px;
height: 30px;
background-color: pink;
color: #fff;
/* 让文字强制一行显示 */
white-space: nowrap;
/* step 就是分几步来完成我们的动画 */
/* forwards 停留在最后一帧的状态 */
animation: w 2s steps(6) forwards;
}
@keyframes w {
0% {
width: 0;
}
100% {
width: 120px;
}
}
</style>
</head>
<body>
<div>你好,世界!</div>
</body>
</html>
-
逐帧动画:帧动画。开发中,一般配合精灵图实现动画效果。
-
animation-timing-function:steps(N);
- 将动画过程等分成N份
-
精灵动画制作步骤
- 准备显示区域
- 设置盒子尺寸是一张小图的尺寸,背景图为当前精灵图
- 定义动画
- 改变背景图的位置(移动的距离就是精灵图的宽度)
- 使用动画
- 添加速度曲线steps(N),N与精灵图上小图个数相同
- 添加无限重复效果
- 准备显示区域
目标:能够使用animation属性给一个元素添加多个动画效果
- 多组动画
- 思考:如果想让小人跑远一些,该如何实现?
- 答:精灵动画的同时添加盒子位移动画。
<!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>
<style>
body{
background-color: aliceblue;
}
div{
position: absolute;
/*1680 / 12:保证显示区域的尺寸和应该精灵小图尺寸相同*/
width: 140px;
height: 140px;
background: url(../images/bg.png) no-repeat;
/* 12: 精灵小图的个数 */
animation:
people 1s steps(12) infinite,
move 5s forwards;
}
@keyframes people{
from {
background-position: 0 0;
}
to {
/* 1680:精灵图的宽度 */
background-position: -1680px 0;
}
}
@keyframes move{
0% {
left: 0;
}
100% {
left: 50%;
transform: translate(-50%);
}
}
</style>
</head>
<body>
<div>
</div>
</body>
</html>
综合案例
走马灯
目标:使用animation实现逐帧图片位移效果
<!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>
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
.box {
overflow: hidden;
width: 600px;
height: 112px;
margin: 100px auto;
border: 5px solid pink;
}
.box ul {
/* 十张照片的宽度 */
width: 2000px;
animation: move 15s infinite linear;
}
.box li {
float: left;
}
.box img{
width: 200px;
}
@keyframes move {
to {
transform: translateX(-1400px);
}
}
/* 用户鼠标移入 box ,动画暂停 */
.box:hover ul {
animation-play-state: paused;
}
</style>
</head>
<body>
<div class="box">
<ul>
<li><img src="./1.jpg" alt=""></li>
<li><img src="./2.jpg" alt=""></li>
<li><img src="./3.jpg" alt=""></li>
<li><img src="./4.jpg" alt=""></li>
<li><img src="./5.jpg" alt=""></li>
<li><img src="./6.jpg" alt=""></li>
<li><img src="./7.jpg" alt=""></li>
<!-- 因为盒子只能放下三张图片 -->
<li><img src="./1.jpg" alt=""></li>
<li><img src="./2.jpg" alt=""></li>
<li><img src="./3.jpg" alt=""></li>
</ul>
</div>
</body>
</html>