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>