外观
11_空间转换 + 动画
01_空间转换
01_平移 + 视距
01_空间转换
空间: 是从坐标轴角度定义的 X, Y 和 Z
三条坐标轴构成了一个立体空间, Z 轴位置与视线方向相同
空间转换也叫 3D 转换
属性: transform
02_平移
属性
取值 (正负
均可)
- 像素单位数值
- 百分比 (参照
盒子自身尺寸
计算结果)
html
<!-- /code/test.html -->
<!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>
.box {
width: 200px;
height: 200px;
margin: 100px auto;
background-color: pink;
transition: all 0.5s;
}
.box:hover {
/* 1.电脑是平面, 默认无法观察 Z 轴平移效果 */
transform: translate3d(100px, 200px, 300px);
/* 2.3d 小括号里面必须逗号隔开三个数(否则不生效) */
/* transform: translate3d(100px, 200px); */
/* 3.水平移动 */
/* transform: translateX(100px); */
/* 4.垂直移动 */
/* transform: translateY(-100%); */
/* 5.视线移动 */
/* transform: translateZ(300px); */
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
03_视距 perspective
作用: 指定了 观察者
与 Z = 0
平面的 距离
, 为元素添加 透视效果
透视效果: 近大远小, 近实远虚
属性: (添加给 父级
, 取值范围 800~1200
)
html
<!-- /code/test.html -->
<!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>
/* 1.视距属性必须添加给 直接父级 */
.father {
/* 2.取值范围 800~1200 */
perspective: 1000px;
}
.son {
width: 200px;
height: 200px;
margin: 100px auto;
background-color: pink;
transition: all 0.5s;
}
.son:hover {
/* 3.负值: 远小 */
/* transform: translateZ(-300px); */
/* 4.正值: 近大 */
transform: translateZ(300px);
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
</html>
02_旋转
01_Z 轴旋转
transform: rotateZ(值);
html
<!-- /code/test.html -->
<!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>
.box {
width: 300px;
margin: 100px auto;
}
img {
width: 300px;
transition: all 2s;
}
.box img:hover {
/* 1.正数: 顺时针旋转 */
/* transform: rotateZ(360deg); */
/* 2.负数: 逆时针旋转 */
transform: rotateZ(-360deg);
}
</style>
</head>
<body>
<div class="box">
<img src="./images/hero.jpeg" alt="" />
</div>
</body>
</html>
02_X 轴旋转
transform: rotateX(值);
html
<!-- /code/test.html -->
<!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>
.box {
width: 300px;
margin: 100px auto;
}
img {
width: 300px;
transition: all 2s;
}
.box {
/* 透视效果: 近大远小, 近实远虚 */
perspective: 1000px;
}
.box img:hover {
/* 1.正数: 从下往上旋转 */
/* transform: rotateX(60deg); */
/* 2.负数: 从上往下旋转 */
transform: rotateX(-60deg);
}
</style>
</head>
<body>
<div class="box">
<img src="./images/hero.jpeg" alt="" />
</div>
</body>
</html>
03_Y 轴旋转
transform: rotateY(值);
html
<!-- /code/test.html -->
<!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>
.box {
width: 300px;
margin: 100px auto;
}
img {
width: 300px;
transition: all 2s;
}
.box {
/* 透视效果: 近大远小, 近实远虚 */
perspective: 1000px;
}
.box img:hover {
/* 1.正数: 从左往右旋转 */
/* transform: rotateY(60deg); */
/* 2.负数: 从右往左旋转 */
transform: rotateY(-60deg);
}
</style>
</head>
<body>
<div class="box">
<img src="./images/hero.jpeg" alt="" />
</div>
</body>
</html>
04_左手法则
左手法则 - 根据 旋转方向
确定取值 正负
左手
握住旋转轴,拇指指向正值方向
, 其他四个手指弯曲
方向为旋转正值
方向
05_拓展
- rotate3d(x, y, z, 角度度数): 用来设置
自定义旋转轴的位置
及旋转的角度- x, y, z 取值为 0 ~ 1 之间的数字
03_立体呈现
01_立体呈现
作用: 设置元素的 子
元素是位于 3D 空间
中还是 平面
中
属性名: transform-style
属性值:
- flat:子级处于
平面
中preserve-3d
: 子级处于3D 空间
呈现立体图形步骤
父元素
添加transform-style: preserve-3d
;- 子级
定位
- 调整子盒子的
位置 (位移或旋转)
html
<!-- /code/test.html -->
<!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>
.cube {
position: relative;
width: 200px;
height: 200px;
margin: 100px auto;
/* background-color: pink; */
transition: all 2s;
/* 1.父元素 添加 transform-style: preserve-3d; */
transform-style: preserve-3d;
/* 旋转与案例效果无关, 用来看前后移动的效果 */
/* transform: rotateY(89deg); */
}
.cube div {
/* 2.子级 定位 */
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 200px;
}
.front {
background-color: orange;
/* 3.调整子盒子的 位置(位移或旋转) */
transform: translateZ(100px);
}
.back {
background-color: green;
/* 4.调整子盒子的 位置(位移或旋转) */
transform: translateZ(-100px);
}
.cube:hover {
transform: rotateY(90deg);
}
</style>
</head>
<body>
<div class="cube">
<div class="front">前面</div>
<div class="back">后面</div>
</div>
</body>
</html>
04_3D 导航案例
01_3D 导航案例
搭建 立方体
- 绿色是立方体的前面
- 橙色是立方体的上面
添加鼠标 悬停
的 旋转
效果
html
<!-- /code/test.html -->
<!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>
ul {
margin: 0;
padding: 0;
list-style: none;
}
.nav {
width: 300px;
height: 40px;
margin: 50px auto;
}
.nav ul {
display: flex;
}
.nav li {
position: relative;
width: 100px;
height: 40px;
line-height: 40px;
transition: all 0.5s;
/* 1.搭建 立方体 */
transform-style: preserve-3d;
/* 为了看到橙色和绿色的移动过程, 给立方体添加旋转 */
/* transform: rotateX(-20deg) rotateY(30deg); */
}
.nav li a {
position: absolute;
left: 0;
top: 0;
display: block;
width: 100%;
height: 100%;
text-align: center;
text-decoration: none;
color: #fff;
}
/* 4.立方体每个面都有独立的坐标轴, 互不影响 */
.nav li a:first-child {
background-color: green;
/* 3.绿色是立方体的前面 */
transform: translateZ(20px);
}
.nav li a:last-child {
background-color: orange;
/* 2.橙色是立方体的上面 */
transform: rotateX(90deg) translateZ(20px);
}
.nav li:hover {
/* 5.添加鼠标 悬停 的 旋转 效果 */
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>
</html>
05_缩放
01_缩放
属性
html
<!-- /code/test.html -->
<!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>
ul {
margin: 0;
padding: 0;
list-style: none;
}
.nav {
width: 300px;
height: 40px;
margin: 50px auto;
}
.nav ul {
display: flex;
}
.nav li {
position: relative;
width: 100px;
height: 40px;
line-height: 40px;
transition: all 0.5s;
/* 搭建 立方体 */
transform-style: preserve-3d;
/* 1.长度缩放倍数 */
/* transform: scaleX(0.5); */
/* 2.宽度缩放倍数 */
/* transform: scaleY(2); */
/* 3.视距缩放倍数 */
/* transform: scaleZ(3); */
/* 4.长度缩放倍数, 宽度缩放倍数, 视距缩放倍数 */
transform: scale3d(0.5, 2, 3);
/* 为了看到橙色和绿色的移动过程, 给立方体添加旋转 */
/* transform: rotateX(-20deg) rotateY(30deg); */
}
.nav li a {
position: absolute;
left: 0;
top: 0;
display: block;
width: 100%;
height: 100%;
text-align: center;
text-decoration: none;
color: #fff;
}
/* 立方体每个面都有独立的坐标轴, 互不影响 */
.nav li a:first-child {
background-color: green;
/* 绿色是立方体的前面 */
transform: translateZ(20px);
}
.nav li a:last-child {
background-color: orange;
/* 橙色是立方体的上面 */
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>
</html>
02_动画
01_介绍
01_介绍
过渡: 实现 两个状态
间的变化过程
动画: 实现 多个状态
间的变化过程, 动画过程可控
(重复播放, 最终画面, 是否暂停)
02_定义使用
01_定义使用
使用动画
html
<!-- /code/test.html -->
<!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>
.box {
width: 200px;
height: 100px;
background-color: pink;
/* 2.使用动画 animation: 动画名称 动画花费时长 */
animation: change 1s;
}
/* 1.定义动画一: 宽度从 200 变化到 800 */
/* @keyframes change {
from {
width: 200px;
}
to {
width: 800px;
}
} */
/* 1.定义动画二: 从 200*100 变化到 300*300 变化到 800*500; 百分比: 表示的意思是动画时长的百分比 */
@keyframes change {
0% {
width: 200px;
height: 100px;
}
20% {
width: 300px;
height: 300px;
}
100% {
width: 800px;
height: 500px;
}
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
03_动画属性
01_动画复合属性
提示:
动画名称
和动画时长
必须赋值- 取值
不
分先后顺序- 如果有
两个时间
值,第一个
时间表示动画时长
,第二个
时间表示延迟时间
html
<!-- /code/test.html -->
<!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>
.box {
width: 200px;
height: 100px;
background-color: pink;
/* 1.速度曲线: linear 匀速 */
/* animation: change 1s linear; */
/* 2.速度曲线: steps 分步动画, 工作中, 配合精灵图实现精灵动画 */
/* animation: change 1s steps(3); */
/* 3.延迟时间: 如果有两个时间, 第一个是动画时长, 第二个是延迟时间 */
/* animation: change 1s 2s; */
/* 4.重复次数: infinite 无限循环 */
/* animation: change 1s 3; */
/* animation: change 1s infinite; */
/* 5.动画方向: alternate 反向 */
/* animation: change 1s infinite alternate; */
/* 6.执行完毕时状态: forwards 结束状态; backwards 开始状态 (默认) */
/* animation: change 1s forwards; */
animation: change 1s backwards;
}
/* 宽度 从 200 变化到 800 */
@keyframes change {
from {
width: 200px;
}
to {
width: 800px;
}
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
02_动画拆分属性
html
<!-- /code/test.html -->
<!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>
.box {
width: 200px;
height: 100px;
background-color: pink;
/* 1.动画名称 */
animation-name: change;
/* 2.动画时长 */
animation-duration: 1s;
/* 3.重复次数: infinite 为无限循环 */
animation-iteration-count: infinite;
}
.box:hover {
/* 4.暂停动画: paused 为暂停, 通常配合 :hover 使用 */
animation-play-state: paused;
}
/* 宽度从 200 变化到 800 */
@keyframes change {
0% {
width: 200px;
}
100% {
width: 800px;
}
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
04_走马灯案例
01_走马灯效果
无缝动画原理: 复制 开头图片
到 结尾
位置 (图片累加宽度 = 区域宽度
)
html
<!-- /code/test.html -->
<!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 {
display: block;
width: 200px;
}
.box {
width: 600px;
height: 112px;
border: 5px solid #000;
margin: 100px auto;
overflow: hidden;
}
.box ul {
display: flex;
/* 2.使用动画: infinite 无限循环, linear 匀速 */
animation: move 6s infinite linear;
}
/* 1.定义位移动画 */
@keyframes move {
0% {
transform: translate(0);
}
100% {
transform: translate(-1400px);
}
}
/* 4.鼠标悬停暂停动画 */
.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>
<!-- 3.无缝动画原理: 复制 开头图片 到 结尾 位置 (图片累加宽度 = 区域宽度) -->
<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>
05_逐帧动画 + 多组动画
01_逐帧动画
02_逐帧动画案例
核心原理:
- steps() 逐帧动画
- CSS 精灵图
精灵动画制作步骤
- 准备显示区域
- 盒子尺寸与
一张精灵小图尺寸
相同- 定义动画
移动背景图 (移动距离 = 精灵图宽度)
- 使用动画
steps(N), N 与精灵小图个数相同
html
<!-- /code/test.html -->
<!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>
div {
/* 1.盒子尺寸与 一张精灵小图尺寸 相同 */
width: 140px;
height: 140px;
border: 1px solid #000;
background-image: url(./images/bg.png);
/* 3.teps(N), N 与精灵小图个数相同 */
animation: run 1s steps(12) infinite;
}
/* 2.移动背景图 ( 移动距离 = 精灵图宽度 ) */
@keyframes run {
from {
background-position: 0 0;
}
to {
background-position: -1680px 0;
}
}
</style>
</head>
<body>
<div></div>
</body>
</html>
03_多组动画
html
<!-- /code/test.html -->
<!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>
div {
width: 140px;
height: 140px;
/* border: 1px solid #000; */
background-image: url(./images/bg.png);
animation:
/* 3.使用动画一 */
run 1s steps(12) infinite,
/* 4.使用动画二 */
move 3s forwards;
}
/* 5.当动画的开始状态样式 跟 盒子默认样式相同, 可以省略动画开始状态的代码 */
/* 1.动画一 */
@keyframes run {
/* from {
background-position: 0 0;
} */
to {
background-position: -1680px 0;
}
}
/* 2.动画二 */
@keyframes move {
/* 0% {
transform: translate(0);
} */
100% {
transform: translate(800px);
}
}
</style>
</head>
<body>
<div></div>
</body>
</html>
03_综合案例
01_全民出游
01_背景图
html
<!-- /code/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>全民出游季</title>
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
</body>
</html>
css
/* /code/css/index.css */
/* 1.背景图 */
html {
/* 默认状态 HTML 和 body 的高度是 0, 所以导致 cover 缩放背景图不成功 */
height: 100%;
}
body {
height: 100%;
background: url(../images/f1_1.jpg) no-repeat center 0 / cover;
/* background-size: cover; */
}
02_云彩
html
<!-- /code/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>全民出游季</title>
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<!-- 1.云彩 -->
<div class="cloud">
<img src="./images/yun1.png" alt="">
<img src="./images/yun2.png" alt="">
<img src="./images/yun3.png" alt="">
</div>
</body>
</html>
css
/* /code/css/index.css */
/* 2.云彩 */
.cloud img {
position: absolute;
left: 50%;
}
.cloud img:nth-child(1) {
margin-left: -250px;
top: 20px;
animation: cloud 1s infinite alternate linear;
}
.cloud img:nth-child(2) {
margin-left: 400px;
top: 100px;
animation: cloud 1s infinite alternate linear 0.4s;
}
.cloud img:nth-child(3) {
margin-left: -550px;
top: 200px;
animation: cloud 1s infinite alternate linear 0.6s;
}
@keyframes cloud {
100% {
transform: translate(20px);
}
}
03_文字
html
<!-- /code/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>全民出游季</title>
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<!-- 云彩 -->
<!-- ...... -->
<!-- 1.文字 -->
<div class="text">
<img src="./images/font1.png" alt="">
</div>
</body>
</html>
css
/* /code/css/index.css */
/* 2.文字 */
.text img {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
animation: text 1s;
}
/* 默认 ==> 小 ==> 大 ==> 小 ==> 默认 */
@keyframes text {
0% {
transform: translate(-50%, -50%) scale(1);
}
20% {
transform: translate(-50%, -50%) scale(0.1);
}
40% {
transform: translate(-50%, -50%) scale(1.4);
}
70% {
transform: translate(-50%, -50%) scale(0.8);
}
100% {
transform: translate(-50%, -50%) scale(1);
}
}