Bootstrap

CSS初入门:动画实现-animation和2D转换模块

1、CSS中的动画

1.1 简介

目前由于该技术的规范还没有稳定,在使用前要先确保浏览器对其兼容性。 Animations是css3的一个模块,使用keyframes定义如何随着时间的移动改变CSS的属性值,可以通过指定它们的持续时间,重复次数,如何重复来控制关键帧的行为。Animations由两部分组成:css动画的配置,以及一系列的keyframes用来描述动画的开始、过程、结束状态)。不需要了解任何Js技术即可完成动画的制作。

过渡(transition)与动画(animation)之间的区别
(1)不同点:过渡必须人为的触发才能执行;动画不需要认为的触发就能执行
(2)相同点:都是用来给元素添加动画的;都是系统新增的属性;都需要满足三要素才会有效果

1.2 属性介绍

animation-name

作用:指定要绑定到选择器的关键帧的名称,告诉系统需要执行哪个动画

通过@keyframes设置动画序列序列中每个关键帧描述动画元素在动画序列的特定时间内如何渲染。关键帧使用了一个百分比来表示在动画序列中出现的时间0%表示动画的初始时间,也可以通过from关键字表示100%表示动画的结束时间,也可以通过to关键字表示
例如:

<div></div>
div{
	animation-name: leftToRight; /*执行动画的名字*/
}
@keyframes 动画名字{
            /* 动画初始位置 */
            from{
                margin-left: 0px;
            }
            /* 动画结束位置 */
            to{
                margin-left: 500px;
            }
        }
animation-duration

作用:动画持续时间
取值:time,指定动画播放完成花费的时间,单位s。默认值为 0,意味着没有动画效果。

animation-timing-function

作用:设置动画执行的速率
取值:
(1)linear,动画从头到尾的速度是相同的,即匀速。
(2)ease,默认,动画以低速开始,然后加快,在结束前变慢。(慢速-快-慢速)
(3)ease-in,动画以低速开始
(4)ease-out,动画以低速结束
(5)ease-in-out,动画以低速开始和结束
(6)cubic-bezier(n,n,n,n)在cubic-bezier函数中自己的值。取值为0~1的数值。

此外,还可以使用一个函数step(n,end),第一个参数是指定动画分割成多少个步骤,第二个参数是可选的,用于指定动画播放时的方向。

animation-delay

作用:设置页面加载完成后动画执行前的延迟间隔。
取值:time,定义动画开始前等待的时间,以秒或毫秒计。默认值为0。

animation-iteration-count

作用:定义动画的播放次数
取值:
(1)n,数字,表示播放次数
(2)infinite,无限次重复执行

animation-direction

作用:指定是否应该轮流反向播放动画
取值:
(1)normal,默认,执行完一次之后回到起点继续执行下一次
(2)alternate,往返执行,即到了末尾后,从末尾又执行到开始位置
(3)reverse,反向执行

animation-fill-mode

作用:规定当动画不播放时(当动画完成时,或当动画有一个延迟未开始播放时),要应用到的元素的样式
取值:
(1)none,不做任何改变
(2)forwards,让元素结束状态保持动画最后一帧的样式
(3)backwards,让元素等待状态的时候显示动画第一帧的样式
(4)both,让元素等待状态显示动画第一帧的样式, 让元素结束状态保持动画最后一帧的样式

animation-play-state

作用:告诉系统当前动画是否需要暂停
取值:
(1)running,执行动画
(2)paused,暂停动画

速写连写格式:
animation:动画名称(animation-name) 动画时长(animation-duration) 动画运动速度(animation-timing-function) 延迟时间(animation-delay) 执行次数(animation-iteration-count) 往返动画(animation-direction);

补充:引入外部animate.css
(1)引入animate的cdn或本地animate.css文件
<link href="https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.min.css" rel="stylesheet">
(2)给指定元素加入class"animate__animated <动效名称>"
<div class="animate__animated animate__fadeInUpBig">你好 animate</div>

