CSS-4

平面转换

整体认识

    div {
        margin: 100px 0;

        width: 100px;
        height: 100px;
        background-color: pink;

        /* 过渡效果 */
        transition: all 1s;
    }

    /* 当鼠标悬停到div时,进行平面转换 */
    div:hover {
        transform: translate(800px) rotate(360deg) scale(2) skew(180deg);
    }
作用:为元素添加动态效果,一般与过渡配合使用
概念:改变盒子在平面内的形态(位移、旋转、缩放、倾斜)

平移

案例展示:通过平移实现"居中"效果
(原理:利用 transform: translate(); 取值为百分比时候,是参照盒子自身尺寸计算结果的特点)

<style>
    .box {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);

        width: 100px;
        height: 100px;
        background-color: pink;
    }
</style>

<body>
    <div class="box"></div>
</body>
属性:
	transform: translate(X轴移动距离,Y轴移动距离);

取值:
	1.像素单位数值
	2.百分比(参照盒子自身尺寸计算结果)
	3.正负均可

技巧:
	1.translate() 只写一个值,表示沿着X轴移动
	2.单独设置X或者Y轴移动距离:translateX()translateY()

旋转

<style>
    .box {
        width: 100px;
        height: 100px;
        background-color: pink;

        transition: all 2s;
    }

    .box:hover {
        transform: rotate(360deg);
    }
</style>

<body>
    <div class="box"></div>
</body>
属性:
	 transform: rotate(旋转角度);
	 
角度单位:deg

技巧:
	取值为正,顺时针旋转
	取值为负,逆时针旋转

转换原点

<style>
    .box {
        width: 100px;
        height: 100px;
        background-color: pink;

        transition: all 2s;
        /* 将旋转的原点改为右边+底部 */
        transform-origin: right bottom;
    }

    .box:hover {
        transform: rotate(360deg);
    }
</style>

<body>
    <div class="box"></div>
</body>
默认情况下,转换原点是盒子中心点
转换原点是一个原点,当发生转换时候(包括旋转、缩放、平移等等),以此为原点进行坐标的定位

属性:
	transform-origin: 水平原点位置  垂直原点位置;

取值:
	1.方位名词(left、top、right、bottom、center)
	2.像素单位数值
	3.百分比

多重转换

多重转换的实现:先平移再旋转
	transform: translate(...) rotate(...);

缩放

<style>
    .box {
        margin: 100px auto;
        
        width: 100px;
        height: 100px;
        background-color: pink;

        transition: all 2s;
    }

    .box:hover {
        transform: scale(2);
    }
</style>

<body>
    <div class="box"></div>
</body>
属性:
	transform: scale( 缩放倍数 );
	transform: scale( X轴缩放倍数, Y轴缩放倍数);

技巧:
	通常,只为scale设置一个值,表示X轴和Y轴等比例缩放
	通常大于1表示放大,取值小于1表示缩小

倾斜

<style>
    .box {
        margin: 100px auto;
        
        width: 100px;
        height: 100px;
        background-color: pink;

        transition: all 0.5s;
    }

    .box:hover {
        transform: skew(-30deg);
    }
</style>

<body>
    <div class="box"></div>
</body>
属性:
	transform: skew(倾斜角度);

渐变

渐变效果

<style>
    .box {
        width: 100px;
        height: 100px;
        background-color: pink;

        transition: all 0.5s;
    }

    .box:hover {
        background-image: linear-gradient(
            to right,
            red,
            green
        );

        background-image: linear-gradient(
            45deg,
            red,
            green
        );

        background-image: linear-gradient(
            red 80%,
            green
        );
    }
</style>
渐变是多个颜色逐渐变换的效果,一般用于设置盒子背景
分类:
	1.线性渐变(沿着直线的方向发生渐变)
	2.径向渐变(沿着圆心向四周发生渐变)
	
属性:
	background-image: linear-gradient(
		渐变方向,
		颜色1 终点位置,
		颜色2 终点位置,
		...
	);
	
取值:
	1.渐变的方向:可选择不写
		to 方位名词
		角度度数
	
	2.终点位置:可选择不写
		百分比

背景颜色渐变的案例

