微信小程序canvas画布自2.9.0 起支持一套新 Canvas 2D 接口(需指定 type 属性),但文档不全,从原canvas的api转变到新的api时遇到不少问题,现将新版与旧版的画布载入图片方法整理一下,避免再次入坑。
旧版代码如下
<canvas style="width:100vw; height:100vh;" canvas-id="canvas_box" ></canvas>
onReady() {
let ctx = wx.createCanvasContext("canvas_box");
ctx.drawImage("../../assets/img/cat.jpg", 0, 0);
ctx.draw();
}
新版注意事项:
- 需指定canvas组件的type属性为2d,如果指定了此属性,则canvas-id属性无需指定;
- 通过获取元素节点的方式获取canvas对象:wx.createSelectorQuery().select(’#canvas_box’),如果是在自定义组件 component 内,则需要加in获取:wx.createSelectorQuery().in(this).select(’#canvas_box’);
- Canvas 2D(新接口)需要显式设置画布宽高 (默认为 300x150);
- 旧版的drawImage方法的第一个参数是图片路径,为字符串如:"…/…/assets/img/cat.jpg",新版的api同web一致,需是这些类型:HTMLImageElement、HTMLCanvasElement、ImageBitmap等,详情可参见这里CanvasRenderingContext2D.drawImage() 和 CanvasImageSource ;
- drawImage方法需要放在图片img的onload方法里面执行;
- 如果需要向canvas里载入多张图片,则需要分别创建多个img对象。
新版代码如下
wxml:
<view class="content">
<canvas type="2d" disable-scroll="true" id="canvas_box" class="canvas_box"></canvas>
</view>
wxss:
.content {
padding: 20rpx;
}
.canvas_box {
width: 100%;
height: 50vh;
border: 1px dashed #ddd;
}
javascript:
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
const query = wx.createSelectorQuery()
query.select('#canvas_box')
.fields({
id: true,
node: true,
size: true
})
.exec(this.init.bind(this));
},
init(res) {
const canvas = res[0].node
const ctx = canvas.getContext('2d')
const dpr = wx.getSystemInfoSync().pixelRatio
//新接口需显示设置画布宽高;
canvas.width = res[0].width * dpr
canvas.height = res[0].height * dpr
ctx.scale(dpr, dpr);
this.setData({
canvas,
ctx
});
this.canvasDraw();//向画布载入图片的方法
console.log(res)
},
canvasDraw() {
let img = this.data.canvas.createImage();//创建img对象
//如果需要向canvas里载入多张图片,则需要分别创建多个img对象
//let img2=this.data.canvas.createImage();
// img2.οnlοad=()=>{};
// img2.src="";
img.onload = () => {
//img.complete表示图片是否加载完成,结果返回true和false;
console.log(img.complete);//true
this.data.ctx.drawImage(img, 0, 0, this.data.canvas._width, this.data.canvas._height);
};
img.src = "../../assets/img/cat.jpg";
console.log(img.complete);//false
},
获取的canvas组件的节点信息返回的是一个数组,如下图: