小程序canvas画环形百分比进度图

组件封装

component/canvas-ring目录下

canvas-ring.js

html 复制代码
<canvas style="width:{{canvasWidth}}px;height:{{canvasWidth}}px; margin:0 auto;position:relative" type="2d" id="myCanvas">
  <view class="circle-bar" style="height:{{canvasWidth}}px;">

    <view class="title_val" style="color: {{valueColor}}; font-weight:{{f_weight}}; margin-top:{{show_tip?'10':'0'}}rpx;font-size:{{f_size}}px">
      {{value}}
      <p style="font-size: 10px;display: inline;">
        {{suffix}}
      </p>
    </view>
    <view class="title_name" style="color: {{lineColor}};">
      {{title}}
    </view>
  </view>
</canvas>
canvas-ring.json
json 复制代码
{
  "component": true,
  "usingComponents": {} 
 }
canvas-ring.wxss
css 复制代码
.circle-bar{
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  position: absolute;
  top: 0;
}
.circle-bar .title_name{
  max-height: 62rpx;
  font-size: 26rpx;
  overflow:hidden;
  text-overflow:ellipsis;
  display:-webkit-box;
  -webkit-box-orient:vertical;
  -webkit-line-clamp:2;
}
.circle-bar .title_val{
  color: #333333;
}
canvas-ring.js
javascript 复制代码
var windWidth = wx.getSystemInfoSync().windowWidth; //这里获取下设备的屏幕宽度

Component({

  /**
   * 组件的属性列表
   */

  properties: {
    //画布的宽度 默认占屏幕宽度的0.4倍
    canvasWidth: {
      type: Number,
      value: windWidth * 0.4
    },
    //线条宽度 默认10
    lineWidth: {
      type: Number,
      value: 10
    },
    //线条颜色
    lineColor: {
      type: String,
      value: "#3696FA"
    },
    //标题 默认"完成率"
    title: {
      type: String,
      value: "完成率"
    },
    //当前的值 默认45
    value: {
      type: Number,
      value: 50
    },
    //值的颜色 默认""
    valueColor: {
      type: String,
      value: "#333"
    },
    //值的字体的大小颜色 默认
    f_size: {
      type: Number,
      value: 14
    },
    f_weight: {
      type: String,
      value: "500"
    },
    //最大值 默认100
    maxValue: {
      type: Number,
      value: 100
    },
    //最小值 默认0
    minValue: {
      type: Number,
      value: 0
    },
    //当前值的后缀名
    suffix: {
      type: null,
      value: "%"
    },
    //从什么角度开始 0~360之间 (12点方向为0,18点方向为180,0点方向为360)
    startDegree: {
      type: Number,
      value: 0
    }
  },
  data: {
    canvasWidth: windWidth * 0.4, //默认创建的环形图宽度为屏幕宽度的40%
    show_tip: true
  },
  methods: {
    drawCanvasRing() {

      //没标题的时候去掉margin-top的值
      if (this.data.title.replace(/(^\s*)|(\s*$)/g, "").length == 0) {
        this.setData({
          show_tip: false
        })
      }
      //canvas 2d
      const query = wx.createSelectorQuery().in(this);
      query.select("#myCanvas")
        .fields({
          node: true,
          size: true
        })
        .exec(this.init.bind(this))
    },
    init(res) {
      const canvas = res[0].node
      const ctx = canvas.getContext("2d");
      canvas.requestAnimationFrame(() => {})
      const dpr = wx.getSystemInfoSync().pixelRatio
      canvas.width = res[0].width * dpr
      canvas.height = res[0].height * dpr
      ctx.scale(dpr, dpr);
      // 大小值的计算
      var circle_r = this.data.canvasWidth / 2; //画布的一半,用来找中心点和半径
      var startDegree = this.data.startDegree; //从什么角度开始
      var maxValue = this.data.maxValue; //最大值
      var minValue = this.data.minValue; //最小值
      var value = this.data.value; //当前的值
      var lineColor = this.data.lineColor; //线条颜色
      var lineWidth = this.data.lineWidth; //线条宽度
      var percent = 360 * ((value - minValue) / (maxValue - minValue)); //计算结果
      //定义起始点
      ctx.translate(circle_r, circle_r);
      //灰色圆弧
      ctx.beginPath();
      ctx.strokeStyle = "#ebebeb";
      ctx.lineWidth = lineWidth;
      ctx.arc(0, 0, circle_r - 10, 0, 2 * Math.PI, true);
      ctx.stroke();
      ctx.closePath();
      //有色彩的圆弧
      ctx.beginPath();
      ctx.strokeStyle = lineColor;
      ctx.lineWidth = lineWidth;
      ctx.arc(0, 0, circle_r - 10, startDegree * Math.PI / 180 - 0.5 * Math.PI, percent * Math.PI / 180 + startDegree * Math.PI / 180 - 0.5 * Math.PI, false);
      ctx.stroke();
      ctx.closePath();
      console.log(this.data.value);
    }
  }
})

