前端学习<二>CSS基础——12-CSS3属性详解:动画详解

news2024/11/27 18:46:51

前言

本文主要内容:

  • 过渡:transition

  • 2D 转换 transform

  • 3D 转换 transform

  • 动画:animation

过渡:transition

transition的中文含义是过渡。过渡是CSS3中具有颠覆性的一个特征,可以实现元素不同状态间的平滑过渡(补间动画),经常用来制作动画效果。

  • 补间动画:自动完成从起始状态到终止状态的的过渡。不用管中间的状态。

  • 帧动画:通过一帧一帧的画面按照固定顺序和速度播放。如电影胶片。

参考链接:补间动画基础

transition 包括以下属性:

  • transition-property: all; 如果希望所有的属性都发生过渡,就使用all。

  • transition-duration: 1s; 过渡的持续时间。

  • transition-timing-function: linear; 运动曲线。属性值可以是:

    • linear 线性

    • ease 减速

    • ease-in 加速

    • ease-out 减速

    • ease-in-out 先加速后减速

  • transition-delay: 1s; 过渡延迟。多长时间后再执行这个过渡动画。

上面的四个属性也可以写成综合属性

     transition: 让哪些属性进行过度 过渡的持续时间 运动曲线 延迟时间;
 ​
     transition: all 3s linear 0s;

其中,transition-property这个属性是尤其需要注意的,不同的属性值有不同的现象。我们来示范一下。

如果设置 transition-property: width,意思是只让盒子的宽度在变化时进行过渡。效果如下:

如果设置 transition-property: all,意思是让盒子的所有属性(包括宽度、背景色等)在变化时都进行过渡。效果如下:

案例:小米商品详情

代码:

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>CSS 过渡</title>
     <style>
         body {
             margin: 0;
             padding: 0;
             background-color: #eeeeee;
         }
 ​
         .content {
             width: 800px;
             height: 320px;
             padding-left: 20px;
             margin: 80px auto;
         }
 ​
         .item {
             width: 230px;
             height: 300px;
             text-align: center;
             margin-right: 20px;
             background-color: #FFF;
             float: left;
             position: relative;
             top: 0;
             overflow: hidden; /* 让溢出的内容隐藏起来。意思是让下方的橙色方形先躲起来 */
             transition: all .5s; /* 从最初到鼠标悬停时的过渡 */
         }
 ​
         .item img {
             margin-top: 30px;
         }
 ​
         .item .desc {
             position: absolute;
             left: 0;
             bottom: -80px;
             width: 100%;
             height: 80px;
             background-color: #ff6700;
             transition: all .5s;
         }
 ​
         /* 鼠标悬停时,让 item 整体往上移动5px,且加一点阴影 */
         .item:hover {
             top: -5px;
             box-shadow: 0 0 15px #AAA;
         }
 ​
         /* 鼠标悬停时,让下方的橙色方形现身 */
         .item:hover .desc {
             bottom: 0;
         }
     </style>
 </head>
 <body>
 <div class="content">
     <div class="item">
         <img src="./images/1.png" alt="">
     </div>
 ​
     <div class="item">
         <img src="./images/2.png" alt="">
         <span class="desc"></span>
     </div>
     <div class="item">
         <img src="./images/3.jpg" alt="">
         <span class="desc"></span>
     </div>
 </div>
 </body>
 </html>

效果如下:

动画效果录制的比较差,但真实体验还是可以的。

工程文件:2018-02-08-小米商品详情过渡

2D 转换

转换是 CSS3 中具有颠覆性的一个特征,可以实现元素的位移、旋转、变形、缩放,甚至支持矩阵方式。

转换再配合过渡和动画,可以取代大量早期只能靠 Flash 才可以实现的效果。

在 CSS3 当中,通过 transform 转换来实现 2D 转换或者 3D 转换。

  • 2D转换包括:缩放、移动、旋转。

我们依次来讲解。

1、缩放:scale

格式:

     transform: scale(x, y);
 ​
     transform: scale(2, 0.5);

参数解释: x:表示水平方向的缩放倍数。y:表示垂直方向的缩放倍数。如果只写一个值就是等比例缩放。

取值:大于1表示放大,小于1表示缩小。不能为百分比。

