# 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.