<style>
    .box {
        position: relative;

        width: 100px;
        height: 100px;
        background-color: pink;
    }

    .mask {
        position: absolute;
        left: 0;
        top: 0;

        width: 100%;
        height: 100%;

        background-image: linear-gradient(
            transparent,  /*  transparent 它代表着全透明黑色,即一个类似rgba(0,0,0,0)这样的值 */
            rgba(0,0,0,0.5)
        );
        /* 将透明度设置为0,起到"关闭显示效果"的作用 */
        opacity: 0;
    }

    .box:hover .mask {
        /* 将透明度设置为1,起到"开启显示的效果"的作用 */
        opacity: 1;
    }
</style>

<body>
    <div class="box">
        <span>Hello World</span>
        <div class="mask"></div>
    </div>
</body>

径向渐变

<style>
    .box {
        width: 100px;
        height: 100px;
        background-color: pink;
        border-radius: 50%;

        background-image: radial-gradient(
            /* 一条半径 */
            50px at center center,
            red,
            pink
        );
    }

    .box:hover {
        background-image: radial-gradient(
            /* 两条半径 */
            50px 20px at center center,
            pink,
            red
        );
    }
</style>

<body>
    <div class="box"></div>
</body>
作用:给按钮添加高光效果
取值:
	1.半径1条则为圆,2条则为椭圆
	2.圆心位置取值:像素单位数值/百分比/方位名词

空间转换

平移

属性:
	transform: translate3d(x, y, z);
	transform: translateX();
	transform: translateY();
	transform: translateZ();
	
取值(正负均可)
	1.像素单位数值
	2.百分比(参照盒子自身尺寸计算结果)
	
注意事项:
	电脑屏幕是平面的,z轴的效果无法直接体现,所以可以配合"视距"知识点使用

视距

作用:指定了观察者与 z = 0 平面的距离,为元素添加透视效果

透视效果:近大远小

属性:
	添加给直接父级,取值范围一般为 800 ~ 1200
	perspective: 视距;

平移与视距的综合效果

<style>
    .father {
        perspective: 800px;
    }

    .son {
        margin: 100px auto;
        width: 100px;
        height: 100px;
        background-color: orange;
        transition: all .5s;
    }

    .son:hover {
        transform: translateZ(300px);
    }

</style>

<body>
    <div class="father">
        <div class="son"></div>
    </div>
</body>

旋转

<style>
    .father {
        /* 旋转时候,使用"视距"所带来的透视效果,会使得旋转更明显(因为"视距"会自动实现"近大远小,近实远虚") */
        perspective: 800px;
    }

    .son {
        margin: 100px auto;
        width: 200px;
        height: 200px;
        background-color: pink;
        transition: all 0.5s;
    }

    .son:hover {
        /* transform: rotateZ(60deg); */
        /* transform: rotateX(60deg); */
        transform: rotateY(-60deg);
    }

</style>

<body>
    <div class="father">
        <div class="son"></div>
    </div>
</body>
 属性:
     transform: rotateX(角度);
     transform: rotateY(角度);
     transform: rotateZ(角度);
 
 角度单位:deg
 
 例子: 
 	transform: rotateZ(60deg);

 拓展:
	rotate3d(x,y,z,角度度数):用来设置自定义旋转轴的位置及旋转的角度
	x,y,z 取值为 0-1 之间的数字
左手法则:根据旋转方向确定取值正负

操作:
	左手握住旋转轴,拇指指向正值方向。其他四个手指弯曲方向为旋转正值方向。

立体呈现

立体知识

<style>
    .cube {
        position: relative;
        margin: 100px auto;
        width: 200px;
        height: 200px;
        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(100px);
    }

    .back {
        background-color: green;
        transform: translateZ(-100px);
    }

    .cube:hover {
        transform: rotateY(90deg);
    }
</style>

<body>
    <div class="cube">
        <div class="front">前面</div>
        <div class="back">后面</div>
    </div>
</body>
作用:控制元素的子元素是位于3D空间中还是平面中
属性名:transform-style
属性值:
	flat: 子级处于平面中
	preserve-3d: 子级处于3D空间

立方体案例