格式举例:

 <!DOCTYPE html>
 <html>
 <head lang="en">
     <meta charset="UTF-8">
     <title></title>
     <style>
         .box {
             width: 1000px;
             margin: 100px auto;
         }
 ​
         .box div {
             width: 300px;
             height: 150px;
             background-color: pink;
             float: left;
             margin-right: 15px;
             color: white;
             text-align: center;
             font: 400 30px/150px “宋体”;
 ​
         }
 ​
         .box .box2 {
             background-color: green;
             transition: all 1s;
         }
 ​
         .box .box2:hover {
             /*width: 500px;*/
             /*height: 400px;*/
             background-color: yellowgreen;
 ​
             /* transform:  css3中用于做变换的属性
                 scale(x,y):缩放 */
             transform: scale(2, 0.5);
         }
 ​
     </style>
 </head>
 <body>
 <div class="box">
     <div class="box1">1</div>
     <div class="box2">2</div>
     <div class="box3">3</div>
 </div>
 ​
 </body>
 </html>

效果:

上图可以看到,给 box1 设置 2D 转换,并不会把兄弟元素挤走。

2、位移:translate

格式:

     transform: translate(水平位移, 垂直位移);
 ​
     transform: translate(-50%, -50%);

参数解释:

  • 参数为百分比,相对于自身移动。

  • 正值:向右和向下。 负值:向左和向上。如果只写一个值,则表示水平移动。

格式举例:

 <!DOCTYPE html>
 <html>
 <head lang="en">
     <meta charset="UTF-8">
     <title></title>
     <style>
         .box {
             width: 1000px;
             margin: 100px auto;
         }
 ​
         .box > div {
             width: 300px;
             height: 150px;
             border: 1px solid #000;
             background-color: red;
             float: left;
             margin-right: 30px;
         }
 ​
         div:nth-child(2) {
             background-color: pink;
             transition: all 1s;
         }
 ​
         /* translate:(水平位移,垂直位移)*/
         div:nth-child(2):hover {
             transform: translate(-50%, -50%);
         }
     </style>
 ​
 </head>
 <body>
 <div class="box">
     <div class="box1">1</div>
     <div class="box2">2</div>
     <div class="box3">3</div>
 </div>
 ​
 </body>
 </html>

效果:

上图中,因为我在操作的时候,鼠标悬停后,立即进行了略微的移动,所以产生了两次动画。正确的效果应该是下面这样的:

应用:让绝对定位中的盒子在父亲里居中

我们知道,如果想让一个标准流中的盒子在父亲里居中(水平方向看),可以将其设置margin: 0 auto属性。

可如果盒子是绝对定位的,此时已经脱标了,如果还想让其居中(位于父亲的正中间),可以这样做:

     div {
         width: 600px;
         height: 60px;
         position: absolute;  绝对定位的盒子
         left: 50%;           首先,让左边线居中
         top: 0;
         margin-left: -300px;  然后,向左移动宽度(600px)的一半
     }

如上方代码所示,我们先让这个宽度为600px的盒子,左边线居中,然后向左移动宽度(600px)的一半,就达到效果了。

现在,我们还可以利用偏移 translate 来做,这也是比较推荐的写法:

     div {
         width: 600px;
         height: 60px;
         background-color: red;
         position: absolute;       绝对定位的盒子
         left: 50%;               首先,让左边线居中
         top: 0;
         transform: translate(-50%);    然后,利用translate,往左走自己宽度的一半【推荐写法】
     }

3、旋转:rotate

格式:

	transform: rotate(角度);

	transform: rotate(45deg);

参数解释:正值 顺时针;负值:逆时针。

举例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box {
            width: 200px;
            height: 200px;
            background-color: red;
            margin: 50px auto;
            color: #fff;
            font-size: 50px;
            transition: all 2s; /* 过渡:让盒子在进行 transform 转换的时候,有个过渡期 */
        }

        /* rotate(角度)旋转 */
        .box:hover {
            transform: rotate(-405deg); /* 鼠标悬停时,让盒子进行旋转 */
        }

    </style>
</head>
<body>
<div class="box">1</div>

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

效果:

注意,上方代码中,我们给盒子设置了 transform 中的 rotate 旋转,但同时还要给盒子设置 transition 过渡。如果没有这行过渡的代码,旋转会直接一步到位,效果如下:(不是我们期望的效果)

案例1:小火箭

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        html,body{
            height:100%;
        }

        body{
            background-color: #DE8910;
        }
        .rocket{
            position: absolute;
            left:100px;
            top:600px;
            height: 120px;
            transform:translate(-200px ,200px) rotate(45deg);
            transition:all 1s ease-in;
        }

        body:hover .rocket{
            transform:translate(500px,-500px) rotate(45deg);
        }
    </style>
</head>
<body>
    <img  class="rocket" src="images/rocket.png" alt=""/>