1.3 使用示例

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>循环播放</title>
    <style>
        div{
            width: 100px;
            height: 100px;
            background-color: red;
            animation-name: leftToRight; /*执行动画的名字*/
            animation-duration: 5s; /**/
            animation-delay: 3s; /*页面加载完成后动画执行前的延迟时间*/
            animation-timing-function: linear; /*执行速率*/
            animation-iteration-count: infinite; /*动画播放次数*/
            animation-direction: alternate; /*是否轮流反复播放*/
        }

		/*鼠标移动到图形上面时暂停*/
        div:hover{
            animation-play-state: paused;
        }
        /* 
            定义动画
           格式: @keyframes 动画名字{}
         */
        @keyframes leftToRight{
            /* 动画初始位置 */
            from{
                margin-left: 0px;
            }
            /* 动画结束位置 */
            to{
                margin-left: 500px;
            }
        }
    </style>
</head>
<body>
    <div></div>
</body>
</html>

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>
        /* 所有标签的外边距、内边距为0 */
        *{
            margin:0px;
            padding: 0px;
            list-style: none;
        }

        div{
            width: 800px;
            height: 300px;
            background-color: black;
            border: 2px solid red;
            margin:100px auto;
            /* 清除div的浮动,使照片在div内容内 */
            overflow: hidden;
        }

        div ul{
            width: 3000px;
            height: 300px;
            /* 设置动画效果:动画效果名 持续7s 匀速 无限重复 */
            animation: play 7s linear infinite;
        }

        div ul li{
            width: 400px;
            height: 300px;
            /* 给全体ul中的li设置浮动,使他们连在一起 */
            float: left;
        }


        /* @keyframes 关键字指定动画效果  play是自定义效果的名字*/
        @keyframes play{
            /* 动画开始的位置:外边距为0处开始 */
            from{
                margin-left: 0;
            }

            /* 结束时候的位置:到达外边距-2200px处时结束 */
            /* 为什么是-2200px,让图往左移动本质上是将图通过浮动连在一起,而图由放在ul标签中,
            然后将整个ul设置动画效果左移,直到移动到div边框左边2200px处结束(在2200px位置时电脑上是看不到的图片的) */
            to{
                margin-left: -2200px;
            }
        }
    </style>
</head>
<body>
    <div>
        <ul>
            <li><img src="./images/ad7.jpeg"></li>
            <li><img src="./images/ad8.jpg"></li>
            <li><img src="./images/ad9.jpeg"></li>
            <li><img src="./images/ad10.jpg"></li>
            <li><img src="./images/ad11.jpg"></li>
            <li><img src="./images/ad12.jpg"></li>
            <li><img src="./images/ad7.jpeg"></li>
            <li><img src="./images/ad8.jpg"></li>

        </ul>
    </div>
</body>
</html>

3、示例三
呼吸灯:别看久了。。。会瞎。。。请添加图片描述

代码:

<!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>
        .bg{
            width:600px;
            height: 600px;
            background-color: black;
            margin: 50px auto;
            /* 设置父元素为相对定位,相对于页面来说的位置 */
            position: relative;
            /* 将盒模型设置为边框盒子:这种盒子的特点是整体的高度为height,宽度为width */
            box-sizing: border-box;
        }

        .bg .smallCircle{
            width: 200px;
            height: 200px;
            border: 20px solid white;
            border-radius: 50%;
            /* 设置子元素为绝对定位 */
            position: absolute;
            /* bottom和left都是子元素在父元素中的绝对位置 */
            bottom: 200px;
            left: 200px;
            margin:0;
            box-sizing: border-box;
            animation: small 2s linear infinite;
        }

        .bg .middleCircle1{
            width: 400px;
            height: 400px;
            border-radius: 50%;
            border: 20px solid white;
            position: absolute;
            bottom: 100px;
            left: 100px;
            box-sizing: border-box;
            animation: middle 4s linear infinite;
        }

        .bg .bigCircle{
            width: 500px;
            height: 500px;
            border: 10px solid white;
            border-radius: 50%;
            position: absolute;
            bottom:50px;
            left:50px;
            box-sizing: border-box; 
        }


        /* border-color控制圈圈的边框颜色变化 */
         /* transform属性中的scale控制大小变化:将圈圈从原大小的0.6逐渐放大到原来的1.3倍 */
        @keyframes small{
            0%{
                border-color: white;
                transform: scale(0.6);
            }
            25%{
                border-color: rgb(214, 214, 51);
                transform: scale(0.7);
            }
            50%{
                border-color: rgb(177, 123, 24);
                transform: scale(0.9);
            }
            75%{
                border-color: rgb(193, 236, 128);
                transform: scale(1.1);
            }
            100%{
                border-color: rgb(55, 185, 55);
                transform: scale(1.3);
            }
        }

        @keyframes middle{
            0%{
                border-color: white;
                transform: scale(0.6);
            }
            25%{
                border-color: rgb(255, 0, 212);
                transform: scale(0.7);
            }
            50%{
                border-color: rgb(255, 0, 98);
                transform: scale(0.9);
            }
            75%{
                border-color: rgb(255, 47, 99);
                transform: scale(1.1);
            }
            100%{
                border-color: rgb(128, 0, 0);
                transform: scale(1.3);
            }
        }
    </style>
