一个显示图标加载进度的镂空饼图(canvas)

ui的设计是这样的:
一个显示图标加载进度的镂空饼图(canvas)_第1张图片
使用场景是在手机app里面加载某些模块时,显示加载进度。
思路比较简单直接见代码注释吧:

interface Params {
  /** canvas dom */
  dom: any,
  /** 颜色 */
  color: string,
  size?: number,
  callback?: Function
  /**表示进度的圆半径(比例) */
  opaqueRate?: number
  /** 挖空的圆半径(比例) */
  excavatedRate?: number
}

/**
 * 显示进度的饼图
 */
const appDownloadRate = (params: Params) => {
  const { dom, color, size, callback, opaqueRate = 0.35, excavatedRate = 0.40 } = params;
  const canvas = dom;

  const L = size || dom.offsetWidth;
  const l_moiety = L / 2;

  return {
    setRate(value: number) {
      canvas.width = L
      canvas.height = L
      const ctx = canvas.getContext("2d");
      ctx.fillStyle = color;
      // 设置坐标零点
      ctx.translate(l_moiety, l_moiety);
      // 先画一个剔除圆的矩形填充
      ctx.beginPath()
      ctx.arc(0, 0, L * excavatedRate, 90 * Math.PI / 180, 450 * Math.PI / 180);
      ctx.lineTo(0, l_moiety)
      ctx.lineTo(l_moiety, l_moiety)
      ctx.lineTo(l_moiety, -l_moiety)
      ctx.lineTo(-l_moiety, -l_moiety)
      ctx.lineTo(-l_moiety, l_moiety)
      ctx.lineTo(0, l_moiety)
      ctx.closePath()
      ctx.fill()

      // 再画一个饼图 表示进度(顺时针)
      ctx.beginPath()
      ctx.moveTo(0, 0);
      // 逆时针旋转90度
      ctx.rotate(-90 * Math.PI / 180)
      // 左右镜像
      ctx.scale(1, -1)
      ctx.arc(0, 0, L * opaqueRate, 0, ((100 - value) * 3.6) * Math.PI / 180);
      ctx.closePath()
      ctx.fill();

      if (value === 100) {
        this.done()
      }
    },

    done() {
      setTimeout(() => { canvas.style.display = 'none' }, 200)
      if (callback) callback()
    }
  }
}

显示效果:
一个显示图标加载进度的镂空饼图(canvas)_第2张图片

你可能感兴趣的:(javascript)