</body>
</html>

上方代码中,我们将 transform 的两个小属性合并起来写了。

小火箭图片的url:http://img.smyhvae.com/20180208-rocket.png

案例2:扑克牌

rotate 旋转时,默认是以盒子的正中心为坐标原点的。如果想改变旋转的坐标原点,可以用transform-origin属性。格式如下:

	transform-origin: 水平坐标 垂直坐标;

	transform-origin: 50px 50px;

	transform-origin: center bottom;   //旋转时,以盒子底部的中心为坐标原点

我们来看一下 rotate 结合 transform-origin 的用法举例。

代码如下:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        body {
            /*background-color: #eee;*/
        }

        .box {

            width: 300px;
            height: 440px;
            margin: 100px auto;
            position: relative;
        }

        img {
            width: 100%;
            transition: all 1.5s;
            position: absolute;     /* 既然扑克牌是叠在一起的,那就都用绝对定位 */
            left: 0;
            top: 0;

            transform-origin: center bottom; /*旋转时,以盒子底部的中心为坐标原点*/
            box-shadow: 0 0 3px 0 #666;
        }

        .box:hover img:nth-child(6) {
            transform: rotate(-10deg);
        }

        .box:hover img:nth-child(5) {
            transform: rotate(-20deg);
        }

        .box:hover img:nth-child(4) {
            transform: rotate(-30deg);
        }

        .box:hover img:nth-child(3) {
            transform: rotate(-40deg);
        }

        .box:hover img:nth-child(2) {
            transform: rotate(-50deg);
        }

        .box:hover img:nth-child(1) {
            transform: rotate(-60deg);
        }

        .box:hover img:nth-child(8) {
            transform: rotate(10deg);
        }

        .box:hover img:nth-child(9) {
            transform: rotate(20deg);
        }

        .box:hover img:nth-child(10) {
            transform: rotate(30deg);
        }

        .box:hover img:nth-child(11) {
            transform: rotate(40deg);
        }

        .box:hover img:nth-child(12) {
            transform: rotate(50deg);
        }

        .box:hover img:nth-child(13) {
            transform: rotate(60deg);
        }

    </style>
</head>
<body>
<div class="box">
    <img src="images/pk1.png"/>
    <img src="images/pk2.png"/>
    <img src="images/pk1.png"/>
    <img src="images/pk2.png"/>
    <img src="images/pk1.png"/>
    <img src="images/pk2.png"/>
    <img src="images/pk1.png"/>
    <img src="images/pk2.png"/>
    <img src="images/pk1.png"/>
    <img src="images/pk2.png"/>
    <img src="images/pk1.png"/>
    <img src="images/pk2.png"/>
    <img src="images/pk1.png"/>
</div>
</body>
</html>

效果如下:

4、倾斜

暂略。

3D 转换

1、旋转:rotateX、rotateY、rotateZ

3D坐标系(左手坐标系)

如上图所示,伸出左手,让拇指和食指成“L”形,大拇指向右,食指向上,中指指向前方。拇指、食指和中指分别代表X、Y、Z轴的正方向,这样我们就建立了一个左手坐标系。

浏览器的这个平面,是X轴、Y轴;垂直于浏览器的平面,是Z轴。

旋转的方向:(左手法则)

左手握住旋转轴,竖起拇指指向旋转轴的正方向,正向就是其余手指卷曲的方向

从上面这句话,我们也能看出:所有的3d旋转,对着正方向去看,都是顺时针旋转。

格式:

	transform: rotateX(360deg);    //绕 X 轴旋转360度

	transform: rotateY(360deg);    //绕 Y 轴旋转360度

	transform: rotateZ(360deg);    //绕 Z 轴旋转360度

格式举例:

(1)rotateX 举例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .rotateX {
            width: 300px;
            height: 226px;
            margin: 200px auto;

            /* 透视 :加给变换的父盒子*/
            /* 设置的是用户的眼睛距离 平面的距离*/
            /* 透视效果只是视觉上的呈现,并不是正真的3d*/
            perspective: 110px;
        }

        img {
            /* 过渡*/
            transition: transform 2s;
        }

        /* 所有的3d旋转,对着正方向去看,都是顺时针旋转*/
        .rotateX:hover img {
            transform: rotateX(360deg);
        }

    </style>
</head>
<body>
<div class="rotateX">
    <img src="images/x.jpg" alt=""/>
</div>
</body>
</html>

效果:

上方代码中,我们最好加个透视的属性,方能看到3D的效果;没有这个属性的话,图片旋转的时候,像是压瘪了一样。

