微信小程序 canvas 环形刻度 进度条

(本仙女的第一篇文章,感谢支持)
最近做小程序需要一个环形刻度条,发现有关微信小程序的类似文章很少,目前只找到了一个关于H5的canvas绘制刻度条和我需求是一样的,于是自己改了改。
话不多说,开始吧。。。


效果图

1、首先在wxml上创建一个画布

<view class="container">
    <canvas canvas-id="firstCanvas" type="2d" id="firstCanvas" style="width:200px;height:200px;display:block;"></canvas>
    <view class="percentage">{{process}}%</view>
</view>

2、在js中创建画布,获取节点信息。

小程序 获取节点信息 的文档地址:
https://developers.weixin.qq.com/miniprogram/dev/api/wxml/wx.createSelectorQuery.html

  const query = wx.createSelectorQuery()
    query.select('#firstCanvas')
     .fields({
        node: true,
        size: true
      })
      .exec((res) => {
        const canvas = res[0].node
        ctx = canvas.getContext('2d')
      })

3、绘制刻度线。

    obj = {
          width: 300,
          height: 300,
          dx: 20, // 刻度宽度
          dy: 4, // 刻度高度
          num: 24, // 刻度条数
          r: 70, // 半径
          start: -90, // 开始角度,与结束角度相对称
          progress: 75, // 显示进度 (单位百分比)
          index: 0, // 开始刻度
          defaultColor: '#dee1e4', // 开始颜色
          activeColor: '#5CCCFF' // 进度条颜色
        };
        obj.deg = (180 - 2 * obj.start) / obj.num;
        canvas.width = obj.width;
        canvas.height = obj.height;

        for (var x = 0; x < obj.num; x++) { //灰色刻度线
          draw(x, obj.defaultColor);
        }

        function draw(x, color) { // 画出环形刻度线
          ctx.save();
          var deg = Math.PI / 180 * (obj.start + obj.deg * x); // 角度换算弧度
          var offsetY = -(Math.sin(deg) * obj.r); // 计算刻度Y轴位置
          var offsetX = -(Math.cos(deg) * obj.r); // 计算刻度X轴位置
          ctx.fillStyle = color;
          ctx.translate(obj.width / 2 - offsetX, obj.height / 2 - offsetY); // 修改画布坐标原点
          ctx.rotate(deg); // 旋转刻度
          ctx.fillRect(0, 0, obj.dx, obj.dy); // 画出刻度
          ctx.restore();
        }

4、实现动画效果。

    function animate(s, time) {
       if (obj.progress == 0) { // 进度为0直接退出函数
         return false;
      }
      draw(s, obj.activeColor);

      var num = obj.progress * (obj.num / 100); //格数计算

      var timmer = setTimeout(function () {
          obj.index = s + 1;

          if (s >= num) {
              clearTimeout(timmer);
            } else {
              if (s > num - 10) { // 剩余10格动画减速
                animate(obj.index, time + 20);
              } else {
                animate(obj.index, time);
              }

            }
          }, time)
     }

附上完整的js代码:

let ctx = null
let obj = {}
Page({
  data: {

  },
  onLoad: function (options) {},
  
  onReady() {
    this.animation()
  },

  animation() {
    const query = wx.createSelectorQuery()
    query.select('#firstCanvas')
      .fields({
        node: true,
        size: true
      })
      .exec((res) => {
        const canvas = res[0].node
        ctx = canvas.getContext('2d')
        obj = {
          width: 300,
          height: 300,
          dx: 20, // 刻度宽度
          dy: 4, // 刻度高度
          num: 24, // 刻度条数
          r: 70, // 半径
          start: -90, // 开始角度,与结束角度相对称
          progress: 75, // 显示进度 (单位百分比)
          index: 0, // 开始刻度
          defaultColor: '#dee1e4', // 开始颜色
          activeColor: '#5CCCFF' // 进度条颜色
        };
        this.setData({
          process: obj.progress
        })
        obj.deg = (180 - 2 * obj.start) / obj.num;
        canvas.width = obj.width;
        canvas.height = obj.height;

        for (var x = 0; x < obj.num; x++) { //灰色刻度线
          draw(x, obj.defaultColor);
        }

        function draw(x, color) { // 画出环形刻度线
          ctx.save();
          var deg = Math.PI / 180 * (obj.start + obj.deg * x); // 角度换算弧度
          var offsetY = -(Math.sin(deg) * obj.r); // 计算刻度Y轴位置
          var offsetX = -(Math.cos(deg) * obj.r); // 计算刻度X轴位置
          ctx.fillStyle = color;
          ctx.translate(obj.width / 2 - offsetX, obj.height / 2 - offsetY); // 修改画布坐标原点
          ctx.rotate(deg); // 旋转刻度
          ctx.fillRect(0, 0, obj.dx, obj.dy); // 画出刻度
          ctx.restore();
        }

        function animate(s, time) {
          if (obj.progress == 0) { // 进度为0直接退出函数
            return false;
          }
          draw(s, obj.activeColor);

          var num = obj.progress * (obj.num / 100); //格数计算

          var timmer = setTimeout(function () {
            obj.index = s + 1;

            if (s >= num) {
              clearTimeout(timmer);
            } else {
              if (s > num - 10) { // 剩余10格动画减速
                animate(obj.index, time + 20);
              } else {
                animate(obj.index, time);
              }

            }
          }, time)
        }
        animate(obj.index, 10)
      })
  }
})

这基本就实现了,这个项目我已经上传到了github上,希望能帮到你们https://github.com/zhangwei727/wx_circular_scaleBar.git

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。