<style>
    .cube {
        width: 300px;
        height: 300px;
        font-size: 80px;
        text-align: center;
        line-height: 300px;
        transition: 2s;
        transform: rotateY(-30deg) rotateX(-35deg);
        transform-style: preserve-3d;
        margin: 300px auto;
    }

    .cube:hover {
        transform: rotateY(30deg) rotateX(35deg);
    }

    .cube>div {
        width: 300px;
        height: 300px;
        position: absolute;
        left: 0;
        top: 0;
        transition: 2s;
        opacity: 0.5;
        border: 1px dashed black;
    }

    .cube .flat1 {
        background-color: red;
        transform: translateY(-150px) rotateX(90deg);
    }

    .cube .flat2 {
        background-color: orange;
        transform: translateY(150px) rotateX(90deg);
    }

    .cube .flat3 {
        background-color: yellow;
        transform: translateX(-150px) rotateY(90deg);
    }

    .cube .flat4 {
        background-color: green;
        transform: translateX(150px) rotateY(90deg);
    }

    .cube .flat5 {
        background-color: lightgreen;
        transform: translateZ(150px);
    }

    .cube .flat6 {
        background-color: blue;
        transform: translateZ(-150px);
    }
</style>

<body>
    <div class="cube">
        <div class="flat1">上</div>
        <div class="flat2">下</div>
        <div class="flat3">左</div>
        <div class="flat4">右</div>
        <div class="flat5">前</div>
        <div class="flat6">后</div>
    </div>
</body>

3D导航案例

<style>
    * {
        margin: 0;
        padding: 0;
    }

    ul {
        margin-top: 100px;
        margin-left: 36%;
    }

    ul li {
        float: left;
        margin: 0 5px;
        width: 120px;
        height: 35px;
        list-style: none;
        /* 一会我们需要给box旋转 也需要透视干脆给li加里面的子盒子都有透视效果 */
        perspective: 500px;
    }

    .box {
        position: relative;
        width: 100%;
        height: 100%;
        background-color: pink;
        transform-style: preserve-3d;
        transition: all .4s;
    }

    .box:hover {
        transform: rotateX(90deg);
    }

    .front,
    .bottom {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
    }

    .front {
        background-color: red;
        opacity: 0.5;
        transform: translateZ(17.5px);
    }

    .bottom {
        background-color: green;
        opacity: 0.5;
        /* 这个x轴一定是负值 */
        /* 我们如果有移动 或者其他样式,必须先写我们的移动 */
        transform: translateY(17.5px) rotateX(90deg);
    }
</style>

<body>
    <ul>
        <li>
            <div class="box">
                <div class="front">导航一</div>
                <div class="bottom">111</div>
            </div>
        </li>
        <li>
            <div class="box">
                <div class="front">导航二</div>
                <div class="bottom">222</div>
            </div>
        </li>
        <li>
            <div class="box">
                <div class="front">导航三</div>
                <div class="bottom">333</div>
            </div>
        </li>
    </ul>
</body>

缩放

transform: scale3d(x,y,z);
transform: scaleX();
transform: scaleY();
transform: scaleZ();

动画

认识动画

过渡:实现两个状态间的变换过程
动画:实现多个状态间的变换过程,动画过程可控(重复播放、最终画面、是否暂停)

定义动画

<style>
    @keyframes 动画名称 {
        from {}
        to {}
    }
</style>
<style>
    @keyframes 动画名称 {
        0% {}
        10% {}
        ...
        100% {}
    }
</style>

使用动画

<style>
    .box {
        animation: 动画名称 动画花费时长;
    }
</style>

基本演示

动画一演示:宽度从200变化到800

<style>
    .box {
        width: 200px;
        height: 100px;
        background-color: pink;
        
        /* 第二步:使用动画 */
        animation: change-size 1s;
    }

    /* 第一步:定义动画 */
    @keyframes change-size {
        from {
            width: 200px;
        }

        to {
            width: 800px;
        }
    }
</style>

<body>
    <div class="box"></div>
</body>
动画二演示:从 200*100 变化到 300*300 再变化到 800*500