</head>
<body>
    <div class="bg">
        <div class="smallCircle"></div>
        <div class="bigCircle"></div>
        <div class="middleCircle1"></div>
    </div>
</body>
</html>
  • 示例四:“动画”
body{
	background-color:#ccc;
}

div{
	postion:absolute;
	width:200px; /* 动画展示区域的宽度 */
	height:100px; /* 动画展示区域的高度 */
	backgound:url(media/bear.png) no-repeat;
	animation:bear 1s steps(8) infinite, move 1s forwards; /* forwards 保留动画最后所处的位置*/
}

/* 熊从左边跑到右边的动画 */
@keyframes move{
	0%{
		left:0;
	}
	100%{
		left:50%;
	}
}

/* 熊动作动画 */
@keyframes bear{
	0%{
		background-position:0 0;
	}
	100%{
		backgound-position:-1600px 0; /* 1600是整个图片的宽度,-号表示往左移动*/	
		transform:translateX(-50%) /* 用于让动画处于中间位置*/
	}
}

2. 2D、3D转换模块

转换模块主要的作用就是通过几个方法将原来的元素位置做出改变,并且这个改变不会影响到其他元素在文档流中的布局。

2.1 2D转换模块

在这里插入图片描述

1、transform属性

transform 属性将元素应用从2D或3D转换。该属性允许我们对元素进行旋转、缩放、移动或者倾斜。

rotate()方法

作用:旋转
格式:rotate(45deg);

deg是单位,代表多少度

旋转轴向
概念:默认情况下所有元素都是围绕Z轴进行旋转

 transform: rotateZ(45deg);

​围绕x轴旋转

​transform: rotateX(45deg);

围绕y轴旋转

​transform: rotateY(45deg);
translate()方法

作用:平移;

transform:translate(100px,0px);

第一个参数代表水平方向
第二个参数代表竖直方向

补充:

translateX(x) 向X轴方向平移
translateY(x) 向Y轴方向平移
scale()方法

作用:缩放

transform:scale(1.5);
transform:sacle(0.5,0.5);

第一个参数:水平方向
第二各参数:竖直方向
如果取值是1, 代表不变;如果取值大于1, 代表需要放大如果取值小于1, 代表需要缩小;如果水平和垂直缩放都一样, 那么可以简写为一个参数

补充:

transform:scaleX(2)
transform:scaleY(2)

转换连写格式
transform: rotate(45deg) translate(100px, 0px) scale(1.5, 1.5);
注意:
(1)如果需要进行多个转换, 那么用空格隔开;
(2)注意属性的前后顺序,2D的转换模块会修改元素的坐标系, 所以旋转之后再平移就不是水平平移的

skew() 方法

skew() 方法使元素沿 X 和 Y 轴倾斜给定角度

div {
  transform: skew(20deg, 10deg);
}

补充:

transform:skewX(20deg)
transform:skewY(20deg)
transition-origin 属性

transform-origin:xxxpx,xxxpx;
形变中心点

第一个参数:水平方向
第二个参数:竖直方向

取值有三种形式
​ 具体像素
transform-origin: 200px 0px;
​ 百分比
transform-origin: 50% 50%;
transform-origin: 0% 0%;
​ 特殊关键字
transform-origin: center center;
注意:默认情况下所有的元素都是以自己的中心点作为参考来旋转的, 我们可以通过形变中心点属性来修改它的参考点

matrix() 方法

matrix() 方法把所有 2D 变换方法组合为一个。

matrix() 方法可接受六个参数,其中包括数学函数,这些参数使您可以旋转、缩放、移动(平移)和倾斜元素。

参数如下:
matrix(scaleX(),skewY(),skewX(),scaleY(),translateX(),translateY())

例如:

