在微信开发工具上,打开小程序项目后,可能有遇到这么一个问题
使用
wx.createCanvasContext会提示此方法,基础库版本 2.9.0 起已废弃,请使用Canvas
替换
💡 如何解决?
- 方法1,改成使用旧的基础库可能有性能问题,此项忽略;
- 方法2,手动查找替换代码,会发现要改动的地方可多了,此项忽略
- 方法3,手动改动次数最小,不知道有没有
有的,下面笔者TA远方提供以下源代码,请仔细看
'use strict';
export default class CanvasContext {
constructor(res){
const { width, height, node } = res;
this.ctx = node.getContext('2d');
this.ctx.canvas.width = width;
this.ctx.canvas.height = height;
this.taskList = [];
this.addTask = (fun) => this.taskList.push(fun);
}
fillRect(x,y,w,h){
this.addTask(() => this.ctx.fillRect(x,y,w,h));
}
stroke(){
this.addTask(() => this.ctx.stroke());
}
fill(){
this.addTask(() => this.ctx.fill());
}
setFillStyle(color){
this.addTask(() => this.ctx.fillStyle = color);
}
setStrokeStyle(color){
this.addTask(() => this.ctx.strokeStyle = color);
}
beginPath(){
this.addTask(() => this.ctx.beginPath());
}
moveTo(x,y){
this.addTask(() => this.ctx.moveTo(x,y));
}
lineTo(x,y){
this.addTask(() => this.ctx.lineTo(x,y));
}
setTextAlign(value){
this.addTask(() => this.ctx.textAlign = value);
}
setTextBaseline(value){
this.addTask(() => this.ctx.textBaseline = value);
}
setFontSize(value){
this.addTask(() => this.ctx.font = value + "px sans-serif");
}
arc(x,y,radius,startAngle,endAngle){
this.addTask(() => this.ctx.arc(x,y,radius,startAngle,endAngle));
}
fillText(text,x,y,maxWidth){
this.addTask(() => this.ctx.fillText(text,x,y,maxWidth));
}
bezierCurveTo(cp1x,cp1y,cp2x,cp2y,cp3x,cp4y){
this.addTask(() => this.ctx.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,cp3x,cp4y));
}
draw(noClear,success){
if (!noClear) {
let canvas = this.ctx.canvas;
this.ctx.clearRect(0,0,canvas.width,canvas.height);
}
this.taskList.forEach(t => t());
this.taskList.length = 0;
if (typeof success == 'function') success();
}
setShadow(offsetX,offsetY,blur,color){
this.addTask(() => {
if (offsetX!=undefined) this.ctx.shadowOffsetX = offsetX;
if (offsetY!=undefined) this.ctx.shadowOffsetX = offsetY;
if (blur!=undefined) this.ctx.shadowBlur = blur;
if (color!=undefined) this.ctx.shadowColor = color;
});
}
clearRect(x,y,w,h){
this.addTask(() => this.ctx.clearRect(x,y,w,h));
}
//更多调用方法...
}
将上面的代码复制粘贴到一个新建的文件canvas_context.js中,然后,在调用的地方去新建CanvasContext
对象类实例,这样就可以像往常一样使用,代码如下,其中的canvA,canvB,canvB使用方式基本不用做多改动
import CanvasContext from '../../utils/canvas_context';
Page({
onLoad(){
// TODO:会提示 wx.createCanvasContext 方法已弃用
// this.data.canvas = {
// canvA: wx.createCanvasContext('canvA'),
// canvB: wx.createCanvasContext('canvB'),
// canvC: wx.createCanvasContext('canvC'),
// };
wx.createSelectorQuery().select('#canvA').fields({ size: true, node: true },res=>{
this.data.canvas.width = res.width;
this.data.canvas.height = res.height;
// TODO:改用 CanvasContext 替换即可,性能不受影响
this.data.canvas.canvA = new CanvasContext(res);
wx.createSelectorQuery().select('#canvB').fields({ size: true, node: true },res=>{
this.data.canvas.canvB = new CanvasContext(res);
wx.createSelectorQuery().select('#canvC').fields({ size: true, node: true },res=>{
this.data.canvas.canvC = new CanvasContext(res);
this.reset()
}).exec()
}).exec()
}).exec()
}
})
还有需要注意,在布局文件中,组件canvas添加新的属性id=""
,type="2d"
, 示例如下
<view class="page">
<view class="canvas-box">
<canvas class="canvas" canvas-id="canvA" id="canvA" type="2d"></canvas>
<canvas class="canvas" canvas-id="canvB" id="canvB" type="2d"></canvas>
<canvas class="canvas" canvas-id="canvC" id="canvC" type="2d" bindtouchstart="onTouch"></canvas>
</view>
<!-- ... -->
</view>