而且,透视的是要加给图片的父元素 div,方能生效。我们在后面会讲解透视属性。

(2)rotateY 举例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .rotateY {
            width: 237px;
            height: 300px;
            margin: 100px auto;

            /* 透视 */
            perspective: 150px;
        }

        img {
            transition: all 2s;  /* 过渡 */
        }

        .rotateY:hover img {
            transform: rotateY(360deg);
        }
    </style>
</head>
<body>
<div class="rotateY">
    <img src="images/y.jpg" alt=""/>
</div>
</body>
</html>

效果:

(3)rotateZ 举例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .rotateZ {
            width: 330px;
            height: 227px;
            margin: 100px auto;

            /* 透视*/
            perspective: 200px;
        }

        img {
            transition: all 1s;
        }

        .rotateZ:hover img {
            transform: rotateZ(360deg);
        }
    </style>
</head>
<body>
<div class="rotateZ">
    <img src="images/z.jpg" alt=""/>
</div>
</body>
</html>

效果:

案例:百度钱包的水平翻转效果

现在有下面这张图片素材:

要求做成下面这种效果:

上面这张图片素材其实用的是精灵图。实现的代码如下:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        body {
            background-color: cornflowerblue;
        }

        .box {
            width: 300px;
            height: 300px;
            /*border: 1px solid #000;*/
            margin: 50px auto;
            position: relative;
        }

        .box > div {
            width: 100%;
            height: 100%;
            position: absolute;
            /*border: 1px solid #000;*/
            border-radius: 50%;
            transition: all 2s;
            backface-visibility: hidden;
        }

        .box1 {
            background: url(images/bg.png) left 0 no-repeat; /*默认显示图片的左半边*/
        }

        .box2 {
            background: url(images/bg.png) right 0 no-repeat;
            transform: rotateY(180deg); /*让图片的右半边默认时,旋转180度,就可以暂时隐藏起来*/

        }

        .box:hover .box1 {
            transform: rotateY(180deg); /*让图片的左半边转消失*/
        }

        .box:hover .box2 {
            transform: rotateY(0deg); /*让图片的左半边转出现*/
        }
    </style>
</head>
<body>
<div class="box">
    <div class="box1"></div>
    <div class="box2"></div>
</div>
</body>
</html>

2、移动:translateX、translateY、translateZ

格式:

	transform: translateX(100px);    //沿着 X 轴移动

	transform: translateY(360px);    //沿着 Y 轴移动

	transform: translateZ(360px);    //沿着 Z 轴移动

格式举例:

(1)translateX 举例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box {
            width: 200px;
            height: 200px;
            background: green;
            transition: all 1s;
        }

        .box:hover {
            transform: translateX(100px);
        }
    </style>
</head>
<body>
<div class="box">

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

效果:

(2)translateY 举例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box {
            width: 200px;
            height: 200px;
            background: green;
            transition: all 1s;
        }

        .box:hover {
            transform: translateY(100px);
        }
    </style>
</head>
<body>
<div class="box">

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

效果:

(3)translateZ 举例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        body {
            /* 给box的父元素加透视效果*/
            perspective: 1000px;
        }

        .box {
            width: 250px;
            height: 250px;
            background: green;
            transition: all 1s;
            margin: 200px auto
        }

        .box:hover {
            /* translateZ必须配合透视来使用*/
            transform: translateZ(400px);
        }
    </style>
</head>
<body>
<div class="box">

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

效果:

上方代码中,如果不加透视属性,是看不到translateZ的效果的。

3、透视:perspective

电脑显示屏是一个 2D 平面,图像之所以具有立体感(3D效果),其实只是一种视觉呈现,通过透视可以实现此目的。

透视可以将一个2D平面,在转换的过程当中,呈现3D效果。但仅仅只是视觉呈现出 3d 效果,并不是正真的3d。

格式有两种写法:

  • 作为一个属性,设置给父元素,作用于所有3D转换的子元素

  • 作为 transform 属性的一个值,做用于元素自身。

格式举例:

perspective: 500px;

4、3D呈现(transform-style)

3D元素构建是指某个图形是由多个元素构成的,可以给这些元素的父元素设置transform-style: preserve-3d来使其变成一个真正的3D图形。属性值可以如下:

	transform-style: preserve-3d;     /* 让 子盒子 位于三维空间里 */

	transform-style: flat;            /* 让子盒子位于此元素所在的平面内(子盒子被扁平化) */