使用

父页面

canvas.js
javascript 复制代码
  /**
   * 页面的初始数据
   */
  data: {
    completePercent: 10, //圆环A的动态值
    completePercent2: 60 //圆环B的动态值
  },
javascript 复制代码
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: async function (options) {
    await tools.request('/main/mainTest', {
      id: 1,
    }, 'get').then((res) => {
      if (res.data.code == 1) {
        this.setData({
          completePercent: res.data.data.score.before,
          completePercent2: res.data.data.score.finish,
        })
      } else {
        wx.showToast({
          title: res.data.msg,
          icon: 'none',
        })
      }
    })

await    this.getRingsA();
await    this.getRingsB();
  },

方法

javascript 复制代码
  getRingsA() {
    this.canvasRing = this.selectComponent("#canringA");
    this.canvasRing.drawCanvasRing() //绘制圆环A
  },
  getRingsB() {
    this.canvasRing2 = this.selectComponent("#canringB");
    this.canvasRing2.drawCanvasRing() //绘制圆环B
  },
canvas.wxml
html 复制代码
 <canvas2d-ring type="2d" id="canringA" canvasWidth="{{120}}" f_weight="bold" value="{{completePercent}}" lineColor="#EA0000" f_size="21" lineWidth="{{10}}" title="{{'施工前'}}"></canvas2d-ring>
canvas.json
json 复制代码
{  
  "navigationStyle":"custom",
  "component": true,
  "usingComponents": {
    "canvas2d-ring": "/component/canvas-ring/canvas-ring"
  }
}
相关推荐
说私域3 分钟前
关键客户转化为会员的重要性及 “开源 AI 智能名片 2 + 1 链动模式商城小程序” 在其中的应用剖析
人工智能·小程序
ai安歌1 小时前
【微信小程序】微信小程序中的异步函数是如何实现同步功能的
微信小程序·小程序·同步·异步
weixin_482565531 小时前
Android IC读写器安卓小程序 3
android·小程序
guanpinkeji5 小时前
旧衣回收小程序开发,绿色生活,便捷回收
小程序·生活·小程序开发·小程序制作·回收小程序·回收·旧衣回收
jiejianyun8576 小时前
上门回收小程序如何搭建?有个小程序收破烂也要高端?
服务器·小程序·apache
Polaris_YJH6 小时前
简单讲解关于微信小程序调整 miniprogram 后, tabbar 找不到图片的原因之一
微信小程序·小程序·notepad++·tabbar图片路径
然后就去远行吧6 小时前
小程序基础 —— 07 创建小程序项目
小程序
kaoyaoyao16 小时前
小程序评论分数提高,提升用户参与感和忠诚度
大数据·小程序·seo·评论·小程序评分
V+zmm1013420 小时前
社区二手物品交易小程序ssm+论文源码调试讲解
java·微信小程序·小程序·毕业设计·ssm