zoukankan      html  css  js  c++  java
  • 微信小程序之圆形进度条(自定义组件)

    思路

    1. 使用2个canvas 一个是背景圆环,一个是彩色圆环。
    2. 使用setInterval 让彩色圆环逐步绘制。

     在看我的文章前,必须先看 ,下面转的文章,因为本文是在它们基础上修改的.

    它们的缺点为:

    1.组件必须用js实例化 (如果我有一个任务列表,后面会显示每个任务的进度,每个任务都必须实例化)

    2.它们js实例化时,绘图是用 px绘制,导致页面用rpx布局,组件却用px绘制.

    修改后的组件

    在components文件加下建立  circle组件,如图

    circle.js :

    /* components/circle/circle.js */
    Component({
      options: {
        multipleSlots: true // 在组件定义时的选项中启用多slot支持
      },
      properties: {
        draw: {//画板元素名称id
          type: String,
          value: 'draw'
        },
        per:{ //百分比 通过此值转换成step
          type: String,
          value: '0'
        },
        r:{//半径
          type: String,
          value: '50'   
        }
    
      },
    
      data: { /*  私有数据,可用于模版渲染 */
        step: 1, //用来算圆的弧度0-2
        size:0, //画板大小
        screenWidth:750, //实际设备的宽度
        txt:0
      },
      methods: {
    
        /**
         * el:画圆的元素
         * r:圆的半径
         * w:圆的宽度
         * 功能:画背景
         */
        drawCircleBg: function (el, r, w) {
          const ctx = wx.createCanvasContext(el,this);
          ctx.setLineWidth(w);// 设置圆环的宽度
          ctx.setStrokeStyle('#E5E5E5'); // 设置圆环的颜色
          ctx.setLineCap('round') // 设置圆环端点的形状
          ctx.beginPath();//开始一个新的路径
          ctx.arc(r, r, r - w, 0, 2 * Math.PI, false);
          //设置一个原点(110,110),半径为100的圆的路径到当前路径
          ctx.stroke();//对当前路径进行描边
          ctx.draw();
    
        },
            /**
         * el:画圆的元素
         * r:圆的半径
         * w:圆的宽度
         * step:圆的弧度 (0-2)
         * 功能:彩色圆环
         */
        drawCircle: function (el, r, w, step) {
          var context = wx.createCanvasContext(el,this);
          // 设置渐变
          var gradient = context.createLinearGradient(2 * r, r, 0);
          gradient.addColorStop("0", "#2661DD");
          gradient.addColorStop("0.5", "#40ED94");
          gradient.addColorStop("1.0", "#5956CC");
          context.setLineWidth(w);
          context.setStrokeStyle(gradient);
          context.setLineCap('round')
          context.beginPath();//开始一个新的路径
          // step 从0到2为一周
          context.arc(r, r, r - w, -Math.PI / 2, step * Math.PI - Math.PI / 2, false);
          context.stroke();//对当前路径进行描边
          context.draw()
        }
    
      },
    
      lifetimes: {
        // 生命周期函数,可以为函数,或一个在methods段中定义的方法名
        attached: function () { 
          const _this = this;
          //获取屏幕宽度
          wx.getSystemInfo({
            success: function(res) {
              _this.setData({
                screenWidth: res.windowWidth
              });
            },
          });
    
          //初始化
          const el = _this.data.draw; //画板元素
          const per = _this.data.per; //圆形进度
          const r = Number(_this.data.r); //圆形半径
          
          _this.setData({
            step: (2 * Number(_this.data.per)) / 100,
            txt: _this.data.per
          });
    
    
          //获取屏幕宽度(并把真正的半径px转成rpx)
          let rpx = (_this.data.screenWidth / 750) * r;
          //计算出画板大小
          this.setData({
            size: rpx * 2
          });
          const w = 4;//圆形的宽度
    
          //组件入口,调用下面即可绘制 背景圆环和彩色圆环。
          _this.drawCircleBg(el + 'bg', rpx, w);//绘制 背景圆环
          _this.drawCircle(el, rpx, w, _this.data.step);//绘制 彩色圆环
    
        }
    
      }
    
    
    })

    circle.wxml :

    <!-- components/circle/circle.wxml -->
    <view class="circle_box" style="{{size}}px;height:{{size}}px">
          <canvas class="circle_bg" canvas-id="{{draw}}bg" style="{{size}}px;height:{{size}}px"></canvas> 
          <canvas class="circle_draw" canvas-id="{{draw}}" style="{{size}}px;height:{{size}}px"></canvas> 
          <text class='circle_txt'> {{txt}}%  </text>  
    </view>

    circle.json :

    {
      "component": true,
      "usingComponents": {}
    }

    circle.wxss :

    .circle_box,.circle_draw{ position: relative; }
    .circle_bg{position: absolute;}
    .circle_box{
      display: flex;
      flex-direction: row;
      justify-content: center;
      align-items: center;
    }
    .circle_txt{
      position: absolute;
      font-size: 28rpx;
    }

    调用 :

    在所需页面的XXX.json 先引入 组件

    {
      "usingComponents": {
        "circle": "/components/circle/circle"
      }
    }

    wxml 使用组件

    <circle draw='circwewle1' per = '40' r = '50'/>
    <circle draw='circwewle2' per = '10' r = '30'/>
    <circle draw='circwewle3' per = '20' r = '100'/>
    <circle draw='circwewle' per = '50' r = '60'/>
    <circle draw='circwewle' per = '90' r = '120'/>
    draw : 确定 canvas的id
    per : 进度百分比 (1-100)
    r: 圆的半径 (按px,最终转化成rpx)

     结果:

     

    转 : 

    https://segmentfault.com/a/1190000013219501

    https://segmentfault.com/a/1190000013242747?utm_source=tag-newest

    参考微信自定义组件讲解 : https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/

  • 相关阅读:
    ECharts 提供了常规的折线图、柱状图、散点图、饼图、K线图, echarts3+ajax+json+SpringMVC+mybatis
    数据可视化—ECharts图表的应用
    关于老猿Python系列文章发布网址变化的说明
    hitorMiss、hitAndMiss以及MORPH_HITMISS?
    OpenCV图像处理MORPH_HITMISS入门使用理解
    OpenCV击中击不中HMT形态变换最容易理解的解释
    区块链学习7:超级账本项目Fabric中的背书、背书节点、背书策略、背书签名
    Python音视频开发:消除抖音短视频Logo的图形化工具实现
    Python音视频开发:消除抖音短视频Logo和去电视台标
    Python音视频开发:消除抖音短视频Logo的图形化工具实现过程详解
  • 原文地址:https://www.cnblogs.com/fps2tao/p/11102444.html
Copyright © 2011-2022 走看看