案例:立方体

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box {
            width: 250px;
            height: 250px;
            border: 1px dashed red;
            margin: 100px auto;
            position: relative;
            border-radius: 50%;

            /* 让子盒子保持3d效果*/

            transform-style: preserve-3d;

            /*transform:rotateX(30deg) rotateY(-30deg);*/

            animation: gun 8s linear infinite;
        }

        .box > div {
            width: 100%;
            height: 100%;
            position: absolute;
            text-align: center;
            line-height: 250px;
            font-size: 60px;
            color: #daa520;
        }

        .left {
            background-color: rgba(255, 0, 0, 0.3);
            /* 变换中心*/
            transform-origin: left;
            /* 变换*/
            transform: rotateY(90deg) translateX(-125px);
        }

        .right {
            background: rgba(0, 0, 255, 0.3);
            transform-origin: right;
            /* 变换*/
            transform: rotateY(90deg) translateX(125px);
        }

        .forward {
            background: rgba(255, 255, 0, 0.3);
            transform: translateZ(125px);
        }

        .back {
            background: rgba(0, 255, 255, 0.3);
            transform: translateZ(-125px);
        }

        .up {
            background: rgba(255, 0, 255, 0.3);
            transform: rotateX(90deg) translateZ(125px);
        }

        .down {
            background: rgba(99, 66, 33, 0.3);
            transform: rotateX(-90deg) translateZ(125px);
        }

        @keyframes gun {
            0% {
                transform: rotateX(0deg) rotateY(0deg);
            }

            100% {
                transform: rotateX(360deg) rotateY(360deg);
            }
        }
    </style>
</head>
<body>
<div class="box">
    <div class="up">上</div>
    <div class="down">下</div>
    <div class="left">左</div>
    <div class="right">右</div>
    <div class="forward">前</div>
    <div class="back">后</div>
</div>
</body>
</html>

动画

动画是CSS3中具有颠覆性的特征,可通过设置多个节点 来精确控制一个或一组动画,常用来实现复杂的动画效果。

1、定义动画的步骤

(1)通过@keyframes定义动画;

(2)将这段动画通过百分比,分割成多个节点;然后各节点中分别定义各属性;

(3)在指定元素里,通过 animation 属性调用动画。

之前,我们在 js 中定义一个函数的时候,是先定义,再调用:

    js 定义函数:
        function fun(){ 函数体 }

     调用:
     	fun();

同样,我们在 CSS3 中定义动画的时候,也是先定义,再调用

    定义动画:
        @keyframes 动画名{
            from{ 初始状态 }
            to{ 结束状态 }
        }

     调用:
      animation: 动画名称 持续时间;

其中,animation属性的格式如下:

            animation: 定义的动画名称 持续时间  执行次数  是否反向  运动曲线 延迟执行。(infinite 表示无限次)

            animation: move1 1s  alternate linear 3;

            animation: move2 4s;

定义动画的格式举例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box {
            width: 100px;
            height: 100px;
            margin: 100px;
            background-color: red;

            /* 调用动画*/
            /* animation: 动画名称 持续时间  执行次数  是否反向  运动曲线 延迟执行。infinite 表示无限次*/
            /*animation: move 1s  alternate linear 3;*/
            animation: move2 4s;
        }

        /* 方式一:定义一组动画*/
        @keyframes move1 {
            from {
                transform: translateX(0px) rotate(0deg);
            }
            to {
                transform: translateX(500px) rotate(555deg);
            }
        }

        /* 方式二:定义多组动画*/
        @keyframes move2 {
            0% {
                transform: translateX(0px) translateY(0px);
                background-color: red;
                border-radius: 0;
            }

            25% {
                transform: translateX(500px) translateY(0px);

            }

            /*动画执行到 50% 的时候,背景色变成绿色,形状变成圆形*/
            50% {
                /* 虽然两个方向都有translate,但其实只是Y轴上移动了200px。
                因为X轴的500px是相对最开始的原点来说的。可以理解成此时的 translateX 是保存了之前的位移 */
                transform: translateX(500px) translateY(200px);
                background-color: green;
                border-radius: 50%;
            }

            75% {
                transform: translateX(0px) translateY(200px);
            }

            /*动画执行到 100% 的时候,背景色还原为红色,形状还原为正方形*/
            100% {
                /*坐标归零,表示回到原点。*/
                transform: translateX(0px) translateY(0px);
                background-color: red;
                border-radius: 0;
            }
        }
    </style>
</head>
<body>
<div class="box">

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

注意好好看代码中的注释。

效果如下:

2、动画属性

我们刚刚在调用动画时,animation属性的格式如下:

