Day2-空间转换+动画
一、空间转换
1.1 目标:使用translate实现元素空间位移效果
空间:是从坐标轴角度定义的。 x 、y 和z三条坐标轴构成了一个立体空间,z轴位置与视线方向相同。
空间转换也叫3D转换
属性:transform
语法:
transform: translate3d(x, y, z);
transform: translateX(值);
transform: translateY(值);
transform: translateZ(值);
取值(正负均可):
1.像素单位数值
2.百分比
<!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>
2.1 目标:使用perspective属性实现透视效果
属性(添加给父级):
perspective: 值;
取值:像素单位数值, 数值一般在800 – 1200。
透视距离也称为视距,所谓的视距就是人的眼睛到屏幕的距离。
作用:空间转换时,为元素添加近大远小、近实远虚的视觉效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>透视效果</title>
<style>
body {
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>
</head>
<body>
<div class="box"></div>
</body>
</html>
3.1 目标:使用rotate实现元素空间旋转效果
语法:
transform: rotateZ(值);
transform: rotateX(值);
transform: rotateY(值);
左手法则:判断旋转方向: 左手握住旋转轴, 拇指指向正值方向, 手指弯曲方向为旋转正值方向
<!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>空间旋转-Z轴</title>
<style>
.box {
width: 300px;
margin: 100px auto;
}
img {
width: 300px;
transition: all 2s;
}
.box img:hover {
transform: rotateZ(360deg);
}
</style>
</head>
<body>
<div class="box">
<img src="./images/hero.jpeg" alt="">
</div>
</body>
</html>
<!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);
}
</style>
</head>
<body>
<div class="box">
<img src="./images/hero.jpeg" alt="">
</div>
</body>
</html>
<!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>空间旋转-Y轴</title>
<style>
.box {
width: 300px;
margin: 100px auto;
}
img {
width: 300px;
transition: all 2s;
}
.box {
/* 透视效果:近大远小,近实远虚 */
perspective: 1000px;
}
.box img:hover {
transform: rotateY(60deg);
}
</style>
</head>
<body>
<div class="box">
<img src="./images/hero.jpeg" alt="">
</div>
</body>
</html>
拓展(不常用):
1.rotate3d(x, y, z, 角度度数) :用来设置自定义旋转轴的位置及旋转的角度
2.x,y,z 取值为0-1之间的数字
4.1 目标: 使用transform-style: preserve-3d呈现立体图形
思考:使用perspective透视属性能否呈现立体图形?
答:不能,perspective只增加近大远小、近实远虚的视觉效果。
实现方法
1.添加transform-style: preserve-3d;
2.使子元素处于真正的3d空间
呈现立体图形步骤
1.盒子父元素添加transform-style: preserve-3d;
2.按需求设置子盒子的位置(位移或旋转)
注意:空间内,转换元素都有自已独立的坐标轴,互不干扰
<!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;
left: 0;
top: 0;
width: 200px;
height: 200px;
}
.front {
background-color: orange;
transform: translateZ(200px);
}
.back {
background-color: green;
}
.cube:hover {
transform: rotateY(180deg);
}
</style>
</head>
<body>
<div class="cube">
<div class="front">前面</div>
<div class="back">后面</div>
</div>
</body>
</html>
5.1 目标:使用立体呈现技巧实现3D导航效果
<!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>
6.1 目标:使用scale实现空间缩放效果
语法:
transform: scaleX(倍数);
transform: scaleY(倍数);
transform: scaleZ(倍数);
transform: scale3d(x, y, z);
二、动画
1.1 目标:使用animation添加动画效果
实现步骤:
1.定义动画
2.使用动画
<!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 2s;
}
/* 一. 定义动画:从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>
<!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: change 1s linear; */
/* 分步动画 */
/* animation: change 1s steps(3); */
/* 3: 重复3次播放*/
/* animation: change 1s steps(3) 1s 3; */
/* 无限循环效果 */
/* animation: change 1s infinite alternate; */
/* 默认值,动画停留在最初的状态 */
/* animation: change 1s backwards; */
/* 动画停留在结束的状态 */
animation: change 1s forwards;
}
@keyframes change {
from {
width: 200px;
}
to {
width: 600px;
}
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
<!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>
2.1 目标:使用steps实现逐帧动画
精灵动画制作步骤:
1.准备显示区域
设置盒子尺寸是一张小图的尺寸,背景图为当前精灵图
2.定义动画
改变背景图的位置(移动的距离就是精灵图的宽度)
3.使用动画
添加速度曲线steps(N),N与精灵图上小图个数相同
添加无限重复效果
思考:如果想让小人跑远一些,该如何实现?
答:精灵动画的同时添加盒子位移动画。
人物跑动
<!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 0.8s steps(12) infinite,
run 2s forwards linear;
}
@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>
以下代码仍然可以实现人物跑动效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>精灵动画</title>
<style>
.box {
position: absolute;
left: 0;
width: 140px;
height: 140px;
background-image: url(./images/bg.png);
animation: run 1s steps(12) infinite,
translate 3s linear forwards;
}
@keyframes run {
100% {
background-position: -1680px 0;
}
}
@keyframes translate {
100% {
left: 600px;
}
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
时钟
<!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>
.clock {
position: relative;
width: 200px;
height: 200px;
margin: 100px auto;
border: 8px solid #000;
border-radius: 50%;
}
/* 刻度线 */
.line {
position: absolute;
left: 50%;
transform: translate(-50%);
width: 3px;
height: 200px;
background-color: #ccc;
}
/* :nth-child() */
.line:nth-child(2) {
transform: translate(-50%) rotate(30deg);
}
.line:nth-child(3) {
transform: translate(-50%) rotate(60deg);
}
.line:nth-child(4) {
transform: translate(-50%) rotate(90deg);
}
.line:nth-child(5) {
transform: translate(-50%) rotate(120deg);
}
.line:nth-child(6) {
transform: translate(-50%) rotate(150deg);
}
/* 遮罩层 */
.mask {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 140px;
height: 140px;
background-color: #fff;
border-radius: 50%;
}
/* 表针 */
.hour,
.minute,
.second {
position: absolute;
left: 50%;
bottom: 50%;
/* transform: translate(-50%); */
/* 绕底部的中间旋转 */
transform-origin: center bottom;
}
.hour {
width: 6px;
height: 40px;
background-color: #000;
transform: translate(-50%) rotate(45deg);
}
.minute {
width: 4px;
height: 50px;
background-color: #000;
transform: translate(-50%) rotate(90deg);
}
.second {
width: 2px;
height: 60px;
background-color: red;
transform: translate(-50%) rotate(225deg);
animation: rotate 60s steps(60) infinite;
}
/* 螺丝 */
.dotted {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 12px;
height: 12px;
background-color: #000;
border-radius: 50%;
}
@keyframes rotate {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<div class="clock">
<!-- 刻度线 -->
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
<!-- 遮罩层 -->
<div class="mask"></div>
<!-- 表针 -->
<div class="hour"></div>
<div class="minute"></div>
<div class="second"></div>
<!-- 螺丝 -->
<div class="dotted"></div>
</div>
</body>
</html>
三、综合案例
1.1 走马灯
<!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 - */
@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>
2.1 全民出游记
<!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>
<!-- 热气球图片 -->
<div class="ball">
<img src="./images/san.png" alt="">
</div>
<!-- 跳舞图片 -->
<div class="dance">
<img src="./images/1.png" alt="">
<img src="./images/2.png" alt="">
<img src="./images/3.png" alt="">
<img src="./images/4.png" alt="">
</div>
<!-- 鹿图片 -->
<div class="deer">
<img src="./images/lu.png" alt="">
</div>
<!-- 周边图片 -->
<div class="play">
<img src="./images/font1.png" alt="">
</div>
</body>
</html>
* {
margin: 0;
padding: 0;
}
html {
height: 100%;
}
body {
height: 100%;
background: url(../images/f1_1.jpg) no-repeat center 0;
/* 缩放背景图 */
/* 图片等比例缩放,当宽度或高度与盒子尺寸相等,图片就不再缩放 */
/* 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;
margin-top: 20px;
animation: cloud 1s infinite alternate linear;
}
.cloud img:nth-child(2) {
margin-left: 400px;
margin-top: 100px;
animation: cloud 1s infinite alternate linear 0.2s;
}
.cloud img:nth-child(3) {
margin-left: -550px;
margin-top: 200px;
animation: cloud 1s infinite alternate linear 0.4s;
}
/* 云彩动画 */
@keyframes cloud {
to {
transform: translateX(20px);
}
}
/* 热气球 */
.ball img {
position: absolute;
left: 50%;
margin-left: -400px;
margin-top: 190px;
animation: ball 1.2s infinite alternate linear;
}
/* 热气球动画 */
@keyframes ball {
to {
transform: translateY(25px);
}
}
/* 跳舞 */
.dance img {
position: absolute;
left: 50%;
bottom: 38px;
}
.dance img:nth-child(1) {
margin-left: -360px;
margin-bottom: 25px;
animation: dance 0.8s infinite alternate;
}
.dance img:nth-child(2) {
margin-left: -160px;
margin-bottom: 25px;
animation: dance 0.8s infinite alternate 0.2s;
}
.dance img:nth-child(3) {
margin-left: 16px;
margin-bottom: 25px;
animation: dance 0.8s infinite alternate 0.4s;
}
.dance img:nth-child(4) {
margin-left: 200px;
margin-bottom: 25px;
animation: dance 0.8s infinite alternate 0.6s;
}
/* 跳舞动画 */
@keyframes dance {
to {
transform: translateY(25px);
}
}
/* 鹿 */
.deer img {
position: absolute;
left: 900px;
top: 80px;
}
/* 周边 */
.play img {
position: absolute;
left: 50%;
top: 35%;
width: 517px;
height: 229px;
transform: translate(-50%);
animation: play 0.5s alternate forwards linear,
play2 0.5s alternate forwards linear 0.5s;
}
/* 周边动画 */
@keyframes play {
to {
width: 388px;
height: 172px;
}
}
@keyframes play2 {
from {
width: 388px;
height: 172px;
}
to {
width: 517px;
height: 229px;
}
}