微信canvas画一个进度条刻度扇形

本文介绍了一种使用微信小程序的canvas组件绘制步数进度扇形的方法。通过双canvas实现,一个用于背景线条,另一个实时更新步数进度。文章详细展示了如何根据步数比例动态调整扇形角度,实现进度显示效果。

在这里插入图片描述

图中的扇形总共需要用到两个canvas

wxml:

<view class="progress">
  <canvas canvas-id="canvasProgress" style="width: {{canvasWidth}}rpx; height: {{canvasHeitht}}rpx;"> </canvas>
</view>
<view class="progress">
  <canvas canvas-id="canvasProgressReal" style="width: {{canvasWidth}}rpx; height: {{canvasHeitht}}rpx;"> </canvas>
</view>

wxss:


.progress {
  position:absolute;
  z-index: 1;
}

js:

Page({

  /**
   * 页面的初始数据
   */
  data: {
    canvasWidth: 500,
    canvasHeitht: 300,
    radioPos: 98,
    footNum: 0,
    footNumAll: 6000,
    myTargetFoot: 10000,
    degree: 210,
    timer: '',
    timerNum: '',
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {
    var that = this;
    let widthPX = wx.getSystemInfoSync().windowWidth;
    let r = this.data.radioPos = widthPX * (500 / 750) * (300 / 365) * (2 / 4)
    var context = wx.createCanvasContext('canvasProgress')
    context.translate(24, 6);
    context.setStrokeStyle("#fff");
    context.setLineWidth(2);
    context.beginPath();
    for (let i = 210; i >= -30; i -= 3) { //每3度绘制一条线
      let degree = i / 360 * Math.PI * 2
      let radio = r * 0.87 - r * 0.05 * (210 - i) / 240
      context.moveTo(r + radio * Math.cos(degree), r - radio * Math.sin(degree)); //向量加减
      context.lineTo(r + r * Math.cos(degree), r - r * Math.sin(degree)); //向量加减
      context.stroke();
    }
    context.draw();



  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function() {
    let that = this
    //清理
    var context = wx.createCanvasContext('canvasProgressReal')
    context.clearRect(0, 0, this.data.canvasWidth, this.data.canvasHeitht)
    context.draw({
      reserve: true
    })
    that.walkAction()
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function() {

  },
  walkAction: function() {
    console.log('walk')
    this.setData({
      degree: 210
    })
    let that = this
    let r = this.data.radioPos
    let widthPX = wx.getSystemInfoSync().windowWidth;
    var context = wx.createCanvasContext('canvasProgressReal')
    context.clearRect(0, 0, this.data.canvasWidth, this.data.canvasHeitht)
    context.setStrokeStyle("#FDD08F");
    context.translate(24, 6);
    context.setLineWidth(2);
    let degreeMax = 210- (this.data.footNumAll / this.data.myTargetFoot) * 240;
    if (Number.parseInt(this.data.footNumAll) >= Number.parseInt(this.data.myTargetFoot)) {
      console.log('footNumAll is smaller than myTargetFoot')
      degreeMax = -33
    }
    this.timer = setInterval(() => {
      if (that.data.degree > degreeMax) {
        context.beginPath();
        let degreeOne = that.data.degree / 360 * Math.PI * 2
        let radio = r * 0.87 - r * 0.05 * (210 - that.data.degree) / 240
        context.moveTo(r + radio * Math.cos(degreeOne), r - radio * Math.sin(degreeOne));
        context.lineTo(r + r * Math.cos(degreeOne), r - r * Math.sin(degreeOne));
        context.stroke();
        // context.draw({
        //   reserve: true
        // })//这个方法真机上绘制有问题
        wx.drawCanvas({
          canvasId: 'canvasProgressReal',
          actions: context.getActions(),
          reserve: true
        })
        that.data.degree -= 3;
      } else {
        clearInterval(that.timer)
      }
      // }, 50)
    }, 10)
    let tempTimes = 0;
    let times = (this.data.footNumAll / this.data.myTargetFoot) * 240 / 3;
    if (Number.parseInt(this.data.footNumAll) >= Number.parseInt(this.data.myTargetFoot)) {
      times = 80
    }
    let step = this.data.footNumAll / times
    this.timerNum = setInterval(() => {
      if (tempTimes < times) {
        that.setData({
          footNum: Math.floor(that.data.footNum + step)
        })
        tempTimes += 1;
      } else {
        that.setData({
          footNum: that.data.footNumAll
        })
        clearInterval(that.timerNum)
      }
      // }, 50)
    }, 10)
  },
})
### 微信小程序实现环形进度条 #### 使用 Canvas 绘制环形进度条 为了在微信小程序中绘制环形进度条,`<canvas>` 组件是核心工具之一。通过设置 canvas 的宽高属性并调用其上下文对象的方法来完成图形的渲染工作[^2]。 ```html <!-- wxml 文件 --> <view class="progress-container"> <canvas type="2d" id="circle-progress"></canvas> </view> ``` #### 初始化 Canvas 上下文环境 JavaScript 中初始化 canvas 并获取 2D 渲染上下文: ```javascript const ctx = wx.createCanvasContext('circle-progress'); ``` #### 定义绘制函数 编写用于更新和重绘进度条状态的功能逻辑,包括但限于起始角度、结束角度以及线条宽度等参数配置[^4]。 ```javascript function drawCircle(progress) { const centerX = 150; const centerY = 150; const radius = 100; // 设置线的颜色 ctx.setStrokeStyle('#ff7f50'); // 开始路径 ctx.beginPath(); // 计算终止弧度 let endAngle = (progress / 100) * 2 * Math.PI + (-Math.PI / 2); // 描绘圆弧 ctx.arc(centerX, centerY, radius, -Math.PI / 2, endAngle); // 线条粗细 ctx.setLineWidth(20); // 执行描边操作 ctx.stroke(); // 关闭路径 ctx.closePath(); } ``` #### 更新页面数据触发重新绘制 每当需要改变显示的进度数值时,应当同步修改视图层的数据绑定变量,并立即执行一次新的绘制过程以反映最新的视觉变化[^3]。 ```javascript Page({ data: { progress: 0, }, onLoad() {}, onReady() { this.startProgress(); }, startProgress() { let that = this; let currentProgress = that.data.progress; let interval = setInterval(() => { currentProgress += 10; if (currentProgress >= 100) { clearInterval(interval); } else { that.setData({ progress: currentProgress }); // 调用绘制方法 drawCircle(currentProgress); ctx.draw(); // 提交绘制命令到屏幕 } }, 1000); // 每隔一秒增百分之十 } }); ``` 上述代码展示了如何在一个简单的场景里构建具有基本功能性的环形进度指示器。实际应用可能还需要考虑更多因素比如样式美化、响应触摸事件等等[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值