animation属性的格式如下:

            animation: 定义的动画名称  持续时间  执行次数  是否反向  运动曲线 延迟执行。(infinite 表示无限次)

            animation: move1 1s  alternate linear 3;

            animation: move2 4s;

可以看出,这里的 animation 是综合属性,接下来,我们把这个综合属性拆分看看。

(1)动画名称:

	animation-name: move;

(2)执行一次动画的持续时间:

	animation-duration: 4s;

备注:上面两个属性,是必选项,且顺序固定。

(3)动画的执行次数:

	animation-iteration-count: 1;       //iteration的含义表示迭代

属性值infinite表示无数次。

(3)动画的方向:

	animation-direction: alternate;

属性值:normal 正常,alternate 反向。

(4)动画延迟执行:

	animation-delay: 1s;

(5)设置动画结束时,盒子的状态:

	animation-fill-mode: forwards;

属性值: forwards:保持动画结束后的状态(默认), backwards:动画结束后回到最初的状态。

(6)运动曲线:

	animation-timing-function: ease-in;

属性值可以是:linear ease-in-out steps()等。

注意,如果把属性值写成steps(),则表示动画不是连续执行,而是间断地分成几步执行。我们接下来专门讲一下属性值 steps()

steps()的效果

我们还是拿上面的例子来举例,如果在调用动画时,我们写成:

	animation: move2 4s steps(2);

效果如下:

有了属性值 steps(),我们就可以作出很多不连续地动画效果。比如时钟;再比如,通过多张静态的鱼,作出一张游动的鱼。

step()举例:时钟的简易模型

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        div {
            width: 3px;
            height: 200px;
            background-color: #000;
            margin: 100px auto;
            transform-origin: center bottom;    /* 旋转的中心点是底部 */
            animation: myClock 60s steps(60) infinite;
        }

        @keyframes myClock {
            0% {
                transform: rotate(0deg);
            }

            100% {
                transform: rotate(360deg);
            }
        }
    </style>
</head>
<body>
<div></div>
</body>
</html>

上方代码,我们通过一个黑色的长条div,旋转360度,耗时60s,分成60步完成。即可实现。

效果如下:

动画举例:摆动的鱼

现在,我们要做下面这种效果:

PS:图片的url是http://img.smyhvae.com/20180209_1245.gif,图片较大,如无法观看,可在浏览器中单独打开。

为了作出上面这种效果,要分成两步。

(1)第一步:让鱼在原地摆动

鱼在原地摆动并不是一张 gif动图,她其实是由很多张静态图间隔地播放,一秒钟播放完毕,就可以了:

上面这张大图的尺寸是:宽 509 px、高 2160 px。

我们可以理解成,每一帧的尺寸是:宽 509 px、高 270 px。270 * 8 = 2160。让上面这张大图,在一秒内从 0px 的位置往上移动2160px,分成8步来移动。就可以实现了。

代码是:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .shark {
            width: 509px;
            height: 270px; /*盒子的宽高是一帧的宽高*/
            border: 1px solid #000;
            margin: 100px auto;
            background: url(images/shark.png) left top; /* 让图片一开始位于 0 px的位置 */
            animation: sharkRun 1s steps(8) infinite; /* 一秒之内,从顶部移动到底部,分八帧, */
        }

        @keyframes sharkRun {
            0% {
            }

            /* 270 * 8 = 2160 */
            100% {
                background-position: left -2160px; /* 动画结束时,让图片位于最底部 */
            }
        }
    </style>
</head>
<body>
<div class="sharkBox">
    <div class="shark"></div>
</div>

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

效果如下:

我们不妨把上面的动画的持续时间从1s改成 8s,就可以看到动画的慢镜头:

这下,你应该恍然大悟了。

(2)第二步:让鱼所在的盒子向前移动。

实现的原理也很简单,我们在上一步中已经让shark这个盒子实现了原地摇摆,现在,让 shark 所在的父盒子 sharkBox向前移动,即可。完整版代码是:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .shark {
            width: 509px;
            height: 270px; /* 盒子的宽高是一帧的宽高 */
            border: 1px solid #000;
            margin: 100px auto;
            background: url(images/shark.png) left top; /* 让图片一开始位于 0 px的位置 */
            animation: sharkRun 1s steps(8) infinite; /* 一秒之内,从顶部移动到底部,分八帧 */
        }

        /* 鱼所在的父盒子 */
        .sharkBox {
            width: 509px;
            height: 270px;
            animation: sharkBoxRun 20s linear infinite;
        }

        @keyframes sharkRun {
            0% {
            }

            /* 270 * 8 = 2160 */
            100% {
                background-position: left -2160px; /* 动画结束时,让图片位于最底部 */
            }
        }

        @keyframes sharkBoxRun {
            0% {
                transform: translateX(-600px);
            }

            100% {
                transform: translateX(3000px);
            }
        }

    </style>
