# 舊版 Canvas 遷移指南
小程序的 舊版 canvas 接口 已經(jīng)不再維護(hù),本指南將指引如何遷移至新版 Canvas 2D 接口。
# 特性差異
| 舊版 canvas 接口 | Canvas 2D 接口 | |
|---|---|---|
| 同層渲染 | 不支持 | 支持 |
| api支持 | 部分支持 | 支持全部 Web 標(biāo)準(zhǔn) |
| 繪制 | 異步繪制 | 同步繪制 |
| 性能 | 低 | 高 |
# 遷移步驟
# 第一步:修改 WXML
<canvas canvas-id="myCanvas" />
<!-- 修改為以下 -->
<canvas id="myCanvas" type="2d" />
舊版 canvas 接口使用 canvas-id 屬性唯一標(biāo)識(shí) canvas;新版 Canvas 2D 可直接使用 id 標(biāo)識(shí)。
另外需要給 canvas 添加 type="2d" 屬性標(biāo)識(shí)為新版 Canvas 2D 接口。
# 第二步:修改獲取 CanvasContext
const context = wx.createCanvasContext('myCanvas')
//
// 修改為以下
//
this.createSelectorQuery()
.select('#myCanvas') // 在 WXML 中填入的 id
.node(({ node: canvas }) => {
const context = canvas.getContext('2d')
})
.exec()
舊版 canvas 接口使用 wx.createCanvasContext 同步獲取 CanvasContext。
新版 Canvas 2D 接口需要先通過(guò) SelectorQuery 異步獲取 Canvas 對(duì)象,再通過(guò) Canvas.getContext 獲取渲染上下文 RenderingContext。
# 第三步:畫布大小初始化
// 舊版 canvas 不能修改寬高
this.createSelectorQuery()
.select('#myCanvas') // 在 WXML 中填入的 id
.fields({ node: true, size: true })
.exec((res) => {
// Canvas 對(duì)象
const canvas = res[0].node
// Canvas 畫布的實(shí)際繪制寬高
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)
})
舊版 canvas 接口的畫布大小是根據(jù)實(shí)際渲染寬度決定的,開發(fā)者無(wú)法修改。
新版 Canvas 2D 接口允許開發(fā)者自由修改畫布的邏輯大小,默認(rèn)寬高為 300*150。
不同的設(shè)備上,存在物理像素和邏輯像素不相等的情況,所以一般我們需要用 wx.getWindowInfo 獲取設(shè)備的像素比,乘上 canvas 的實(shí)際大小。
# 第四步:修改繪制方法
// 若干繪制調(diào)用
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)
// 若干繪制調(diào)用
context.fillRect(0, 0, 50, 50)
context.fillRect(20, 20, 50, 50)
// 這里繪制完成
console.log('draw done')
舊版 canvas 接口繪制需要調(diào)用 CanvasContext.draw 才會(huì)進(jìn)行繪制,并且繪制過(guò)程是異步的,需要等待繪制完成回調(diào)才能進(jìn)行下一步操作。
新版 Canvas 2D 接口不再需要調(diào)用 draw 函數(shù),所有繪制方法都會(huì)同步繪制到畫布上。
需要注意的是 CanvasContext.draw 函數(shù)第一個(gè)參數(shù)控制在繪制前是否保留上一次繪制(默認(rèn)值為 false,即不保留),若設(shè)置為 false,則遷移至新接口后,需要在繪制前通過(guò) clearRect 清空畫布。
# 第五步:修改圖片繪制
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 進(jìn)行繪制。
新版 Canvas 2D 接口需要先通過(guò) Canvas.createImage 創(chuàng)建圖片對(duì)象,onload 圖片加載完成回調(diào)觸發(fā)后,再將圖片對(duì)象傳入 context.drawImage 進(jìn)行繪制。
# 其余接口調(diào)整
# wx.canvasToTempFilePath
wx.canvasToTempFilePath({
canvasId: 'myCanvas',
success(res) {
//
}
})
//
// 修改為以下
//
wx.canvasToTempFilePath({
canvas: canvas,
success(res) {
//
}
})
舊版 canvas 接口傳入 canvas-id。
新版 Canvas 2D 接口需要直接傳入 Canvas 實(shí)例
# 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)
// after put image data
新版 canvas 不支持 wx.canvasPutImageData,應(yīng)使用 context.putImageData 代替。
# 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
新版 canvas 不支持 wx.canvasGetImageData,應(yīng)使用 context.getImageData 代替。
# 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 設(shè)置 native。