小程序Canvas注意的问题

小程序Canvas注意的问题

前言

当我们要做海报生成、描绘图片后保存这类需求时,往往离不开一个原生组件 —— canvas;但canvas在文档中都是一些常规的操作,所以导致不能满足我们日常所要的需求,当我们实际开发的过程中,就会遇到各种各样的坑,所以我收集了下常见的问题,希望大家可以多多参考!~

1. canvas的异步执行

canvas 中很多 API 都是异步执行,这导致很多问题!
例如:
点击按钮保存图片为什么是空的等等…

  • canvasContext.drawImage 不能直接用网络图片(也不能用Base64),需要用 wx.downloadFile(OBJECT) 下载成功后以 tempFilePath 的形式传给页面,res = {tempFilePath: ‘文件的临时路径’},用这个 tempFilePath 才能画图。
  • wx.downloadFile(OBJECT)异步 执行;
  • wx.getImageInfo(OBJECT)异步 执行;
  • canvasContext.draw 异步

解决办法:

利用判断或者加入定时器同样异步,确保画布生成后再进行保存操作。

2.生成图片时,图片模糊

我们都很容易想到解决方法:
使用wx.canvasToTempFilePath生成图片后用image预览
但使用后会遇到两个问题:

  1. canvas无法使用display:none等方法隐藏(包括隐藏父容器),这会使得生成图片为空
    解决方法:
<canvas class="canvas" canvas-id="invitationImage"></canvas>
<view class="invitation-main">
 <view class="invitation-image">
   <image class="image" src="{{imageUrl}}"></image>
 </view>
 <view class="invitation-operations">
   <view class="operations-item">
     <image src="{{baseUrl}}static/invitation/icon_qx.png"></image>
     <view>取消</view>
   </view>
   <view class="operations-item">
     <image src="{{baseUrl}}static/invitation/icon_wx.png"></image>
     <view>微信好友</view>
   </view>
   <view class="operations-item">
     <image catchtap="saveImage" src="{{baseUrl}}static/invitation/icon_bc.png"></image>
     <view>保存到手机</view>
   </view>
 </view>
</view>
.canvas {
  width: 750px;
  height: 1334px;
}
.invitation-main{
  display: flex;
  align-content: center;
  flex-direction: column;
  justify-content: center;
  height: 100vh;
  background-color: #fff;
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
}

将canvas放在容器外面,容器绝对定位占全屏已达到遮挡目的就行啦~

  1. wx.canvasToTempFilePath时必须draw()完成,否则生成图片也为空
drawImage: function(){
  const ctx = wx.createCanvasContext('invitationImage')
  // ctx.drawImage("/images/invitation/img_fx.png", 0, 0, 262, 466)
  ctx.drawImage("/images/invitation/img_fx.png", 0, 0, 750, 1334)
  ctx.rotate(-5 * Math.PI / 180)
  // ctx.drawImage("/images/invitation/code.png", 92, 253, 57, 57)
  ctx.drawImage("/images/invitation/code.png", 265, 723, 164, 164)
  ctx.draw()
},
getImage: function(){
  let that = this
  console.log("getImage")
  wx.canvasToTempFilePath({
    x: 0,
    y: 0,
    width: 750,
    height: 1334,
    // width: 262,
    // height: 466,
    destWidth: 750,
    destHeight: 1334,
    canvasId: 'invitationImage',
    success(res) {
      console.log("tempFilePath",res.tempFilePath)
      that.setData({
        imageUrl: res.tempFilePath
      })
    },
    fail() {
      console.log("fail")
    }
  })
  console.log("getImageEnd")
},
onLoad: function(options) {
  this.drawImage()
},
onReady: function () {
  let that=this
  setTimeout(function () {
    that.setData({
      isOk: true
    })
    that.getImage()
  }, 2000)
},

在文档加载时drawImage,完成时调用getImage。
注:延时操作确保异步执行,不然会出现时有时无

总结

因为canvas的API方法很多都是异步操作的,所以当我们绘制我们想要的效果后,生成图片一定要加入为异步执行。

欢迎关注我的博客: https://blog.csdn.net/weixin_42323607

github地址: https://github.com/qdheyongjie

多多支持!本人会持续更新哒 ❤️

©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页