半圆形进度条(小程序)

近期在做一个读书类的小程序,这时需要作出一个半圆形的进度条,等级进度条,就想着用canvas来完成,在网上百度了一下,参阅了这这篇博客博客地址,在结合实际需求加以修改。
在这里插入图片描述
这是ui的图片,一看就能知道这个需要自定义标题栏,然后这是一个长图,标题栏和下面的进度条的背景得分开来。上进度条的代码,
wxml

<view class="progress">
      <canvas canvas-id='bgCanvas' id='canvas-one' class='canvasI' wx:if="{{bgCanvas}}"></canvas>
      <image src="{{bgCanvasImg}}" class='canvasII' wx:else></image>
      <canvas canvas-id="runCanvas" class='canvasII' wx:if="{{runCanvas}}">
      </canvas>
      <image src="{{runCanvasImg}}" class='canvasII' wx:else></image>
    </view>

wxss

.progress {
  width: 90%;
  margin: 0 auto;
  height: 470rpx;
  position: relative;
}

.canvasI {
  width: 470rpx;
  height: 470rpx;
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
  margin: auto auto;
}

.canvasII {
  width: 470rpx;
  height: 470rpx;
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
  margin: auto auto;
}

让这两个canvas重叠在一起
js

const ctx = wx.createCanvasContext("bgCanvas"); //创建一个全局的canvas绘图上下文
const ctx2 = wx.createCanvasContext("runCanvas");
let mytime = "";
let n = 0;
var w = "";
var h = "";

Page({

  /**
   * 页面的初始数据
   */
  data: {
    resurl: app.globalData.resurl,
    percent_30: 30,
    percent_80: 80,
    c_val: 20,
    suffix: 300,
    menuBarHeight: app.globalData.menuBarHeight,
    statusBarHeight: app.globalData.statusBarHeight,
    runCanvas:true,
    bgCanvas:true
  },
  run(e) {
    let that = this;
    let src = that.data.src; //总共需要绘制的弧度
    let allSrc = that.data.allSrc; //每个间隔所需绘制的弧度所占比例
    n++;
    if (src * n > allSrc) {
      console.log('结束');
      clearInterval(mytime); //如果绘制完成,停掉计时器,绘制结束
      n = 0;
      //转化成图片
      wx.canvasToTempFilePath({
        canvasId: 'runCanvas',
        success: function(res) {
          var tempFilePath = res.tempFilePath;
          console.log('图片' + tempFilePath);
          that.setData({
            runCanvas:false,
            runCanvasImg: tempFilePath
          })
          wx.canvasToTempFilePath({
            canvasId: 'bgCanvas',
            success:function(succ){
              that.setData({
                bgCanvas: false,
                bgCanvasImg: succ.tempFilePath
              })
            }
          })
        },
        fail: function(res) {
          console.log(res);
        }
      })
      return;
    }
    let ntitle = that.data.ntitle;
    let score = that.data.score;
    let count = that.data.count;
    let left = that.data.left;
    let utitle = that.data.utitle;
    ctx2.arc(w, h, w - 8, 0.93 * Math.PI, (0.93 + src * n) * Math.PI); //每个间隔绘制的弧度
    ctx2.setStrokeStyle("#27C761");
    ctx2.setLineWidth("8");
    ctx2.setLineCap("round");
    ctx2.stroke();
    ctx2.beginPath();
    ctx2.setFontSize(24);
    ctx2.setFillStyle("#27c761");
    ctx2.fillText(ntitle, 95, 60);
    ctx2.setFontSize(15);
    ctx2.setFillStyle("#27c761");
    ctx2.fillText(score, 85, 85);
    ctx2.setFillStyle("#fff");
    if (count == -1) {
      ctx2.fillText('/ ∞', 110, 85);
      ctx2.setFontSize(12);
      ctx2.fillText('你已经是最高等级' + ntitle, 55, 120);
    } else {
      ctx2.fillText('/ ' + count, 110, 85);
      ctx2.setFontSize(12);
      ctx2.fillText('只需' + left + '点积分即可升级为' + utitle, 30, 120);

    }
    ctx2.draw();


  },
  canvasTap() {
    let that = this;
    clearInterval(mytime);
    mytime = setInterval(that.run, 5)
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {
    let that = this;

    getLevel({
      op: 'grade'
    }, function(res) {
      let allSrc = res.myself.score / res.myself.count;//计算需要绘制的比例
      let count = res.myself.count;//最大的比例
      let src = allSrc / 100
      if (count == -1) src = 1;
      that.setData({
        ntitle: res.myself.ntitle,
        score: res.myself.score,
        count: count,
        left: res.myself.left,
        utitle: res.myself.utitle,
        src: src,
        allSrc: allSrc,
        upgradeList: res.grade,
        myself: res.myself,
        explain: res.explain,
      })

      that.canvasTap();
    });

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function() {
    var context = wx.createCanvasContext('firstCanvas')
    context.draw();
    wx.createSelectorQuery().select('#canvas-one').boundingClientRect(function(rect) { //监听canvas的宽高
      //获取canvas宽的的一半
      w = parseInt(rect.width / 2);
      //获取canvas高的一半,
      h = parseInt(rect.height / 2);
      //获取宽高的一半是为了便于找到中心点

      ctx.arc(w, h, w - 8, 0.93 * Math.PI, 2.08 * Math.PI); //绘制圆形弧线
      ctx.setStrokeStyle("#dddddd"); //设置填充线条颜色
      ctx.setLineWidth("8");     //设置线条宽度
      ctx.setLineCap("round");        //设置线条端点样式
      ctx.stroke();     //对路径进行描边,也就是绘制线条。

      ctx.draw();       //开始绘制
    }).exec()
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function() {

  },

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

  },

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

  },

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

  },

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


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

  },
 

我这里转换成图片是因为这是一个长图,需要滚动,canvas的层级太高会遮挡标题栏,尝试用cover-view来写标题栏,但是cover-view不能用背景图片,所以把canvas转化成图片就不会被自定义标题栏遮挡了

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值