Mini Program Canvas Use

Recently I developed a small program of my own called Ouch Weather. In this small program, canvas is used in two places, so I will summarize it here. First look at the two effects I made with canvas:

The line chart in the first screenshot and the picture with the QR code in the second screenshot are generated using canvas.

OK, let's start using canvas, let's start simple, first draw this picture with QR code, address, temperature, and background image:

First generate a CanvasContext:

const ctx = wx.createCanvasContext('qrCanvas')

How did the string qrCanvas come from, it is actually defined in the wxml file:

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

You can see that the canvas-id is qrCanvas.

After getting the CanvasContext, we first draw the background image, which is the beautiful landscape image. The main code is as follows:

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

The key code is ctx.drawImage, which has five parameters, the first background image address (must be a local address, not a network address), the second and third are the starting point coordinates, and the fourth and fifth are The width and height of the image.

Next, we draw a white rectangle below the background image, which contains a QR code image, etc.:

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

Then draw the QR code on it:

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

Now we start to draw the text,

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

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

Then draw the address, temperature, wind direction, etc.:

    
    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)

Finally, call

 ctx.draw()

It can be displayed on the Page, so how to save it as a picture:

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

The following method is to generate a picture of the canvas and preview it.

OK Let's introduce the production of the temperature line chart, let's go directly to the code:

In 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()
}

Finally, attach the QR code of my applet:

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325573022&siteId=291194637