<style>
    .box {
        width: 200px;
        height: 100px;
        background-color: pink;

        animation: changed 1s;
    }

    /* 注意:这里的 0%、20%、100% 表示的意思是动画时常的百分比 */
    @keyframes changed {
        0% {
            width: 200px;
            height: 100px;
        }

        20% {
            width: 300px;
            height: 300px;
        }

        100% {
            width: 800px;
            height: 500px;
        }
    }
</style>

<body>
    <div class="box"></div>
</body>

其他属性值

<style>
    .box {
        width: 200px;
        height: 100px;
        background-color: pink;

        /* 速度曲线 */
        animation: change 2s linear;       /* linear: 匀速运动 */
        animation: change 2s steps(3);     /* steps(n步): 将动画按照"步骤"分成n步 */

        /* 延迟时间 */
        animation: change 2s 4s;           /* 第一个时间是动画时长,第二个时间是延时时间 */

        /* 重复次数 */
        animation: change 2s 3;           /* 动画重复播放3次 */
        animation: change 2s infinite;    /* 动画一直重复播放 */

        /* 动画方向 */
        animation: change 2s alternate;    /* alternate:反向 */

        /* 执行完毕时状态 */
        animation: change 2s forwards;
        animation: change 2s backwards;    /* 默认效果 */
        
        /* 暂停动画 */
        animation-play-state: paused;		/* 通常配合:hover使用 */
    }

    @keyframes change {
        from {
            width: 200px;
        }

        to {
            width: 800px;
        }
    }
</style>

<body>
    <div class="box"></div>
</body>
animation: 动画名称 动画时长 速度曲线 延迟时间 重复次数 动画方向 执行完毕时状态

提示:
	1.动画名称和动画时长必须赋值
	2.取值不分先后顺序
	3.如果有两个时间值,第一个时间值表示动画时长,第二个时间值表示延迟时间

走马灯案例

<style>
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }

    li {
        list-style: none;
    }

    img {
        display: block;
        width: 200px;
        height: 102px;
    }

    .box {
        margin: 100px auto;
        width: 600px;
        height: 112px;
        border: 5px solid #000;
        overflow: hidden;
    }

    .box ul {
        display: flex;
        animation: move 6s infinite linear;
    }

    /* 定义位移动画:ul使用动画:鼠标悬停暂停动画 */
    @keyframes move {
        0% {
            transform: translate(0);
        }

        100% {
            /* 向左移动,使用负数;一张图片宽度为200px,4张图片宽度为800px,故而向左移动4张图片的宽度为-800px */
            transform: translate(-800px);
        }
    }

    .box:hover ul {
        animation-play-state: paused;
    }
</style>

<body>
    <div class="box">
        <ul>
            <!-- 真正要展示的图片 -->
            <li><img src="./images/img0.png" alt=""></li>
            <li><img src="./images/img1.png" alt=""></li>
            <li><img src="./images/img2.png" alt=""></li>
            <li><img src="./images/img3.png" alt=""></li>

            <!-- 复制前几张图片进行再次展示,只是为了弥补方框中的空白 -->
            <li><img src="./images/img0.png" alt=""></li>
            <li><img src="./images/img1.png" alt=""></li>
            <li><img src="./images/img2.png" alt=""></li>
        </ul>
    </div>
</body>

精灵动画案例

在这里插入图片描述

<style>
    div {
        width: 140px;
        height: 140px;
        border: 1px solid #000;
        background-image: url(./images/run.png);

        /* 本张精灵图有12个小图,故而steps(12) */
        animation: run 1s steps(12) infinite;
    }

    @keyframes run {
        from {
            background-position: 0 0;
        }

        to {
            background-position: -1680px 0;
        }
    }
</style>

<body>
    <div></div>
</body>

多组动画

<style>
    div {
        width: 140px;
        height: 140px;
        /* border: 1px solid #000; */
        background-image: url(./images/run.png);

        /* 多组动画 */
        animation:
            run 1s steps(12) infinite,
            move 3s forwards
    }

    /* 实现原地跑的动画效果 */
    @keyframes run {
        from {
            background-position: 0 0;
        }

        to {
            background-position: -1680px 0;
        }
    }

    /* 实现向前移动的动画效果 */
    @keyframes move {
        0% {
            transform: translate(0);
        }

        100% {
            transform: translate(800px);
        }
    }
</style>

<body>
    <div></div>
</body>