小程序画布使用

最近开发了一款自己的小程序,名字叫做哎呦天气,在这个小程序中有两处使用到了画布canvas,所以在此总结一下。首先看一下我用canvas做的两个效果:

第一张截屏中的折线图和第二张截屏中的带有二维码的图片都是使用canvas生成。

OK,开始使用canvas,我们先从简单的做起,先画出带有二维码、地址、温度、背景图的这个图片:

首先生成一个CanvasContext:

const ctx = wx.createCanvasContext('qrCanvas')

那字符串qrCanvas是怎么来的呢,其实是在wxml文件中定义的:

 <canvas hidden='{{canvasHide}}' style="width: 100%; height: 300px; background-color:#ddd" canvas-id="qrCanvas"></canvas> 

可以看到canvas-id就为qrCanvas.

得到CanvasContext之后呢,我们先画背景图,就是那张漂亮的风景图,主要代码如下:

let width = systemInfo.windowWidth
let height = 300
ctx.drawImage(bgPicturePath, 0, 0, width, height)

重点代码为ctx.drawImage,它有五个参数,第一个背景图地址(必须为本地地址,网络地址不可以),第二个和第三个为起点坐标,第四个和第五个为图片的宽高。

下面我们画一个白色的长方形,位于背景图的下面,里面有二维码图片等:

    ctx.setFillStyle('white')//填充白色
    ctx.fillRect(0, height - 60, width, 60)//坐标x:0,y:height-60 宽高。。。

然后吧二维码在画上去:

 ctx.drawImage(qrPicturePath, 5, height - 57, 55, 55)

下面我们就开始画文字了,

    ctx.moveTo(width / 2, 20)//画笔移动到垂直居中位置(高度20不重要,我随便写的)
    ctx.setTextAlign('center')//设置文字要垂直居中

    ctx.setFillStyle('#333')//字体颜色
    ctx.setFontSize(15)//字体大小
    ctx.fillText("哎呦天气,不错哦!", width / 2, height - 25)//字体内容和位置

然后画地址、温度、风向等:

    ctx.setFillStyle('white')
    //地址
    ctx.setFontSize(13)
    ctx.fillText('上海', width / 2, 30)
    //温度
    ctx.setFontSize(50)
    ctx.fillText(currentTmp, width / 2, 120)
    //天气
    ctx.setFontSize(15)
    ctx.fillText(cond, width / 2, 160)
    //风向
    ctx.setFontSize(15)
    ctx.fillText(wind, width / 2, 190)

最后呢,调用

 ctx.draw()

就可以展示在Page上了,那怎么保存成一张图片呢:

      wx.canvasToTempFilePath({
        canvasId: 'qrCanvas',
        success: function (res) {
          console.log(res)
          wx.hideLoading()
          wx.previewImage({
            urls: [res.tempFilePath]
          })
        }
      })

下面的方法就是把画布生成图片并预览。

OK 下面介绍温度折线图的制作,直接上代码吧:

wxml中:

   <canvas class='forecast_canvas' canvas-id="forcastCanvas">
    </canvas> 

js中:

function drawForecastView(forecast){//参数forecast为数据模型
  const forecastCtx = wx.createCanvasContext('forcastCanvas')
  console.log("forecastWeather", forecast)
  let width = systemInfo.windowWidth
  let height = 130
  let dot = width / 12
  let maxTmp = parseInt(forecast[0].tmp_max) 
  let minTmp = parseInt(forecast[0].tmp_min) 
  forecast.forEach((item)=>{
    if (maxTmp < parseInt(item.tmp_max)){
      maxTmp = parseInt(item.tmp_max)
    }
    if (minTmp > parseInt(item.tmp_min)) {
      minTmp = parseInt(item.tmp_min)
    }
  })
  let average = (minTmp + maxTmp) / 2 //此温度在height/2的位置
 
  let dValue = maxTmp - average
  let gradient = 4;
  while (gradient * dValue > height / 2 - 30){
    gradient = gradient - 0.5
  }
  console.log('倍数', gradient)
  let flag = 1
  forecastCtx.beginPath()
  //最高温度
  forecast.forEach((item)=>{
    let x1 = flag * dot;
    let y1 = height / 2 - (parseInt(item.tmp_max) - average) * gradient
    item.maxX = x1
    item.maxY = y1
    //画线
    if (flag == 1){
      forecastCtx.moveTo(x1, y1)
    }else{
      forecastCtx.lineTo(x1, y1)
    }
    //画圆圈
    forecastCtx.arc(x1, y1, 3, 0, 2 * Math.PI)
    flag = flag + 2
  })

  forecastCtx.setStrokeStyle("#FF8C00");
  forecastCtx.stroke()
  //最低温度
  forecastCtx.beginPath()
  flag = 1
  forecast.forEach((item) => {
    let x2 = flag * dot;
    let y2 = height / 2 + (average - parseInt(item.tmp_min)) * gradient
    item.minX = x2
    item.minY = y2
    //画线
    if (flag == 1) {
      forecastCtx.moveTo(x2, y2)
    } else {
      forecastCtx.lineTo(x2, y2)
    }
    //画圆圈
    forecastCtx.arc(x2, y2, 3, 0, 2 * Math.PI)
    flag = flag + 2
  })
  forecastCtx.setStrokeStyle("#7cb5ec");
  forecastCtx.stroke()
  console.log(forecast)
  forecastCtx.setFontSize(12)
  forecastCtx.setTextAlign('center')
  //画文字
  for (var i = 0; i < forecast.length; i++) {
    forecastCtx.moveTo(forecast[i].maxX, 20)
    forecastCtx.fillText(" " + forecast[i].tmp_max + "°", forecast[i].maxX, forecast[i].maxY - 10)
    forecastCtx.fillText(" " + forecast[i].tmp_min + "°", forecast[i].minX, forecast[i].minY + 20)
  }
  forecastCtx.draw()
}

最后呢附上我的小程序的二维码:

 

 
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值