小程序Canvas制作表盘

小程序canvas制作表盘

小程序中使用canvas如何制作表盘呢?刚开始接触小程序canvas的时候,脑袋都大了一圈,实现功能了又太耗性能,优化了性能,功能又出问题了。刚好手上有个实时监测pm2.5的项目,花了点时间把其中的canvas表盘扣出来做了一个组件

实现思路

  1. 画背景
    先画圆(刻度间有间隔)——> 再给每个方位设置上刻度值(坐标点调了半天)

  2. 实现进度动画
    设定区间变更的颜色 ——> 根据开始的值与结束的值开个定时任务,10ms更新一次画布

  3. 动态更新开始的值与结束的值

组件代码详解

实时接收调用组件的数值变化

	//实时接收调用组件的数值变化
  observers: {
    'end': function(end) {
      this.setData({
        count: this.properties.start
      })
      clearInterval(this.data.countTimer)
      this.startProgress(this.properties.start, this.properties.end);
    }
  },

根据pm2.5的值获取颜色跟状态

	//根据pm2.5的值获取颜色跟状态
   	pmtocolor(pm) {
      let color = ""
      let status = ""
      let language = this.properties.language
      if (pm <= 50 && pm >= 0) {
        color = this.data.colors[0]
        status = 0
      } else if (pm <= 100 && pm >= 51) {
        color = this.data.colors[1]
        status = 1
      } else if (pm <= 150 && pm >= 101) {
        color = this.data.colors[2]
        status = 2
      } else if (pm <= 200 && pm >= 151) {
        color = this.data.colors[3]
        status = 3
      } else if (pm <= 300 && pm >= 201) {
        color = this.data.colors[4]
        status = 4
      } else if (pm >= 300) {
        color = this.data.colors[5]
        status = 5
      }
      return [color, status]
    },

绘制表盘背景

    //绘制背景
    drawProgressbg() {
      var context = wx.createCanvasContext('canvasProgressbg', this);
      var start = 0.5 * Math.PI;
      var point = {
        x: this.rpxtopx(this.properties.size / 2 + 25),
        y: this.rpxtopx(this.properties.size / 2 + 25)
      };
      var size = this.rpxtopx(this.properties.size + 50);
      let end = 0;
      var radius = this.rpxtopx(this.properties.size / 2 - this.properties.long);
      for (var i = 1; i < 351; i++) {
        context.beginPath();
        if (i % 2 == 0) {
          end = i / 350 * 2 * Math.PI + 0.5 * Math.PI;
          context.setStrokeStyle('rgba(0,0,0,0)');
          context.setLineWidth(this.properties.long + 2);
        } else {
          end = (i - 0.5) / 350 * 2 * Math.PI + 0.5 * Math.PI;
          context.setStrokeStyle(this.properties.colorBg);
          context.setLineWidth(this.properties.long);
        }
        context.arc(point.x, point.y, radius, start, end, false);
        context.stroke();
        start = end;
      }
      let translates = []
      let rotates = []
      let texts = []
      let device = this.device()
      let system = device.system
      let width = device.width
      translates.push([(size / 229) * 110.5, (size / 229) * 227])
      translates.push([(size / 229) * 41, (size / 229) * 188])
      translates.push([(size / 229) * 11, (size / 229) * 104.5])
      translates.push([(size / 229) * 56, (size / 229) * 28])
      translates.push([(size / 229) * 146.5, (size / 229) * 16])
      translates.push([(size / 229) * 212, (size / 229) * 78.5])
      translates.push([(size / 229) * 203, (size / 229) * 170])
      rotates.push(0 * Math.PI / 180)
      rotates.push(230 * Math.PI / 180)
      rotates.push(282 * Math.PI / 180)
      rotates.push(332 * Math.PI / 180)
      rotates.push(22 * Math.PI / 180)
      rotates.push(78 * Math.PI / 180)
      rotates.push(129 * Math.PI / 180)
      texts.push('0')
      texts.push('50')
      texts.push('100')
      texts.push('150')
      texts.push('200')
      texts.push('250')
      texts.push('300')
      for (let i = 0; i < texts.length; i++) {
        this.addFont(context, translates[i], rotates[i], texts[i])
      }
      context.draw()
    },
    //动态添加字体
    addFont(context, translate, rotate, fillText) {
      context.save()
      context.translate(translate[0], translate[1]);
      context.rotate(rotate);
      context.setFillStyle(this.properties.colorBg);
      context.setFontSize(12);
      context.fillText(fillText, 0, 0);
      context.restore();
    },

绘制表盘进度动画

    /**
     * 画progress进度
     */
    drawCircle(step) {
      // 使用 wx.createContext 获取绘图上下文 context
      var context = wx.createCanvasContext('canvasProgress', this);
      let color = this.pmtocolor(step)[0]
      var start = 0.5 * Math.PI;
      var point = {
        x: this.rpxtopx(this.properties.size / 2 + 25),
        y: this.rpxtopx(this.properties.size / 2 + 25)
      };
      let end = 0;
      var radius = this.rpxtopx(this.properties.size / 2 - this.properties.long);
      for (var i = 1; i < step + 1; i++) {
        context.beginPath();
        if (i % 2 == 0) {
          end = i / 350 * 2 * Math.PI + 0.5 * Math.PI;
          context.setStrokeStyle('rgba(0,0,0,0)');
          context.setLineWidth(this.properties.long + 2);
        } else {
          end = (i - 0.5) / 350 * 2 * Math.PI + 0.5 * Math.PI;
          context.setStrokeStyle(color);
          context.setLineWidth(this.properties.long);
        }
        context.arc(point.x, point.y, radius, start, end, false);
        context.stroke();
        context.save()
        context.restore();
        start = end;
      }
      context.draw();
    },

开始表盘进度动画

    startProgress(start, end) {
      let count = this.data.count
      if (start < end) {
        this.setData({
          index: this.pmtocolor(end)[1],
          color: this.pmtocolor(end)[0],
          countTimer: setInterval(res => {
            if (count < end) {
              this.drawCircle(count)
              if (end - count > 10) {
                count = count + 10;
              } else {
                count = count + 1;
              }
            }
          }, 10)
        })
      } else if (start > end) {
        this.setData({
          color: this.pmtocolor(end)[0],
          index: this.pmtocolor(end)[1],
          countTimer: setInterval(res => {
            if (count > end) {
              this.drawCircle(count)
              if (count - end > 10) {
                count = count - 10;
              } else {
                count = count - 1;
              }
            }
          }, 10)
        })
      }
    }

组件使用方法

1.下载

npm下载插件

 	npm install jox-wxapp --save

git下载

 	git clone https://github.com/jon-son/jox-wxapp.git

2.并将本项目的dist复制进你的项目文件夹根目录
3.页面中调用

demo示例

Alt

结尾

一只小菜鸡,欢迎各位大佬指正,github链接:https://github.com/jon-son/jox-wxapp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值