wx小程序最新版Canvas和旧版比较?

767 阅读3分钟

1. 在wxml中添加canvas组件

旧版

<canvas canvas-id="myCanvas" />

新版

<canvas id="myCanvas" type="2d" style="border: 1px solid; width: 300px; height: 150px;" />

首先需要在 WXML 中添加 canvas 组件。

指定 id="myCanvas" 唯一标识一个 canvas,用于后续获取 Canvas 对象。

指定 type 用于定义画布类型,本例子使用 type="2d" 示例。

2. 获取Canvas对象和渲染上下文

旧版

const context = wx.createCanvasContext('myCanvas')

新版

wx.createSelectorQuery()
    .select('#myCanvas') // 在 WXML 中填入的 id
    .node(({ node: canvas }) => {
        const context = canvas.getContext('2d')
    })
    .exec()

旧版 canvas 接口使用 wx.createCanvasContext 同步获取 CanvasContext。

新版 Canvas 2D 接口需要先通过 SelectorQuery 异步获取 Canvas 对象,再通过 Canvas.getContext 获取渲染上下文 RenderingContext。

新版可以初始化canvas

wx.createSelectorQuery()
    .select('#myCanvas') // 在 WXML 中填入的 id
    .fields({ node: true, size: true })
    .exec((res) => {
        // Canvas 对象
        const canvas = res[0].node
        // 渲染上下文
        const ctx = canvas.getContext('2d')

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

        // 初始化画布大小
        const dpr = wx.getWindowInfo().pixelRatio
        canvas.width = width * dpr
        canvas.height = height * dpr
        ctx.scale(dpr, dpr)
    })

不同的设备上,存在物理像素和逻辑像素不相等的情况,所以一般我们需要用 wx.getWindowInfo 获取设备的像素比,乘上 canvas 的渲染大小,作为画布的逻辑大小。其中上面代码中的dpr就是设备的像素比。

3. 绘制方法的改变

旧版

// 若干绘制调用
context.fillRect(0, 0, 50, 50)
context.fillRect(20, 20, 50, 50)

context.draw(false, () => {
    // 这里绘制完成
    console.log('draw done')
})

新版

// 绘制前清空画布
context.clearRect(0, 0, canvas.width, canvas.height)
// 若干绘制调用
context.fillRect(0, 0, 50, 50)
context.fillRect(20, 20, 50, 50)

// 这里绘制完成
console.log('draw done')

旧版 canvas 接口绘制需要调用 CanvasContext.draw才会进行绘制,并且绘制过程是异步的,需要等待绘制完成回调才能进行下一步操作。

新版 Canvas 2D 接口不再需要调用 draw 函数,所有绘制方法都会同步绘制到画布上。

需要注意的是 CanvasContext.draw 函数第一个参数控制在绘制前是否保留上一次绘制(默认值为 false,即不保留),若设置为 false,则迁移至新接口后,需要在绘制前通过 clearRect 清空画布。

4. 绘制图片的更改

旧版

context.drawImage(
    'https://open.weixin.qq.com/zh_CN/htmledition/res/assets/res-design-download/icon64_wx_logo.png',
    0,
    0,
    150,
    100,
)

新版

const image = canvas.createImage()
image.onload = () => {
    context.drawImage(
        image,
        0,
        0,
        150,
        100,
    )
}
image.src = 'https://open.weixin.qq.com/zh_CN/htmledition/res/assets/res-design-download/icon64_wx_logo.png'

旧版 canvas 接口 CanvasContext.drawImage 直接传入图片 url 进行绘制。

新版 Canvas 2D 接口需要先通过 Canvas.createImage 创建图片对象,onload 图片加载完成回调触发后,再将图片对象传入 context.drawImage 进行绘制。

5. 其余接口调整

wx.canvasToTempFilePath

旧版

wx.canvasToTempFilePath({
    canvasId: 'myCanvas',
    success(res) {
        //
    }
})

旧版传入canvas-id,还可以设置图片大小,画布区域等等。

新版

wx.canvasToTempFilePath({
    canvas: canvas,
    success(res) {
        //
    }
})

新版直接传入canvas实例。

wx.canvasPutImageData

###旧版

wx.canvasPutImageData({
    canvasId: 'myCanvas',
    x: 0,
    y: 0,
    width: 1,
    height: 1,
    data: data,
    success (res) {
        // after put image data
    }
})

新版

const context = canvas.getContext('2d')
context.putImageData(data, 0, 0, 0, 0, 1, 1)

wx.canvasGetImageData

获取画布图片数据

旧版

wx.canvasGetImageData({
    canvasId: 'myCanvas',
    x: 0,
    y: 0,
    width: 100,
    height: 100,
    success(res) {
        console.log(res.width) // 100
        console.log(res.height) // 100
        console.log(res.data instanceof Uint8ClampedArray) // true
        console.log(res.data.length) // 100 * 100 * 4
    }
})

新版

const context = canvas.getContext('2d')
const imageData = context.getImageData(0, 0, 100, 100)
console.log(imageData.width) // 100
console.log(imageData.height) // 100
console.log(imageData.data instanceof Uint8ClampedArray) // true
console.log(imageData.data.length) // 100 * 100 * 4

wx.loadFontFace

旧版

wx.loadFontFace({
  family: 'Bitstream Vera Serif Bold',
  source: 'url("https://sungd.github.io/Pacifico.ttf")',
  success: console.log
})

新版

wx.loadFontFace({
  family: 'Bitstream Vera Serif Bold',
  source: 'url("https://sungd.github.io/Pacifico.ttf")',
  scopes: ['webview', 'native'],
  success: console.log
})

新版 Canvas 2D 接口需要为 scopes 设置 native

6. 总结。

以上就是微信小程序画布的新版和旧版的比较。

注意:新版画布容易超出最大尺寸高度。不能设置太高的画布。