小程序利用Canvas绘图生成海报排雷经验分享

Posted by Yinode on Saturday, November 9, 2019

TOC

前言

最近小程序搞的比较多,最烦人的就是这个海报生成,踩雷不少,跟大家分享一点经验,也许可以解决你的问题

绘制完成后导出 发现内容缺失

这个第一是 最后调用 draw 的时候必须使用回调函数,第二是光回调还不够,你得再加点延迟,再导出

 // 完成
      ctx.draw(false, () => {
        console.log('drawText')
        setTimeout(() => {
          wx.canvasToTempFilePath({
            x: 0,
            y: 0,
            width: 690,
            height: 1190,
            destWidth: 690 * 2,
            destHeight: 1190 * 2,
            canvasId: 'shareCanvas',
            success: res => {
              callback(res.tempFilePath)
            }
          })
        }, 100)
      })

IOS 下绘制多行文本发现排版错乱

请避免换行符

this.firstCargo.content.replace(/[\r\n]/g, '')

安卓下有几率触发排版错乱

比如说一些字体的颜色一会正常,一会可能是黄色,绿色,他的位置可能也会有问题,甚至同一行字能在不同地方以不同样式出现两次

这个问题查了一下,貌似无解,安卓特有,目前微信还没解决

在线图片无法绘制

请使用微信的 API 获取图片缓存到本地之后再绘制,记得图片的域名要在微信的合法域名里面配置,放到 download 下

const promisify = api => {
  return (options, ...params) => {
    return new Promise((resolve, reject) => {
      const extras = {
       success: resolve,
        fail: resolve,
        complate: resolve
      }
      api({ ...options, ...extras }, ...params)
    })
  }
}

const wxGetImageInfo = promisify(wx.getImageInfo)

Promise.all([
    wxGetImageInfo({
      src: "某个在线地址"
    })
]).then(images=>{
// 获取到图片之后再进行绘制
  ctx.drawImage(images[0].path, 96, 1050, 120, 120)
})

某些本地图片 drawImage 无法绘制

这个也是毒的不行,我的解决方法是,把绘制图片的代码从 A 拷贝到 B 然后从 B 拷贝到 A, 结果就好了!!!。至今没明白咋回事

小程序 动态生成二维码 Scene 参数编解码工具函数

适用于小程序动态生成二维码的时候,scene 参数的诸多限制,可以避免 HTTP query 参数本身的干扰和微信的限制,能够存放 KV 对

scene 最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)

const encodeScene = obj => {
  let keys = Object.keys(obj)

  let res = []

  for (let key of keys) {
    res.push(key)
    res.push('_')
    res.push(obj[key] || '')
    res.push('__')
  }
  res.pop()
  return res.join('')
}

const decodeScene = str => {
  let res = {}
  let kvList = str.split('__')

  for (let kv of kvList) {
    let kvcdr = kv.split('_')
    if (kvcdr.length === 2) {
      res[kvcdr[0]] = kvcdr[1] || ''
    }
  }
  return res
}

使用

// 编码
let params =encodeScene({
      t: 'p',
      fuid: "5"
    })
wx.getImageInfo({
src: `${
          net.host
        }/100328/api/user/share/qrcode?page=${encodeURIComponent(
          'pages/system/login/index'
        )}&scene=${params}&width=120&uid=${userInfo.getToken()}`
})

// 解码

onLoad: function(options) {
    let scene = options.scene
    try {
      scene = util.decodeScene(scene)
      this.setData({
        target: scene.t || '',
        fromUserId: scene.fuid || '',
        id: scene.id || ''
      })
    } catch (e) {
      console.log(e)
    }
}