在小程序中用canvas画一个仪表盘

本文介绍了一位开发者在微信小程序中遇到的挑战,即如何实现一个类似f2的半圆进度条。由于引入外部组件困难,作者选择使用canvas自行绘制。通过在onReady函数中初始化canvas,设置半径、偏移量和线条样式,动态更新进度并用util.dayForMonth计算当前月份的进度。最后展示了代码实现和效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本意是打算写一个类似f2的半圆进度条,但是感觉小程序中引入太难调了,所以就自己用canvas随便画了一个实现了类似的效果。

最终效果图

在这里插入图片描述

wxml
    <view class="top-box">
      <canvas class="canvas-box" canvas-id='canvas'></canvas>
      <view class="nx" style="left:{{(app.globalData.windowWidth)/2 - 50}}px;top: 140px;">{{nx}}%</view>
    </view>
js
  onReady: function () { 
    this.initCanvas()
  },
  
  initCanvas() {
    let windowsWidth = app.globalData.windowWidth
    let offset =  0.1  // 偏移
    let r = 140  // 半径
    const ctx = wx.createCanvasContext('canvas')
    ctx.arc(windowsWidth / 2, 175, r, Math.PI * 1 - offset, computedC(1))
    ctx.setStrokeStyle('#F8F9FC')
    ctx.setLineCap('round')
    ctx.setLineWidth(10)
    ctx.stroke()
    ctx.draw(true)

    let x = 0
    let ex = util.dayForMonth(new Date())
    let timer = setInterval(()=>{
      const ctxs = wx.createCanvasContext('canvas')  
  
      if(x >= ex){
        clearInterval(timer)
      }
      this.setData({
        nx:(x * 100).toFixed(1)
      })
      ctxs.arc(windowsWidth / 2, 175, r, Math.PI * 1 - offset, computedC(x))
      ctxs.setLineWidth(10)
      ctxs.setLineCap('round')
      ctxs.setStrokeStyle('#07C160')
      ctxs.stroke()
      ctxs.draw(true)
      x += 0.001
    },5)

    const ctxfont = wx.createCanvasContext('canvas')
    ctxfont.setFontSize(20)
    ctxfont.setFillStyle('#fff')
    ctxfont.setTextAlign('center')
    ctxfont.setTextBaseline('middle')
    ctxfont.fillText(`本月进度`, windowsWidth / 2, 110)
    ctxfont.draw(true)

    function computedC(num) {
      return Math.PI * (num + 1) + offset
    }
  },
utils.js
const dayForMonth = date => {
  function $in(array, value) {
    return array.indexOf(value) !== -1
  }

  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const thx = [1, 3, 5, 7, 8, 10, 12]
  const twx = [4, 6, 9, 11]
  if ($in(thx, month)) {
    return (day/31).toFixed(4)
  }
  else if ($in(twx, month)) {
    return (day/30).toFixed(4)
  }
  else{
    if(year%4 === 0){
      return (day/29).toFixed(4)
    }else{
      return (day/28).toFixed(4)
    }
  }
}
wxss
.top-box{
  display: flex;
  margin: 0 auto;
  border-radius: 1%;
  color: #fff;
  width: 100vw;
  height: 220px;
  background-image: linear-gradient(#FF8B00, #FFCE00);
}

.canvas-box{
  display: flex;
  margin: 0 auto;
  width: 100%;
  height: 220px;
}

.nx{
  position: absolute;
  width: 100px;
  text-align: center;
  color: #fff;
  font-size: 40px;
  font-family: bold;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值