美文网首页Web 前端开发
一步一步去实现一个环形进度条

一步一步去实现一个环形进度条

作者: cb12hx | 来源:发表于2017-12-31 23:34 被阅读0次

    有这么个环形进度条,应该怎么去实现呢


    image.png

    从结构来看,需要一根背景线,一个进度线,一个百分比进度条,ok,一步步来看怎么实现

    1.画背景线

    这个比较简单,直接arc一下, 然后stroke一下即可,看看代码

      var c1 = document.querySelector('#c1')
      var ctx = c1.getContext('2d')
      ctx.translate(c1.width / 2, c1.height / 2)
      ctx.arc(0, 0, 100, 0, Math.PI * 2)
      ctx.lineWidth = 5
      ctx.stroke()
      ctx.beginPath()
    

    translate将画笔放到canvas的中心,然后画一个圆,设置线的宽度为5,然后进行描边,之后开启一段新路径

    2.画百分比进度条

    其实这个也比较简单,只需要设置一下进度条的宽度,颜色,和圆弧的长度即可

      ctx.arc(0,0,100,0,60*Math.PI/180)
      ctx.lineWidth=10
      ctx.strokeStyle = 'red'
      ctx.stroke()
    

    这段代码画了一条圆弧,长度为60度的角对应的弧长,设置弧宽为10,设置弧的颜色为红色,然后开始描边,看看效果


    image.png

    可以看出,一般情况下,我们需要弧的起点终点是圆的,这里用到了一个api,lineCap,它有三个取值

    ctx.lineCap = "butt";
    ctx.lineCap = "round";
    ctx.lineCap = "square";
    

    具体的请参阅这里,此处我们去round

    image.png

    3.画中间的百分比

    这个也比较简单,先来看看代码

      ctx.beginPath()
      ctx.font = '30px Arial'
      ctx.fillText(parseFloat((60 / 360) * 100).toPrecision(2) + '%', -20, 10)
    

    效果如下


    image.png

    这样的基本的环形百分比就画好了,注意设置font时,要同时传font-size和font-family,不然没有效果

    4.添加动画

    js中使用动画可以有setTimeout,setInterval,requestAnimationFrame,demo中用到的是第三个,因为它会自动的去算1000中执行多少帧,从而能够平滑地做动画;这里要注意的一点就是,画进度时,要先使用clearRect去除上一次的进度,不然会有一坨数字叠加。这里跟canvas的关系不大,就不一句一句解释了,贴出全部代码吧,直接保存为html即可看到具体效果

    <html>
    
    <head>
      <meta charset="utf-8">
      <title>文档标题</title>
      <!-- 开启响应式 -->
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <!-- SEO页面关键词 -->
      <meta name="keywords" content="your keywords">
      <!-- SEO页面描述 -->
      <meta name="description" content="your description">
      <style>
      * {
        margin: 0;
        padding: 0;
      }
    
      #c1 {
        display: block;
        margin: 10px auto;
        border: 1px solid red;
        width: 300;
        height: 300;
      }
      </style>
    </head>
    
    <body>
      <canvas width="600" height="600" id="c1"></canvas>
      <script type="text/javascript">
      var c1 = document.querySelector('#c1')
      var ctx = c1.getContext('2d')
      ctx.translate(c1.width / 2, c1.height / 2)
      ctx.arc(0, 0, 100, 0, Math.PI * 2)
      ctx.lineWidth = 5
      ctx.stroke()
      ctx.beginPath()
    
      var currentAngle = 0
      var currentProcess = 0
      var currentPercentage = 0
    
      function process(endAngle) {
        var step = Math.PI / 60
        if (currentAngle + step > endAngle) {
          currentAngle = endAngle
        } else {
          currentAngle += step
        }
        ctx.beginPath()
        ctx.arc(0, 0, 100, 0, currentAngle)
        ctx.lineCap = 'round'
        var lingrad = ctx.createLinearGradient(0, 0, 0, 150);
        lingrad.addColorStop(0, '#f00');
        lingrad.addColorStop(1, '#ff0');
        ctx.lineWidth = 20
        ctx.strokeStyle = lingrad
        ctx.stroke()
        ctx.beginPath()
    
        currentProcess = (parseFloat(currentAngle / endAngle) * 100).F(2)
        ctx.clearRect(-50, -50, 120, 100)
        ctx.font = '30px Arial'
        ctx.fillText((parseFloat(+currentAngle / (Math.PI * 2))*100).toPrecision(2) + '%', -30, 5)
        if (currentAngle >= endAngle) {
          currentProcess = 1
          currentAngle = endAngle
          return
        }
        requestAnimationFrame(() => {
          process(endAngle)
        }, 100)
      }
      process(Math.PI * 1 / 3)
      </script>
    </body>
    
    </html>
    

    相关文章

      网友评论

        本文标题:一步一步去实现一个环形进度条

        本文链接:https://www.haomeiwen.com/subject/dahzgxtx.html