12.2D、3D 转换动画
大约 10 分钟学习笔记前端基础CSS
一、 2D 转换(transform)
转换(
transform
):可以实现元素的位移、旋转、缩放等效果2D 转换: 改变标签在二维平面上的位置和形状
注意
如果 既有位移,又有旋转、缩放时,需要先写位移 再写其他,否则方向会跑偏
/* 位移 旋转 缩放 */
transform: translate(50% 50%) rotate(180deg) scale(1.2em);
详情
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>demo</title>
<style>
* {
padding: 0;
margin: 0;
}
.demo {
margin: 0 auto;
margin-top: 20px;
width: 300px;
}
.box {
margin: 0 auto;
width: 300px;
height: 200px;
font-size: 20px;
background-color: bisque;
}
.box img {
width: 300px;
transition: 1s;
}
.box:hover img {
/* 先写位移,再做旋转 放大 */
transform: translateY(100px) rotate(360deg) scale(2);
}
</style>
</head>
<body>
<div class="demo">
<p>2D 转换</p>
<div class="box">
<img src="https://img.pupper.cn/img/202111291344063.jpg" alt="">
</div>
</div>
</body>
</html>
1. 2D 转换 --- 移动(translate)
语法:
transform: translate(x, y);
transform: translateX(n);
transform: translateY(n);
注
translate 不会影响其他元素的位置;
translate 中,如果使用百分比,则是移动 自身元素大小 的百分比;
/* 垂直水平居中 */ div { position: absolute; top: 50%; left: 50%; width: 200px; hight: 200px; margin-top: -100px; margin-left: -100px; /* 等价于 */ transfrom: translate(-50%, -50%); }
translate 对 行内元素 没有效果
详情
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>CSS3 过渡效果</title>
<style>
* {
padding: 0;
margin: 0;
}
.demo {
margin: 100px auto;
width: 300px;
}
.demo div {
float: left;
width: 100px;
height: 100px;
}
.demo div:first-child {
background-color: aquamarine;
transition: 0.5s;
}
.demo div:last-child {
background-color: bisque;
margin-left: 100px;
transition: 0.5s;
}
.demo div:first-child:hover {
transform: translateY(-50px);
}
.demo div:last-child:hover {
transform: translateX(-100px);
}
</style>
</head>
<body>
<div class="demo">
<div>鼠标滑过,元素移动</div>
<div>鼠标滑过,元素移动</div>
</div>
</body>
</html>
2. 2D 转换 --- 旋转(rotate)
语法:
transform: rotate(度数);
注
- rotate 里面 度数的单位为
deg
,如:rotate(45deg) - 度数为正时,顺时针旋转,度数为负时,逆时针旋转
- 默认旋转中心点为元素的中心点
详情
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>demo</title>
<style>
* {
padding: 0;
margin: 0;
}
.demo {
margin: 0 auto;
margin-top: 20px;
width: 500px;
height: 500px;
font-size: 30px;
}
.demo img {
/* 过度需要写在元素本身,不能写在 hover 中 */
transition: 1s;
}
.demo img:hover {
transform: rotate(360deg);
}
</style>
</head>
<body>
<div class="demo">
鼠标滑过,图片旋转
<img src="https://img.pupper.cn/img/202111291344063.jpg" alt="">
</div>
</body>
</html>
3. 设置旋转中心点(transform-origin)
语法:
transform-origin: x y;
注
- x 和 y 需要用 空格 隔开
- x 和 y 默认旋转中心点 是 元素中心点 (50% 50%)
- 可以给 x 和 y 设置 像素 或 方位名词 (top bottom left right center)
- 旋转中心需要设置在元素本身的样式中,不能设置在 hover 中
详情
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>demo</title>
<style>
* {
padding: 0;
margin: 0;
}
.demo {
margin: 0 auto;
margin-top: 20px;
width: 300px;
}
.box {
margin: 0 auto;
width: 300px;
height: 200px;
font-size: 20px;
background-color: bisque;
overflow: hidden;
}
.box img {
width: 300px;
/* 过度需要写在元素本身,不能写在 hover 中 */
transition: 0.5s;
transform-origin: left bottom;
transform: rotate(180deg);
}
.box:hover img {
transform: rotate(0deg);
}
</style>
</head>
<body>
<div class="demo">
<p>鼠标滑过,图片出现</p>
<div class="box">
<img src="https://img.pupper.cn/img/202111291344063.jpg" alt="">
</div>
</div>
</body>
</html>
4. 2D 转换 --- 缩放(scale)
语法:
transform: scale(x, y);
注
- x 和 y 用
逗号
隔开 transform: scale(1, 1)
: 相当于没有放大transform: scale(3)
: 如果一个值时,默认两个值一样,等价于 scale(3, 3)- 可以设置缩放中心点,不影响其他盒子
详情
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>demo</title>
<style>
* {
padding: 0;
margin: 0;
}
.demo {
margin: 0 auto;
margin-top: 20px;
width: 300px;
}
.box {
margin: 0 auto;
width: 300px;
height: 200px;
font-size: 20px;
background-color: bisque;
overflow: hidden;
}
.box img {
width: 300px;
transition: 0.5s;
}
.box:hover img {
transform: scale(1.3);
}
</style>
</head>
<body>
<div class="demo">
<p>鼠标滑过,图片放大</p>
<div class="box">
<img src="https://img.pupper.cn/img/202111291344063.jpg" alt="">
</div>
</div>
</body>
</html>
二、 动画
动画需要 先定义 再 调用
属性 | 描述 |
---|---|
@keyframes | 规定动画 |
animation | 所有动画属性的简写,除了 animation-play-state 属性 |
animation-name | 动画名称(必须) |
animation-duration | 动画时间,默认为 0 (必须) |
animation-timing-function | 动画的速度曲线,默认是 ease ,linear (匀速)、steps (步长) |
animation-delay | 动画何时开始,默认为 0 |
animation-iteration-count | 动画播放次数,默认为 1,还有 infinite(无限) |
animation-direction | 是否逆向播放,默认为 normal , alternate(逆播放) |
animation-play-state | 是否正在运行或暂停,默认 running , 还有 paused |
animation-fill-mode | 动画结束状态,保持(forwards),回到起始(backwards) |
1. 定义动画(keyframes)
语法:
@keyframes 动画名称 {
0% {
动画样式
}
100% {
动画样式
}
}
注
动画序列:
- 0% 是动画开始,100% 是动画完成
- 动画定义在
@keyframes
中 - 使用百分比来控制动画发生的时间,或用关键字
from
和to
,等同于0%
和100%
2. 调用动画(animation-name)
语法:
选择器 {
/* 调用动画 */
animation-name: 动画名称
/* 持续时间 */
animation-duration: 持续时间
}
3. 简写
注
简写规则:
animation: 动画名称 持续时间 运动曲线 何时开始 播放次数 是否方向 起始或结束状态
animation: myfirst 5s linnear 2s infinite alternate;
.box img {
/* 普通写法 */
/* animation-name: demo;
animation-duration: 10s;
animation-iteration-count: infinite; */
/* 简写 */
animation: demo 10s infinite;
}
详情
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>demo</title>
<style>
* {
padding: 0;
margin: 0;
}
.box {
width: 500px;
height: 500px;
}
.box img {
width: 300px;
}
@keyframes demo {
0% {
transform: translate(0,0);
}
20% {
transform: translateX(500px) rotate(720deg);
}
50% {
transform: translate(500px, 500px);
}
70% {
transform: translate(0, 500px) rotate(-720deg);
}
100% {
transform: translate(0,0);
}
}
.box img {
/* 普通写法 */
/* animation-name: demo;
animation-duration: 10s;
animation-iteration-count: infinite; */
/* 简写 */
animation: demo 10s infinite;
}
</style>
</head>
<body>
<div class="demo">
<div class="box">
<img src="https://img.pupper.cn/img/202111291344063.jpg" alt="">
</div>
</div>
</body>
</html>
详情
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>demo</title>
<style>
* {
padding: 0;
margin: 0;
}
@keyframes xiong {
0% {
background-position: 0 0;
}
100% {
background-position: -1600px 0;
}
}
@keyframes zhong {
0% {
left: 0;
}
100% {
left: 50%;
transform: translateX(-50%);
}
}
.demo {
background-color: #ccc;
width: 100%;
height: 1000px;
}
.box {
position: absolute;
width: 200px;
height: 100px;
background: url(https://img.pupper.cn/img/202112021756966.png) no-repeat;
animation: xiong 0.7s steps(8) infinite, zhong 3s forwards;
}
</style>
</head>
<body>
<div class="demo">
<div class="box">
</div>
</div>
</body>
</html>
三、3D 转换
三维坐标系:
- x 轴 : 水平向右(向右为正值,向左为负值)
- y 轴 : 垂直向下(向下为正值,向上为负值)
- z 轴 : 垂直向屏幕(向外为正值,向内为负值)
透视 (perspective)
透视(
perspective
):也叫 视距,可以将 3D 效果在 网页中显示出来,视距越小,图像越大,视距越大,图像越小
注意
透视(perspective) 需要写在被观察元素的 父盒子 上;
视距:眼睛到屏幕的距离,视距越小,图像越大;
z 轴: 物体距离屏幕的距离,z 轴越大,图像越大;
1. 3D 移动(translate3d)
语法:
transform: translateX(x)
transform: translateY(x)
transform: translateZ(x)
transform: translate3d(x, y, z)
注意事项:
- x 轴 的单位一般都是 px
- x,y,z 不能省略,如果没有就写 0 ;
- 3d 效果需要搭配 透视(perspective) 才能显示效果;
2. 3D 旋转(rotate3d)
3D 旋转遵守 “左手法则”,大拇指指向旋转轴的方向,四指指向旋转(正值)的方向
语法:
transform: rotateX(100deg);
transform: rotateY(100deg);
transform: rotateZ(100deg);
transform: rotate3d(x, y, z, deg)
如:transform: rotate3d(1, 1, 0, 180deg)
详情
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>demo</title>
<style>
* {
padding: 0;
margin: 0;
}
.box {
width: 900px;
height: 300px;
margin: 100px auto;
perspective: 500px;
}
.box div {
/* float: left; */
width: 280px;
height: 200px;
margin-top: 60px;
background: url(https://img.pupper.cn/img/202111291344063.jpg) center;
transition: all 1s;
}
.box div:first-child:hover {
transform: translateX(100px) rotateX(360deg);
}
.box div:nth-child(2):hover {
transform: translateY(100px) rotateY(360deg);
}
.box div:last-child:hover {
transform: translateZ(100px) rotateZ(360deg);
}
</style>
</head>
<body>
<div class="demo">
<div class="box">
<div></div>
<div></div>
<div></div>
</div>
</div>
</body>
</html>
3. 3D 呈现(transform-style)
transfrom-style
: 控制 子元素 是否开启三维立体环境
语法:
transform-style: flat(不开启,默认) | preserve-3d(开启);
注意:
transfrom-style
是写在 父元素 中的,但是会影响子元素
详情
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>demo</title>
<style>
* {
padding: 0;
margin: 0;
}
.box {
position: relative;
width: 200px;
height: 200px;
margin: 100px auto;
perspective: 500px;
transform-style: preserve-3d;
transition: all 1s;
}
.box div {
position: absolute;
width: 200px;
height: 200px;
margin: 0 auto;
line-height: 200px;
background-color: beige;
}
.box div:last-child {
background-color: aquamarine;
transform: rotateX(60deg);
}
.box:hover {
transform: rotateY(360deg);
}
.box2 {
position: relative;
margin: 0 auto;
width: 200px;
height: 200px;
perspective: 400px;
transform-style: preserve-3d;
transition: all .4s;
}
.box2 div {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
background-color: blueviolet;
text-align: center;
line-height: 200px;
color: #fff;
font-size: 30px;
z-index: 10;
}
.box2 div:last-child {
background-color: brown;
transform: rotateY(180deg);
z-index: 1;
}
.box2:hover {
transform: rotateY(180deg);
}
</style>
</head>
<body>
<div class="demo">
<div class="box">
<div></div>
<div></div>
</div>
<div class="box2">
<div>这是正面</div>
<div>这是背面</div>
</div>
</div>
</body>
</html>
案例一
详情
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>demo</title>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
list-style: none;
}
.box {
height: 50px;
width: 800px;
margin: 100px auto;
/* 元素呈现3D效果需要添加 视距 */
perspective: 500px;
}
.box ul li {
position: relative;
margin: 0 5px;
float: left;
height: 50px;
width: 150px;
text-align: center;
line-height: 50px;
/* 控制 子元素维持 3D 环境 */
transform-style: preserve-3d;
transition: all .5s;
}
.box ul li p {
width: 150px;
position: absolute;
left: 0;
top: 0;
background-color: aqua;
color: #fff;
font-size: 20px;
}
.box ul li p:first-child {
background-color: blueviolet;
transform: translateZ(25px);
}
.box ul li p:last-child {
transform: translateY(25px) rotateX(-90deg);
}
.box ul li:hover {
transform: rotateX(90deg);
}
</style>
</head>
<body>
<div class="demo">
<div class="box">
<ul>
<li>
<p>我是菜鸟</p>
<p>我爱学习</p>
</li>
<li>
<p>我是菜鸟</p>
<p>我爱学习</p>
</li>
<li>
<p>我是菜鸟</p>
<p>我爱学习</p>
</li>
<li>
<p>我是菜鸟</p>
<p>我爱学习</p>
</li>
<li>
<p>我是菜鸟</p>
<p>我爱学习</p>
</li>
</ul>
</div>
</div>
</body>
</html>
案例二
详情
<!DOCTYPE html>
<html lang="ch-NG">
<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>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
perspective: 3000px;
}
.demo {
position: relative;
width: 1000px;
height: 600px;
margin: 50px auto;
transform-style: preserve-3d;
}
.demo div {
position: absolute;
left: 350px;
top: 150px;
width: 300px;
height: 300px;
}
/* 先旋转后移动 */
.demo div:nth-child(1) {
background: url(https://img.pupper.cn/img/202112041024160.jpg) no-repeat;
background-size: 100%;
transform: translateZ(500px);
}
.demo div:nth-child(2) {
background: url(https://img.pupper.cn/img/202112041024160.jpg) no-repeat;
background-size: 100%;
transform: rotateY(60deg) translateZ(500px) ;
}
.demo div:nth-child(3) {
background: url(https://img.pupper.cn/img/202112041024160.jpg) no-repeat;
background-size: 100%;
transform: rotateY(120deg) translateZ(500px) ;
}
.demo div:nth-child(4) {
background: url(https://img.pupper.cn/img/202112041024160.jpg) no-repeat;
background-size: 100%;
transform: rotateY(180deg) translateZ(500px);
}
.demo div:nth-child(5) {
background: url(https://img.pupper.cn/img/202112041024160.jpg) no-repeat;
background-size: 100%;
transform: rotateY(240deg) translateZ(500px) ;
}
.demo div:nth-child(6) {
background: url(https://img.pupper.cn/img/202112041024160.jpg) no-repeat;
background-size: 100%;
transform: rotateY(300deg) translateZ(500px);
}
@keyframes demo {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(360deg);
}
}
.demo {
animation: demo 10s linear infinite;
}
.demo:hover {
animation-play-state: paused;
}
</style>
</head>
<body>
<div class="demo">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</body>
</html>