likes
comments
collection
share

Taro微信小程序绘制分享图片

作者站长头像
站长
· 阅读数 12

具体思路:

  1. 通过小程序的元素查询,查询到canvas节点
  2. 可以像在web中正常的使用ctx进行绘制,但也有部分api与原生web不同如 ctx.drawImage
  3. 绘制完成之后需要通过canvas生成为一个临时链接
  4. 最后通过调用小程序的保存图片api将图片链接传入,这一步可以是任意的分享方式。

官方说明了 wx.createCanvasContext 从基础库 2.9.0 开始,本接口停止维护,请使用 Canvas 代替。大部分教程使用的还是 wx.createCanvasContext。本文将使用截止发布日期最新的api。查收从wx.createCanvasContext 迁移到 Canvas

整体程序流程

const drawSharingImageAndSaving = async() => {
    // 绘制的同时进行loading
    await whileLoading(async ()=>{
        // 获取canvas元素,myCanvas必须是界面中的一个元素
        const canvas = await querySelector('#myCanvas')
        // 绘制分享图像
        await drawSharingImage(canvas)
        // 使用canvas生成临时资源地址
        const tempFile = await Taro.canvasToTempFilePath({canvas,canvasId:'#myCanvas'})
        // 通过临时地址保存相册
        await Taro.saveImageToPhotosAlbum({filePath:tempFile.tempFilePath})
        Taro.showToast({title:'保存成功'})
    }).catch(()=>{
        Taro.showToast({title:'保存失败',icon:'none'})
    })

}

使用canvas元素节点来创建画布

获取canvas元素

const querySelector = (selector)=>{
    return new Promise((resolve)=>{
        Taro.createSelectorQuery()
        .select(selector) // 在 WXML 中填入的 id
        .fields({ node: true })
        .exec((res) => {
            resolve(res[0].node)
        })
    })
}

开始绘制

const drawSharingImage =async (canvas) => {
    const context = canvas.getContext('2d')
    // 为canvas创建一个图片,具体绘制内容更具需求
    const image = await createImageForCanvas(canvas,'你的图片地址')
    // 绘制图片需要通过canvas先创建一个image
    context.drawImage(context,0,0,image.width,image.height)
    // context.rect(0,0,canvas.width,canvas.height)
    // ... code
}
// createImageForCanvas具体实现
const createImageForCanvas = (canvas,src)=>{
    return new Promise((resolve)=>{
        const image = canvas.createImage()
        image.onload = () => {
            resolve(image)
        }
        image.src = src
    })
}

题外话 whileLoading 实现

const whileLoading = async <T extends Promise<unknown>>(asyncHandler: () => T, option: Taro.showLoading.Option) =>{
  Taro.showLoading(option)
  const response = await asyncHandler().catch((e)=>{
    Taro.hideLoading()
    throw e
  })
  Taro.hideLoading()
  return response as T
}

最后

贴一个原生web绘制的示例 支持不同屏幕等比缩放,所有尺寸通过设计稿与实际屏幕尺寸按缩放比例计算出来,写完发现也可以用context.scale来实现。

转载自:https://juejin.cn/post/7240111396869914684
评论
请登录