div {
  transform: matrix(1, -0.3, 0, 1, 0, 0);
}
2、使用示例
<style>
  .container {
    margin: auto;
    width: 300px;
    height: 100px;
  }

  div[class^="demo"] {
    width: 100px;
    height: 100px;
    background-color: rgb(221, 108, 55);
    margin: 10px;
  }

  .demo1 {
    transition: all 0.8s ease;
  }

  .demo1:hover {
    transform: translate(0, -30px);
  }

  .demo2 {
    transition: all 2s ease;
  }

  .demo2:hover {
    transform: rotate(90deg);
  }

  .demo3 {
    transition: all 1.5s ease-in;
  }

  .demo3:hover {
    transform: scale(2);
  }

  .demo4 {
    transition: all 1.5s ease-out;
  }

  .demo4:hover {
    transform: translate(200px, 200px) rotate(90deg);
  }

  .demo5 {
    transition: all 1.5s ease-in-out;
  }

  .demo5:hover {
    transform: rotate(90deg) translateX(200px);
  }
</style>
</head>
<body>
<div class="container">
  <div class="demo1">2d平移</div>
  <div class="demo2">2d旋转</div>
  <div class="demo3">2d放大</div>
  <div class="demo4">先平移后旋转</div>
  <div class="demo5">边旋转边平移</div>
</div>
</body>

2.2 3D转换模块

在这里插入图片描述

2.2.1 属性

属性描述
transform转换模式为2D或者3D,属性值为转换方法
transform-origin改变轴原点位置,属性值(x,y,z),分别定义视图在各个轴上的位置,其中x可以为left、center、right、length、%,y可以为top、center、bottom、length、%,z可以为length
transform-style规定被嵌套的元素是否按照3D显示,取值有:flat、preserve-3d;,flat表示子元素将不保留其 3D 位置;preserve-3d表示子元素保留其3D位置。
perspective设置透视,取值:number、1none;,其中number是元素距离视图的距离,以像素计,none表示不透视,通常用于父元素上。
perspective-origin该属性用于定义 3D 元素所基于的 X 轴和 Y 轴。
backface-visibility定义元素在不面对屏幕时是否可见,简单来说就是当元素背面翻转过来时元素不可见,取值有:visible、hidden

2.2.2 方法

在这里插入图片描述
perspective(n),在2D平面产生近大远小视觉立体,透视可以理解成3D物体投影在2D平面内,单位是像素。透视要写在被观察元素的父盒子上面

2.2.3 使用示例

  • 示例一
<style>
   .container {
     width: 200px;
     perspective: 2000px;
     margin: 50px auto;
   }

   .box {
     width: 200px;
     height: 200px;
     margin-top: 20px;
     display: inline-block;
     transition: all 2s ease;
     background-image: linear-gradient(
       to bottom right,
       red,
       yellow
     ) !important;
   }

   .rotateX:hover {
     transform: rotateX(180deg);
   }

   .rotateY:hover {
     transform: rotateY(180deg);
   }

   .rotateZ:hover {
     transform: rotateZ(180deg);
   }

   .translateX:hover {
     transform: translateX(100px);
   }

   .translateY:hover {
     transform: translateY(100px);
   }

   .translateZ:hover {
     transform: translateZ(100px);
   }

   .scaleX:hover {
     transform: scaleX(2);
   }

   .scaleY:hover {
     transform: scaleY(2);
   }

   .scaleZ:hover {
     transform: scaleZ(2);
   }
 </style>
</head>
<body>
 <div class="container">
   <!-- 实现卡片沿轴翻转效果 -->
   <!-- 沿x轴 -->
   <div class="box rotateX"></div>
   <!-- 沿y轴 -->
   <div class="box rotateY"></div>
   <!-- 沿z轴 -->
   <div class="box rotateZ"></div>

   <!-- 卡片沿轴平移 -->
   <!-- 沿x轴 -->
   <div class="box translateX"></div>
   <!-- 沿x轴 -->
   <div class="box translateY"></div>
   <!-- 沿z轴 -->
   <div class="box translateZ"></div>

   <!-- 沿轴放大 -->
   <!-- 沿x轴 -->
   <div class="box scaleX"></div>
   <!-- 沿x轴 -->
   <div class="box scaleY"></div>
   <!-- 沿x轴 -->
   <div class="box scaleZ"></div>
 </div>
