# Legacy Canvas Migration Guide

Weixin Mini Program's legacy canvas interface is no longer maintained, and this guide will guide how to migrate to the new version of Canvas 2D interface .

# Differences in characteristics

Old canvas interface Canvas2D Interface
Same layer rendering No support. Support
API support Part of Support Supports all web standards
draw Asynchronous painting Synchronous mapping
performance low high

# migration steps

# Edit: Modifying WXML

<canvas canvas-id="myCanvas" />
<!-- 修改为以下 -->
<canvas id="myCanvas" type="2d" />

The old canvas interface uses thecanvas-idattribute to uniquely identify canvas;The new version of Canvas 2D can be identified directly withid.

You also need to add thetype = "2d"attribute to the canvas to identify the new Canvas2D interface.

# Step 2: Modify Get CanvasContext

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

The old canvas interface uses wx.createCanvasContext Synchronize to get CanvasContext

The new version of the Canvas 2D interface needs to be approved by SelectorQuery Asynchronously obtains the Canvas object and obtains the rendering context by canvas.getContext RenderingContext

# Step 3: Initialize the canvas size

// Old canvas can not modify the width
this.createSelectorQuery()
    .select('#myCanvas') // 在 WXML 中填入的 id
    .fields({ node: true, size: true })
    .exec((res) => {
        // Canvas 对象
        const canvas = res[0].node
        // Canvas 画布的实际绘制宽高
        const renderWidth = res[0].width
        const renderHeight = res[0].height
        // Canvas 绘制上下文
        const ctx = canvas.getContext('2d')

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

The canvas size of the old canvas interface is determined by the actual render width and cannot be modified by the developer.

The new Canvas2D interface allows developers to freely modify the logical size of the canvas, the default width is 300 * 150.

On different devices, there are cases where the physical and logical pixels are not equal, so generally we need to use wx.getWindowInfo to obtain the pixel ratio of the device and multiply the actual size of the canvas.

# Step 4: Modify the drawing method

// Several mapping calls
context.fillRect(0, 0, 50, 50)
context.fillRect(20, 20, 50, 50)

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

//
// Revise to the following
//

// Empty the canvas before painting
context.clearRect(0, 0, canvas.width, canvas.height)
// Several mapping calls
context.fillRect(0, 0, 50, 50)
context.fillRect(20, 20, 50, 50)

// The drawing is done here.
console.log('draw done')

Older versions of the canvas interface drawing required calling CanvasContext.draw to draw, and the drawing process was asynchronous and required waiting for the drawing to complete a callback to proceed.

The new Canvas 2D interface no longer requires calling thedrawfunction, and all drawing methods are synchronized **to the canvas.

Note that CanvasContext.draw The first argument of the function controls whether to retain the previous drawing before drawing (the default is false, i.e. not retained). If set to false, the migration to the new interface requires clearRectandto empty the canvas before drawing.

# Step 5: Modify the picture drawing

context.drawImage(
    'https://open.weixin.qq.com/zh_CN/htmledition/res/assets/res-design-download/icon64_wx_logo.png',
    0,
    0,
    150,
    100,
)
//
// Revise to the following
//
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'

Old canvas interface CanvasContext.drawImage Direct incoming image url for drawing.

The new version of the Canvas 2D interface needs to be approved by Canvas.createImage Create a picture object,onloadAfter the picture loading callback is completed, pass the picture object tocontext.drawImageto draw.

# The remaining interface adjustments

# wx.canvasToTempFilePath

wx.canvasToTempFilePath({
    canvasId: 'myCanvas',
    success(res) {
        //
    }
})
//
// Revise to the following
//
wx.canvasToTempFilePath({
    canvas: canvas,
    success(res) {
        //
    }
})

Old version canvas interface passed incanvas-id.

The new version of the Canvas2D interface needs to pass in the Canvas instance directly

# wx.canvasPutImageData

wx.canvasPutImageData({
    canvasId: 'myCanvas',
    x: 0,
    y: 0,
    width: 1,
    height: 1,
    data: data,
    success (res) {
        // after put image data
    }
})
//
// Revise to the following
//
const context = canvas.getContext('2d')
context.putImageData(data, 0, 0, 0, 0, 1, 1)
// after put image data

The new canvas does not support wx.canvasPutImageData . Usecontext.putImageData [()] instead.

# 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
    }
})
//
// Revise to the following
//
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

The new canvas does not support wx.canvasGetImageData . Usecontext.getImageData [()] instead.

# wx.loadFontFace

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

The new version of the Canvas 2D interface needs to be set toscopes``native.