第三章 小程序canvas绘制海报

112 阅读3分钟

前言

根据开发需求,要求绘制一个分享的海报图,并可以进行下载。


一、canvas绘制

1. canvas初始化

canvas在设置css时的宽高就是初始化时js拿到的宽高

	 <canvas class='canvas' type="2d" id="myCanvas"></canvas>
// canvas 绘制
 async drawShareImage() {
  // canvas 初始化
  const query = wx.createSelectorQuery()
  query.select('#myCanvas').fields({
   node: true,
   size: true
  }).exec(async (res) => {
   const canvas = res[0].node // canvas 对象
   this.setData({
    canvas
   })
   const ctx = canvas.getContext('2d') // 渲染上下文

   // Canvas 画布的实际绘制宽高
   const width = res[0].width
   const height = res[0].height

   // 获取canvas的宽高,初始化 canvas的大小
   const dpr = wx.getSystemInfoSync().pixelRatio
   canvas.width = width * dpr
   canvas.height = height * dpr
   ctx.scale(dpr, dpr)
   // 进行绘制
   ctx.fillStyle = '#f4f4f4';
   ctx.fillRect(0, 0, width, height)

	// canvas 绘制多张图片需要将图片的初始化单独封装调用
   const addImage = (src) => {
    return new Promise((resolve, reject) => {
     const img = canvas.createImage()
     img.crossOrigin = 'anonymous'
     img.onload = () => {
      resolve(img)
     }
     img.src = src
    });
   }
   // 下面进行具体的canvas绘制 根据ui设计图绘制
   // 举例上述图片绘制的使用
	  let img = await addImage(Imgsrc)
      ctx.save();
      x = width / 2 - 52
      ctx.drawImage(img, x, y, 104, 17);
      ctx.restore()


   })()
  })
 },

2. 绘制内容

具体的内容绘制需要根据业务需求来实现,这个因人而异

绘制命令

	// 2.进行绘制
	ctx.clearRect(0, 0, width, height)
	// 绘制红色正方形
	ctx.fillStyle = 'rgb(200, 0, 0)';
	ctx.fillRect(10, 10, 50, 50);
	
	// 绘制蓝色半透明正方形
	ctx.fillStyle = 'rgba(0, 0, 200, 0.5)';
	ctx.fillRect(30, 30, 50, 50);
	const image = canvas.createImage()

    // 设置文字样式
    ctx.font = 'normal 10px Arial'
    ctx.fillStyle = '#333'
    ctx.fillText(`${'这里可以是参数'}文字内容`, 80, 60); // 绘制填充文字

绘制海报的背景图

	// 图片对象
	const image = canvas.createImage()
	// 图片加载完成回调
	image.onload = () => {
	  // 缩放图片撑满屏幕
	  const imageWidth = image.width
	  const imageHeight = image.height
	  // 计算缩放比例,使图片的宽度和高度与 canvas 相匹配
	  const scaleX = width / imageWidth
	  const scaleY = height / imageHeight
	  // 将图片绘制到 canvas 上
	  ctx.drawImage(image, 0, 0, imageWidth * scaleX, imageHeight * scaleY)
	}
	// 设置图片src
	image.src = '你们的背景图'

3. 海报下载

海报下载后,需要用户自行分享到朋友圈或者聊天。

我们当时没有找到微信小程序可以直接将图片作为朋友圈发出的办法。

 //获取已绘制好的canvas的临时文件路径---保存图片到相册
 saveImage(e) {
  this.setData({
   btnType: e.currentTarget.dataset.type
  })
  wx.canvasToTempFilePath({
   canvas: this.data.canvas, // 在canvas初始化时保存
   success: (res) => {
    const tempFilePath = res.tempFilePath
    this.setData({
     tempFilePath
    })
    // 判断是否授权保存到相册
    this.checkAuthSetting(tempFilePath)
   },
   fail: (err) => {}
  })
 },
 // 保存图片查看是否有权限进行保存
 checkAuthSetting(tempFilePath) {
  wx.getSetting({
   success: (res) => {
    //是否已授权
    if (res.authSetting['scope.writePhotosAlbum']) { //已授权直接保存
     this.saveImageToPhotosAlbum(tempFilePath)
    } else if (res.authSetting['scope.writePhotosAlbum'] === undefined) { //未授权请求授权
     wx.authorize({
      scope: 'scope.writePhotosAlbum',
      success: () => {
       this.saveImageToPhotosAlbum(tempFilePath) //授权后保存
      },
      fail: () => {
       wx.showToast({
        title: '您没有授权,无法保存到相册',
        icon: 'none'
       })
      }
     })
    } else {  //用户拒绝授权后,无法再直接调起请求授权,需要用户自己去设置
     wx.openSetting({
      success: (res) => {
       if (res.authSetting['scope.writePhotosAlbum']) { //用户设置后保存
        this.saveImageToPhotosAlbum(tempFilePath)
       } else {
        wx.showToast({
         title: '您没有授权,无法保存到相册',
         icon: 'none'
        })
       }
      }
     })
    }
   }
  })
 },
// 保存图片
 saveImageToPhotosAlbum(tempFilePath) {
  wx.saveImageToPhotosAlbum({
   filePath: tempFilePath,
   success: (res) => {
    console.log(res);
    if (this.data.btnType == 'save') {     //提示用户已保存
     wx.showModal({
      content: '图片已保存,分享一下吧!',
      showCancel: false,
      confirmText: '好的',
      confirmColor: '#333',
      success: (res) => {},
      fail: (res) => {}
     })
    }
   },
   fail: () => {}
  })
 }

总结

参考文档

Canvas的基本介绍与使用,图解+案例带你快速上手Canvas

微信官方文档-canvas

微信小程序canvas画图,保存页面为海报

以上是我们绘制canvas的一些需求实现,内容绘制因为需求需要自行探索。