</body>
  • ratateX()
    在这里插入图片描述

  • rotateY()
    在这里插入图片描述

  • rotateZ()
    在这里插入图片描述

  • translateX()
    在这里插入图片描述

  • translateY()
    在这里插入图片描述

  • translateZ()
    在这里插入图片描述

  • scaleX()
    在这里插入图片描述

  • scaleY()
    在这里插入图片描述

  • scaleZ()
    在这里插入图片描述

在使用rotate()方法的时候,其参数值可以传正数,也可以传负数,用来控制旋转方向,有这样一种判断方法,左手定则,左手拇指伸直,指向轴的方向,其他手指弯曲,指向的是旋转的方向为正值,反之为负值。

  • 示例二:两面翻转盒子

如图

在这里插入图片描述

 <style>
      .container {
        position: relative;
        width: 200px;
        height: 200px;
        margin: 100px auto;
        transition: all 0.8s ease;
        /* 让没有出现在人眼前的元素依旧保持3D效果 */
        transform-style: preserve-3d;
        /* 给父元素添加透视 */
        perspective: 800px;
      }

      /* 将外边的容器整体翻转 */
      .container:hover {
        transform: rotateY(180deg);
      }

      .front,
      .reverse {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        border-radius: 50%;
        line-height: 200px;
        text-align: center;
        font-size: 30px;
        color: #fff;
        /* 将元素背面隐藏 */
        backface-visibility: hidden;
        box-shadow: 0 4px 20px #4b4747;
      }

      .front {
        background-color: rgb(239, 53, 84);
        /* 让当前盒子先显示 */
        z-index: 1;
      }

      .reverse {
        background-color: rgb(11, 191, 227);
        transform: translateZ(1px);
        /* 显示翻转过来的内容 */
        transform: rotateY(180deg);
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="front">前面</div>
      <div class="reverse">后面</div>
    </div>
  </body>
  • 示例二:翻转的导航栏
    在这里插入图片描述
<style>
    * {
      margin: 0;
      padding: 0;
    }

    ul {
      list-style: none;
      margin: 100px;
    }

    ul li {
      width: 120px;
      height: 40px;
      /* 透视 */
      perspective: 800px;
    }

    .box {
      position: relative;
      width: 100%;
      height: 100%;
      transition: all 0.8s;
      /* 让子元素转换时维持3D状态 */
      transform-style: preserve-3d;
    }

    .front,
    .bottom {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      backface-visibility: hidden;
    }

    .front {
      background-color: rgb(84, 242, 226);
      z-index: 1;
      transform:translateZ(20px)
    }

    .bottom {
      background-color: rgb(36, 223, 71);
      transform:  translateY(20px) rotateX(-90deg);
    }

    .box:hover {
      transform: rotateX(90deg);
    }
  </style>
</head>
<body>
  <ul>
    <li>
      <div class="box">
        <div class="front">前面</div>
        <div class="bottom">下面</div>
      </div>
    </li>
  </ul>
</body>
  • 旋转木马
    在这里插入图片描述
<style>
   body {
     perspective: 1000px;
   }

   .container {
     position: relative;
     width: 300px;
     height: 200px;
     margin: 100px auto;
     transform-style: preserve-3d;
     /* 添加动画效果 */
     animation: rotate 10s linear infinite;
   }
   
   /* 动画帧 */
   @keyframes rotate {
     0% {
       transform: rotateY(0);
     }

     100% {
       transform: rotateY(360deg);
     }
   }

   /* 鼠标放上去动画停止 */
   .container:hover {
     animation-play-state: paused;
   }

   .container div {
     position: absolute;
     inset: 0;
     width: 100%;
     height: 100%;
     /* TODO:待添加图片 */
     background: url(/image/pikaqiu.jpg) no-repeat center;
   }

   .container div:nth-child(1) {
     transform: translateZ(300px);
   }

   .container div:nth-child(2) {
     transform: rotateY(60deg) translateZ(300px);
   }
   .container div:nth-child(3) {
     transform: rotateY(120deg) translateZ(300px);
   }
   .container div:nth-child(4) {
     transform: rotateY(180deg) translateZ(300px);
   }
   .container div:nth-child(5) {
     transform: rotateY(240deg) translateZ(300px);
   }
   .container div:nth-child(6) {
     transform: rotateY(300deg) translateZ(300px);
   }
 </style>
</head>
<body>
 <div class="container">
   <div></div>
   <div></div>
   <div></div>
   <div></div>
   <div></div>
   <div></div>
 </div>
</body>
;