</head>
<body>
<div class="sharkBox">
    <div class="shark"></div>
</div>

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

大功告成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1558357.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024 MCM数学建模美赛2024年A题复盘,思路与经验分享:资源可用性与性别比例 | 性别比例变化是否对生态系统中的其他生物如寄生虫提供优势(五)

审题 第四问让我们探究性别比例变化是否对生态系统中的其他生物如寄生虫提供优势。这里我们可以把问题简化一下&#xff0c;只探究性别比例会不会对寄生虫提供优势。因为考虑太多生物&#xff0c;会使模型更复杂&#xff0c;我这个水平处理不了这么复杂的问题&#xff0c;是我…

宠物领养(源码+文档)

宠物领养管理系统&#xff08;小程序、ios、安卓都可部署&#xff09; 文件包含内容程序简要说明含有功能项目截图客户端主页举报页注册页领养详细发布寻宠/送养领养页 管理端送养管理用户管理科普管理签到管理 文件包含内容 1、搭建视频 2、流程图 3、开题报告 4、数据库 5、…

【javaWeb 第八篇】后端-Mybatis(万字详细学习)

Mybatis框架 前言MybatisMybatis入门配置SQL提示JDBC数据库连接池lombok Mybatis基础操作日志输出Mybatis的动态SQL 前言 这篇是作者学习数据持久层框架Mybatis的学习笔记&#xff0c;希望对大家有所帮助&#xff0c;希望大家能够与作者交流讨论 Mybatis Mybatis是一款优秀的…

书生·浦语大模型实战营之轻松玩转书生·浦语大模型趣味案例

书生浦语大模型实战营 为了帮助社区用户高效掌握和广泛应用大模型技术&#xff0c;我们重磅推出书生浦语大模型实战营系列活动&#xff0c;旨在为开发者们提供全面而系统的大模型技术学习课程。加入我们&#xff0c;一起深入大模型全流程&#xff0c;从零搭建 RAG、多模态和智…

23种设计模式之创建型模式 - 单例模式

文章目录 一、单例模式1.1单例模式定义1.2 单例模式的特点 二、实现单例模式的方式2.1 饿汉式2.2 懒汉式2.3 双重检查锁&#xff1a;2.4 静态内部类2.5 枚举实现&#xff08;防止反射攻击&#xff09;&#xff1a; 一、单例模式 1.1单例模式定义 单例模式确保系统中某个类只有…

基于SSM汽车交易系统

基于SSM汽车交易系统的设计与实现 摘要 电子商务的兴起不仅仅是带来了更多的就业行业。同样也给我们的生活带来了丰富多彩的变化。多姿多彩的世界带来了美好的生活&#xff0c;行业的发展也是形形色色的离不开技术的发展。作为时代进步的发展方面&#xff0c;信息技术至始至终…

Geoserver中CQL_FILTER的使用

概述 在Geoserver中可通过CQL_FILTER对要素进行过滤&#xff0c;CQL_FILTER即支持属性过滤也支持空间过滤&#xff0c;本文通过实际的例子演示如何使用CQL_FILTER。 简介 CQL(Common Query Language)是为OGC目录规范创建的纯文本语言。GeoServer对其进行了调整&#xff0c;使…

批量爬取招聘网站【Boss直聘】上工作岗位的招聘信息

不管是学生还是工作的小伙伴&#xff0c;估计都对不同岗位工作几年的薪酬水平比较感兴趣。本文提供爬取招聘网站&#xff0c;获取某类工作招聘信息的实现逻辑和代码。具体的实施步骤是&#xff1a;明确爬取的招聘网站—确定爬取的工作城市—确定爬取的岗位—获取岗位的招聘子链…

前端学习<二>CSS基础——13-CSS3属性:Flex布局图文详解

前言 CSS3中的 flex 属性&#xff0c;在布局方面做了非常大的改进&#xff0c;使得我们对多个元素之间的布局排列变得十分灵活&#xff0c;适应性非常强。其强大的伸缩性和自适应性&#xff0c;在网页开中可以发挥极大的作用。 flex 初体验 我们先来看看下面这个最简单的布局…

【蓝桥杯嵌入式】六、真题演练(一)-1演练篇:第 届真题

