收起左侧

[前端] 详解用CSS3制作圆形滚动进度条动画效果

1
回复
[复制链接]
avatar
  • TA的每日心情
    qdsmile擦汗
    2024-8-3 00:07
  • 签到天数: 2660 天

    [LV.Master]伴吧终老

    461

    主题

    1077

    帖子

    4万

    积分
    发表于 2017-5-6 02:26:35 | 显示全部楼层 |阅读模式
    详解用CSS3制作圆形滚动进度条动画效果

    主  题
        今天手把手教大家用CSS3制作圆形滚动进度条动画,想不会都难!那么,到底是什么东东呢?先不急,之前我分享了一个css实现进度条效果的博客《CSS实现进度条和订单进度条》,但是呢,那篇博客只是制作出来效果而已,并没有动画效果,因为当时正期末复习期间,所以就省了制作动画的时间成本。所以,今天就一起把各种效果都实现吧!
    内  容
        先看一下效果图,会提升我们的学习兴趣哟:

    261546247015000.gif
        好的,我将按照此图从上到下的顺序讲解,由于第一和第二种效果之气那篇博客《CSS实现进度条和订单进度条》已经介绍过怎么做的了,这里就把重心放在动画上面,对于圆形效果是重点,我将详细讲解。
    第一种效果:
    html结构:
    1. <div id="progress">
    2.       <span></span>
    3. </div>
    复制代码
    css样式:
    1. #progress{
    2.             width: 50%;
    3.             height: 30px;
    4.             border:1px solid #ccc;
    5.             border-radius: 15px;
    6.             margin: 50px 0 0 100px;
    7.             overflow: hidden;
    8.             box-shadow: 0 0 5px 0px #ddd inset;
    9.         }
    10.         #progress span {
    11.             display: inline-block;
    12.             width: 100%;
    13.             height: 100%;
    14.             background: #2989d8; /* Old browsers */
    15.             background: -moz-linear-gradient(45deg, #2989d8 33%, #7db9e8 34%, #7db9e8 59%, #2989d8 60%); /* FF3.6+ */
    16.             background: -webkit-gradient(linear, left bottom, right top, color-stop(33%,#2989d8), color-stop(34%,#7db9e8), color-stop(59%,#7db9e8), color-stop(60%,#2989d8)); /* Chrome,Safari4+ */
    17.             background: -webkit-linear-gradient(45deg, #2989d8 33%,#7db9e8 34%,#7db9e8 59%,#2989d8 60%); /* Chrome10+,Safari5.1+ */
    18.             background: -o-linear-gradient(45deg, #2989d8 33%,#7db9e8 34%,#7db9e8 59%,#2989d8 60%); /* Opera 11.10+ */
    19.             background: -ms-linear-gradient(45deg, #2989d8 33%,#7db9e8 34%,#7db9e8 59%,#2989d8 60%); /* IE10+ */
    20.             background: linear-gradient(45deg, #2989d8 33%,#7db9e8 34%,#7db9e8 59%,#2989d8 60%); /* W3C */
    21.             filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#2989d8', endColorstr='#2989d8',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
    22.             background-size: 60px 30px;
    23.             text-align: center;
    24.             color:#fff;
    25.             -webkit-animation:load 3s ease-in;
    26.         }
    27.         @-webkit-keyframes load{
    28.             0%{
    29.                 width: 0%;
    30.             }
    31.             100%{
    32.                 width:100%;
    33.             }
    34.         }
    复制代码
    可以看到其实这种进度条的动画是最容易实现的,根据具体进度百分比设置默认的width百分比和动画里100%处的width百分比就行了,比如说,我想实现70%的进度条动画效果,那么我只需要修改一下两处地方:
    1. #progress span{
    2.     width: 70%;
    3. }
    4. @-webkit-keyframes load{
    5.       0%{
    6.         width: 0%;
    7.       }
    8.     100%{
    9.         width:70%;
    10.       }
    11. }
    复制代码
    第二种效果:
    html结构:
    1. <div id="progressBar">
    2.       <!-- 进度条 -->
    3.       <div>
    4.         <span></span>
    5.       </div>
    6.       <!-- 五个圆 -->
    7.       <span></span>
    8.       <span></span>
    9.       <span></span>
    10.       <span></span>
    11.       <span></span>
    12. </div>
    复制代码
    css样式:
    1. #progressBar{
    2.             width: 80%;
    3.             height: 50px;
    4.             position: relative;
    5.             margin: 50px 0 0 100px;
    6.         }
    7.         #progressBar div{
    8.             width: 100%;
    9.             height: 10px;
    10.             position: absolute;
    11.             top:50%;
    12.             left: 0;
    13.             margin-top:-20px;
    14.             background: #ccc;
    15.         }
    16.         #progressBar div span{
    17.             position: absolute;
    18.             display: inline-block;
    19.             background: green;
    20.             height: 10px;
    21.             width: 100%;
    22.             -webkit-animation:bgLoad 5.5s linear;
    23.         }
    24.         @-webkit-keyframes bgLoad{
    25.             0%{
    26.                 width: 0%;
    27.             }
    28.             18.18%,27.27%{
    29.                 width:25%;
    30.             }
    31.             45.45%,54.54%{
    32.                 width: 50%;
    33.             }
    34.             72.72%,81.81%{
    35.                 width: 75%;
    36.             }
    37.             100%{
    38.                 width:100%;
    39.             }
    40.         }
    41.         #progressBar>span{
    42.             position: absolute;
    43.             top:0;
    44.             margin-top: -10px;
    45.             width: 40px;
    46.             height: 40px;
    47.             border-radius: 50%;
    48.             background: #ccc;
    49.             margin-left: -20px;
    50.             color:#fff;
    51.         }
    52.         @-webkit-keyframes circleLoad_1{
    53.             0%,66.66%{
    54.                 background: #ccc;
    55.             }
    56.             100%{
    57.                 background:green;
    58.             }
    59.         }
    60.         @-webkit-keyframes circleLoad_2{
    61.             0%,83.34%{
    62.                 background: #ccc;
    63.             }
    64.             100%{
    65.                 background:green;
    66.             }
    67.         }
    68.         @-webkit-keyframes circleLoad_3{
    69.             0%,88.88%{
    70.                 background: #ccc;
    71.             }
    72.             100%{
    73.                 background:green;
    74.             }
    75.         }
    76.         @-webkit-keyframes circleLoad_4{
    77.             0%,91.67%{
    78.                 background: #ccc;
    79.             }
    80.             100%{
    81.                 background:green;
    82.             }
    83.         }
    84.         #progressBar span:nth-child(2){
    85.             left: 0%;background:green;
    86.         }
    87.         #progressBar span:nth-child(3){
    88.             left: 25%;background:green;
    89.             -webkit-animation:circleLoad_1 1.5s ease-in;
    90.         }
    91.         #progressBar span:nth-child(4){
    92.             left: 50%;background:green;
    93.             -webkit-animation:circleLoad_2 3s ease-in;
    94.         }
    95.         #progressBar span:nth-child(5){
    96.             left: 75%;background:green;
    97.             -webkit-animation:circleLoad_3 4.5s ease-in;
    98.         }
    99.         #progressBar span:nth-child(6){
    100.             left: 100%;background:green;
    101.             -webkit-animation:circleLoad_4 6s ease-in;
    102.         }
    复制代码

    可以看到,其实对于动画本身是很简单的,一看就明白了,主要就是动画持续时间的计算,由于这个动画效果只执行一次,所以其实也可以用动画延迟时间来保证各个动画在指定的时间点开始执行,但是对于循环或者多次动画效果,延迟很不灵活,所以这里还是用持续时间的长短来控制动画的执行时间。

    这个订单进度条,我是设置了走一段用时1秒,然后每到一个圆点就停顿0.5秒,而这0.5秒就是相对应的圆点的动画持续执行时间。但是再次强调这个是单次动画,如果想实现循环动画,还是得做调整的,必须让所有动画的持续执行时间是一样的,不然循环起来就错乱的。而时间的改动也会影响动画关键帧的改动,下面对第一小段和第二个圆的动画时间讲解一下

    首先,细长条的动画持续时间通过计算:

    4小段x1秒 + 中间3个圆点 x 0.5秒 = 5.5秒

    接下来就是计算细长条动画关键帧的时间分配,设每一份0.5秒,那么共总就是11份,每小段得2份,每个圆点得1份,用100%除以11,可得每份大约是9.09%,接下来就是分配时间了,这个就简单了,不多说。

    接着,当细长条完成第一小段的动画效果到达第二个圆点时,会停顿0.5秒,而这0.5秒就是第二个圆点的动画时间,所以第二个圆点的动画持续时间就是:

    等待细长条执行完1小段 x1秒+自身的动画完成时间x0.5秒=1.5秒

    同样的方法计算每一份的时间然后进行分配。同理,其他动画效果相似,就不再赘述了。

    第三种效果:

    今天就重点讲解这个效果,首先,当有人说你能不能做一个圆形进度条效果出来时,如果是静态完整圆形进度条,那么就很简单了:

    1. .circleprogress{
    2.     width: 160px;
    3.     height: 160px;
    4.     border:20px solid red;
    5.     border-radius: 50%;
    6. }
    复制代码

    261546256077856.jpg

    然后就会说,这很简单嘛。但是如果不是完整圆形的呢?想了想:

    1. .circleprogress{
    2.     width: 160px;
    3.     height: 160px;
    4.     border:20px solid red;
    5.     border-left:20px solid transparent;
    6.     border-bottom:20px solid transparent;
    7.     border-radius: 50%;
    8. }
    复制代码

    2461546259207826.jpg

    然后还是会说,这个也不难啦。可是,如果不是刚好都是45度的倍数呢?

    OK,我们先设置一个200x200的方块,然后我们在这里面完成我们的效果:

    1. .circleProgress_wrapper{
    2.     width: 200px;
    3.     height: 200px;
    4.     margin: 50px auto;
    5.     position: relative;
    6.     border:1px solid #ddd;
    7. }
    复制代码

    261546269519112.jpg

    接下来我将在这个容器里再放两个矩形,每个矩形都占一半:

    1. <div class="circleProgress_wrapper">
    2.         <div class="wrapper right">
    3.             <div class="circleProgress rightcircle"></div>
    4.         </div>
    5.         <div class="wrapper left">
    6.             <div class="circleProgress leftcircle"></div>
    7.         </div>
    8. </div>
    复制代码
    1. .wrapper{
    2.     width: 100px;
    3.     height: 200px;
    4.     position: absolute;
    5.     top:0;
    6.     overflow: hidden;
    7. }
    8. .right{
    9.     right:0;
    10. }
    11. .left{
    12.     left:0;
    13. }
    复制代码

    261546282633911.jpg

    这里重点说一下.wrapper 的overflow:hidden; 起着关键性作用。这两个矩形都设置了溢出隐藏,那么当我们去旋转矩形里面的圆形的时候,溢出部分就被隐藏掉了,这样我们就可以达到我们想要的效果。

    从html结构也已看到,在左右矩形里面还会各自有一个圆形,先讲一下右半圆:

    1. .circleProgress{
    2.     width: 160px;
    3.     height: 160px;
    4.     border:20px solid transparent;
    5.     border-radius: 50%;
    6.     position: absolute;
    7.     top:0;
    8. }
    9. .rightcircle{
    10.     border-top:20px solid green;
    11.     border-right:20px solid green;
    12.     right:0;
    13. }
    复制代码

    261546292172753.jpg

    1. .circleProgress{
    2.     width: 160px;
    3.     height: 160px;
    4.     border:20px solid transparent;
    5.     border-radius: 50%;
    6.     position: absolute;
    7.     top:0;
    8.     -webkit-transform: rotate(45deg);
    9. }
    复制代码

    261546304207051.jpg

    所以只要旋转自己想要的角度就可以实现任意比例的进度条。接下来把左半圆弧也实现,变成一个全圆:

    1. .leftcircle{
    2.     border-bottom:20px solid green;
    3.     border-left:20px solid green;
    4.     left:0;
    5. }
    复制代码

    261546317173322.jpg

    紧接着,就是让它动起来,原理是这样的,先让右半圆弧旋转180度,再让左半圆弧旋转180度,这样,两个半圆弧由于先后都全部溢出而消失了,所以看起来就是进度条再滚动的效果:

    1. .rightcircle{
    2.             border-top:20px solid green;
    3.             border-right:20px solid green;
    4.             right:0;
    5.             -webkit-animation: circleProgressLoad_right 5s linear infinite;
    6.         }
    7.         .leftcircle{
    8.             border-bottom:20px solid green;
    9.             border-left:20px solid green;
    10.             left:0;
    11.             -webkit-animation: circleProgressLoad_left 5s linear infinite;
    12.         }
    13.         @-webkit-keyframes circleProgressLoad_right{
    14.             0%{
    15.                 -webkit-transform: rotate(45deg);
    16.             }
    17.             50%,100%{
    18.                 -webkit-transform: rotate(225deg);
    19.             }
    20.         }
    21.         @-webkit-keyframes circleProgressLoad_left{
    22.             0%,50%{
    23.                 -webkit-transform: rotate(45deg);
    24.             }
    25.             100%{
    26.                 -webkit-transform: rotate(225deg);
    27.             }
    28.         }
    复制代码

    261546335131507.gif

    当然,我们只需要调整一下角度就可以实现反向的效果:

    1. .circleProgress{
    2.             width: 160px;
    3.             height: 160px;
    4.             border:20px solid transparent;
    5.             border-radius: 50%;
    6.             position: absolute;
    7.             top:0;
    8.             -webkit-transform: rotate(-135deg);
    9.         }
    10.         @-webkit-keyframes circleProgressLoad_right{
    11.             0%{
    12.                 -webkit-transform: rotate(-135deg);
    13.             }
    14.             50%,100%{
    15.                 -webkit-transform: rotate(45deg);
    16.             }
    17.         }
    18.         @-webkit-keyframes circleProgressLoad_left{
    19.             0%,50%{
    20.                 -webkit-transform: rotate(-135deg);
    21.             }
    22.             100%{
    23.                 -webkit-transform: rotate(45deg);
    24.             }
    25.         }
    复制代码

    261546345298564.gif

    好的,接下来就是奔向最终效果了,正如我们一开始看到的那样,有点像我们使用360卫士清理垃圾时的类似效果,当然不是很像啦:

    1. .circleProgress_wrapper{
    2.             width: 200px;
    3.             height: 200px;
    4.             margin: 50px auto;
    5.             position: relative;
    6.             border:1px solid #ddd;
    7.         }

    8.         .wrapper{
    9.             width: 100px;
    10.             height: 200px;
    11.             position: absolute;
    12.             top:0;
    13.             overflow: hidden;
    14.         }
    15.         .right{
    16.             right:0;
    17.         }
    18.         .left{
    19.             left:0;
    20.         }
    21.         .circleProgress{
    22.             width: 160px;
    23.             height: 160px;
    24.             border:20px solid rgb(232, 232, 12);
    25.             border-radius: 50%;
    26.             position: absolute;
    27.             top:0;
    28.             -webkit-transform: rotate(45deg);
    29.         }
    30.         .rightcircle{
    31.             border-top:20px solid green;
    32.             border-right:20px solid green;
    33.             right:0;
    34.             -webkit-animation: circleProgressLoad_right 5s linear infinite;
    35.         }
    36.         .leftcircle{
    37.             border-bottom:20px solid green;
    38.             border-left:20px solid green;
    39.             left:0;
    40.             -webkit-animation: circleProgressLoad_left 5s linear infinite;
    41.         }
    42.         @-webkit-keyframes circleProgressLoad_right{
    43.             0%{
    44.                 border-top:20px solid #ED1A1A;
    45.                 border-right:20px solid #ED1A1A;
    46.                 -webkit-transform: rotate(45deg);
    47.             }
    48.             50%{
    49.                 border-top:20px solid rgb(232, 232, 12);
    50.                 border-right:20px solid rgb(232, 232, 12);
    51.                 border-left:20px solid rgb(81, 197, 81);
    52.                 border-bottom:20px solid rgb(81, 197, 81);
    53.                 -webkit-transform: rotate(225deg);
    54.             }
    55.             100%{
    56.                 border-left:20px solid green;
    57.                 border-bottom:20px solid green;
    58.                 -webkit-transform: rotate(225deg);
    59.             }
    60.         }
    61.         @-webkit-keyframes circleProgressLoad_left{
    62.             0%{
    63.                 border-bottom:20px solid #ED1A1A;
    64.                 border-left:20px solid #ED1A1A;
    65.                 -webkit-transform: rotate(45deg);
    66.             }
    67.             50%{
    68.                 border-bottom:20px solid rgb(232, 232, 12);
    69.                 border-left:20px solid rgb(232, 232, 12);
    70.                 border-top:20px solid rgb(81, 197, 81);
    71.                 border-right:20px solid rgb(81, 197, 81);
    72.                 -webkit-transform: rotate(45deg);
    73.             }
    74.             100%{
    75.                 border-top:20px solid green;
    76.                 border-right:20px solid green;
    77.                 border-bottom:20px solid green;
    78.                 border-left:20px solid green;
    79.                 -webkit-transform: rotate(225deg);
    80.             }
    81.         }
    复制代码

    可以看到,其实就是多了一些改变不同边框颜色的动画而已,这个就给大家自己去实践吧!主要还是利用两个矩形来完成这么一个圆形进度条效果,特别注意overflow这条规则,起着关键作用。


    学习心情好,签到少不了。
    avatar
  • TA的每日心情
    qdsmile开心
    2019-1-3 10:34
  • 签到天数: 4 天

    [LV.2]小吧熟人

    0

    主题

    0

    帖子

    79

    积分

    发表于 2019-1-1 16:41:28 | 显示全部楼层
    5641564456654
    您需要登录后才可以回帖 登录 | 立即注册 QQ登录

    本版积分规则