小程序canvas 2d支持同层渲染,绘制环形进度条,可全环,可半环

小程序canvas2d

1.首先因为最初绘制环形使用的是小程序canvas, wx.createCanvasContext,但是由于canvas不支持同层渲染层级过高,并且wx.createCanvasContext已停用。所以更改为type=2d,wx.createSelectorQuery()来绘制环形进度条

此外:canvas2d真机同层渲染才生效,微信开发工具有问题

如图所示:在这里插入图片描述

(1):wxml,wxss内容

<canvas style="width:{{canvasWidth}}rpx;height:{{canvasWidth}}rpx; position:relative" type="2d"  id="myCanvas" >
  <view class="circle-bar" style="height:{{canvasWidth}}rpx;">
    <view class="title_name" style="color: {{valueColor}}; ">
      {{title}}
    </view>
    <view class="title_val" style="color: {{valueColor}}; font-weight:{{f_weight}}; font-size:{{f_size}}rpx">
      {{value}} {{suffix}}
    </view>
  </view>
</canvas>

//wxss内容
.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;
}


js内容

var windWidth = wx.getSystemInfoSync().windowWidth;
//为了适配所有屏幕,这里之前所有像素单位赋值之前都要换成以rpx为单位的大小乘以xs
const xs = windWidth / 750;
Component({
  /**
   * 组件的属性列表
   */
  properties: {
   //画布的宽度 默认占屏幕宽度的0.4倍
    canvasWidth: {
      type: Number,
      value: windWidth * 0.4 *xs
    },
    //线条宽度 默认12,单位rpx
    lineWidth: {
      type: Number,
      value: 8
    },
    //线条颜色
    lineColor: {
      type: String,
      value: "#3696FA"
    },
    //进度条最大值 默认100
    maxValue: {
      type: Number,
      value: 100
    },
    //进度条最小值
    minValue:{
      type: Number,
      value: 0
    },
    //进度条的弧度大小,最小值为0,最大值为1,默认为1代表绘制一个圆的弧度也就是360°
    radian: {
      type: Number,
      value: 3 / 4
    },
    //当前进度值的方向,只在radian为1时起作用,可填left(九点钟方向开始),top(12点钟方向开始),bottom(6点钟方向开始),right(3点钟方向开)
    direction: {
      type: String,
      value: "top"
    },
    //标题
    title: {
      type: String,
      value: "已抢"
    },
    //当前显示的文字值 默认45
    value: {
      type: Number,
      value: 45
    },
    //值的颜色 默认""
    valueColor:{
      type: String,
      value: "#E3AF6A"
    },
    //中间字体大小,单位rpx
    f_size: {
      type: Number,
      value: 30
    },
    //当前值的后缀名
    suffix: {
      type: null,
      value: "%"
    },
    f_weight:{
      type: String,
      value: "500"
    },
  },

  /**
   * 组件的初始数据
   */
  data: {
    canvasWidth:' windWidth * 0.4 * xs',
  },
  // observers 属性,设置需要监听的属性
  observers:{
    'value'(val){
      this.drawCanvasRing();
    },
  },
  lifetimes:{
    attached(){
    }
  },
  /**
   * 组件的方法列表
   */
  methods: {
    drawCanvasRing() {
      //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(()=>{
        // console.log('1111111111111111111111')
      //})
      const dpr = wx.getSystemInfoSync().pixelRatio
	  
	  var radian = this.data.radian//弧度大小
      radian=radian>1?1:radian //控制最大值为1
      radian=radian<0?0:radian //控制最小值为0
 
      canvas.width = res[0].width * dpr
      canvas.height = res[0].height * dpr
      ctx.scale(dpr, dpr);
      
      // 大小值的计算
      var circle_r = this.data.canvasWidth *xs / 2; //画布的一半,用来找中心点和半径
      var maxValue = this.data.maxValue; //最大值
      var minvalue= this.data.minvalue; //当前进度值
      var lineColor = this.data.lineColor; //线条颜色
      var lineWidth = this.data.lineWidth* xs; //线条宽度
	   
	  //计算弧形的起点,这是为了保证起点和终点在同一水平线上
      var startPath = Math.PI * (3 / 2 - radian)
      var endPath = startPath + 2 * Math.PI * radian
	  
      //定义起始点
      ctx.translate(circle_r, circle_r);
      
      //灰色圆弧
      ctx.beginPath();
      ctx.strokeStyle="#ebebeb";
      ctx.lineWidth=lineWidth;
      ctx.arc(0, 0, circle_r - lineWidth / 2, startPath, endPath, false);
      ctx.lineCap ="round"  //末端圆弧
      ctx.stroke();
      ctx.closePath();
      
	  //计算当前进度弧形大小,环形总长度为Math.PI*2
      var percent = 2 * Math.PI * radian * (minvalue/ maxValue)
      var currStartPath = startPath //当前进度值的起点位置
      //如果radian为1则使用自定义的起始位置
      if (radian == 1) {
        var direction = this.data.direction//当前进度值
        switch (direction) {
          case 'left':
            currStartPath =Math.PI //九点钟方向
            break
          case 'top':
            currStartPath = 3 / 2 * Math.PI //十二点钟方向
            break
          case 'right':
            currStartPath = 0 //三点钟方向
            break
          case 'bottom':
            currStartPath = 1 / 2 * Math.PI //六点钟方向
            break
        }
      }
      
      //有色彩的圆弧      
      ctx.beginPath();
      ctx.strokeStyle=lineColor;
      ctx.lineWidth=lineWidth;
      ctx.arc(0, 0, circle_r - lineWidth / 2, currStartPath, percent + currStartPath, false);
      ctx.lineCap ="round" //末端圆弧
      ctx.stroke();
      ctx.closePath();
    }
  }
})

父组件引用

<mycanvas canvasWidth="{{165}}" maxValue="{{item.kcqty}}" minValue="{{item.sales}}" value="{{(item.sales)/(item.kcqty)*100}}"  lineColor="{{zt_color}}"></mycanvas>
        
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值