【实例】Canvas之环形进度条

1,249 阅读1分钟

实现样例

shizhong.gif

完成代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    canvas{
      border:1px solid #000;
    }
  </style>
</head>
<body>
  <canvas id="myCanvas" width="800" height="600"></canvas>
  <script>
    let canvas = document.getElementById('myCanvas')
    let ctx = canvas.getContext('2d')
    let w = canvas.width , h = canvas.height
    const step = 0.2
    function print(ctx,lineWidth,x,y,r,colors,deg){
      let startAngle = 0 
      let endAngle = 2 * Math.PI  * deg


      ctx.lineWidth = 10
      ctx.lineCap = 'round'

      let stepTime = (endAngle - startAngle) / step

      let colorObj = getStepColor(colors,stepTime)
      let startColor = colors[0]
      let startRGB = colorRgb(colors[0])
      let endRGB = colorRgb(colors[1])
      // 循环次数
      for(let i=1;i<=stepTime;i++){
        ctx.beginPath()
        let color = `rgb(${parseInt(startRGB[0] + i * colorObj.colorR)},${parseInt(startRGB[1] + i * colorObj.colorG)},${parseInt(startRGB[2] + i * colorObj.colorB)})`
        ctx.strokeStyle = color
        ctx.arc(x,y,r,startAngle,startAngle + step,false)
        ctx.stroke()
        startAngle += step
      }
    }

    // 生成每个颜色的间隔
    function getStepColor(colors,step){
      if(colors && !colors.length){
        return false
      }
      if(step == 0){
        return false
      }
      let startColor = colors[0]
      let endColor = colors[1]

      let startColor_rgb = colorRgb(startColor)
      let endColor_rgb = colorRgb(endColor)
      let colorR = (endColor_rgb[0] - startColor_rgb[0]) ? (endColor_rgb[0] - startColor_rgb[0]) / step : 0
      let colorG = (endColor_rgb[1] - startColor_rgb[1]) ? (endColor_rgb[1] - startColor_rgb[1]) / step : 0
      let colorB = (endColor_rgb[2] - startColor_rgb[2]) ? (endColor_rgb[2] - startColor_rgb[2]) / step : 0
      return {step,colorR,colorG,colorB}
    }
    
    //将16进制转换成10进制的rgb
    function colorRgb(color){
      let colors = []
      for(let i=1 ;i<7;i+=2){
        colors.push(
          parseInt(`0x${color.slice(i,i+2)}`)
        )
      }
      return colors
    }
    
    let a  = 0.1
    let start = 0 , end = 1
    ctx.translate(w/2,h/2)
    ctx.rotate(-90 * Math.PI / 180)
    
    function move(){
      window.requestAnimationFrame(move)
      ctx.clearRect(0,0,w,h)
      let v = (end - start) * a
      start += v
      if(start >= 0.999){
        start = 1
      }
      print(ctx,20,0,0,100,['#ff6464','#3586ff'], start)
    }
    move()
  </script>
</body>
</html>

步骤:

  • 完成圆弧上渐变色
    • 主要是每一小段圆弧上对应一个颜色
  • 完成缓动动画
    • 主要是每次移动的距离是开始结束差值的十分之一