温馨提示&#xff1a; 真题演练分为模拟篇和研究篇。本专栏的主要作用是记录我的备赛过程&#xff0c;我打算先自己做一遍&#xff0c;把遇到的问题和不同之处记录到演练篇&#xff0c;然后再返回来仔细研究一下&#xff0c;找到最佳的解题方法记录到研究篇。 解题记录&#x…

了解 LoadRunner 性能测试软件及其基础使用

目录 一、了解LoadRunner 1、什么是Loadrunner&#xff1f; 2、Loadrunner包括什么组件&#xff1f; &#xff08;1&#xff09;前台组件 &#xff08;2&#xff09;后台组件 二、LoadRunner三大组件 1、VuGen&#xff08;虚拟用户脚本生成器&#xff09; &#xff08;…

2024全开源小狐狸ai付费创作系统V2.8.0

源码介绍 小狐狸GPT付费体验系统的开发基于国外很火的ChatGPT&#xff0c;这是一种基于人工智能技术的问答系统&#xff0c;可以实现智能回答用户提出的问题。相比传统的问答系统&#xff0c;ChatGPT可以更加准确地理解用户的意图&#xff0c;提供更加精准的答案。同时&#x…

算法---动态规划练习-10(删除并获得点数)

题目 1. 题目解析2. 讲解算法原理3. 编写代码 1. 题目解析 题目地址&#xff1a;点这里 2. 讲解算法原理 rob_s函数&#xff1a;这个函数实现了经典的"打家劫舍"问题的算法。使用动态规划的思想&#xff0c;通过填表的方式计算在给定范围内能够获取的最大点数。 f和…

Windows入侵排查

目录 0x00 前言 0x01 入侵排查思路 1.1 检查系统账号安全 1.2 检查异常端口、进程 1.3 检查启动项、计划任务、服务 0x00 前言 当企业发生黑客入侵、系统崩溃或其它影响业务正常运行的安全事件时&#xff0c;急需第一时间进行处理&#xff0c;使企业的网络信息系统在最短时…

PAT(多路复用)配置

PAT&#xff08;多路复用&#xff09; 核心&#xff1a;多个内网IP对应一个公共IP 如下图&#xff1a; 配置命令&#xff1a; 第一步&#xff08;定义访问控制列表&#xff09; access-list 编号 permit 网络地址 反掩码 第二步&#xff08;定义合法的外部IP&#xff09; ip …

杰发科技——Jlink插件使用

0. 简介 杰发自带的烧录工具是ATCLink&#xff0c;基于DapLink适配。个人不太喜欢ATCLink&#xff0c;推荐使用Jlink&#xff0c;毕竟自己买&#xff0c;不用问原厂要&#xff0c;而且带Jlink&#xff0c;至少5Mhz以上。 V9烧录器使用7.50以下版本驱动。 V11烧录器可以使用7…

JavaSE:继承和多态(下篇)

目录 一、前言 二、多态 &#xff08;一&#xff09;多态的概念 &#xff08;二&#xff09;多态实现条件 &#xff08;三&#xff09;多态的优缺点 三、重写 &#xff08;一&#xff09;重写的概念 &#xff08;二&#xff09;重写的规则 &#xff08;三&#xff09;重…

AtCoder+ABC129_Typical Stairs

题目描述 有一个有 N 级台阶的楼梯。高桥现在站在楼梯的脚下&#xff0c;也就是第0个台阶上。他可以一次爬上一个或两个台阶。 但是&#xff0c;编号为a[1] ~ a[m]台阶的踏板都坏了&#xff0c;所以踏上这些台阶很危险。 在不踏上坏掉的台阶的情况下&#xff0c;有多少中方案…

《书生·浦语大模型全链路开源开放体系》学习笔记

书生浦语大模型全链路开源开放体系-学习笔记 大模型成为发展通用人工智能的重要途径专用模型通用大模型 书生大模型开源历程InternLM2回归语言建模的本质主要亮点性能全方位提升强大的内生计算能力 从模型到应用典型流程全链条开源开放体系数据数据集获取预训练微调XTuner 评测…

unipush 2.0流程及踩坑记录(后端调用接口,前端推送)

unipush 在线离线示例 在DCLOUD开发者中心里面创建unipush的应用 如果遇到选择Android 包名后没有自动生成Android 应用签名的话&#xff0c;就是下图这样的。 这个情况多半就是通过直接创建云端证书造成的&#xff0c;没有编辑应用信息 没有云端证书的看这里 在我的应用&…