新冠防疫隔离在家,无聊得紧,就写写微信小游戏来玩。
开始发现字体是模糊的,图片也比较模糊。
查了官方文档,微信官方说调整了canvas的缩放策略,它把物理像素和逻辑像素自动做了缩放,使我们不用考虑pixelRatio,因此字体和图片都模糊了,如果要显示高清,就要自己处理了。
官方说明如下:
https://developers.weixin.qq.com/community/develop/doc/00040c9903023848e0d7bd6205a401?highLine=%25E6%2596%2587%25E5%25AD%2597%25E6%25A8%25A1%25E7%25B3%258A
要处理高清,就要把canvas的大小乘以pixelRatio倍,如:
let sysInfo = wx.getSystemInfoSync();
canvas.width = sysInfo.screenWidth * sysInfo.pixelRatio;
canvas.height = sysInfo.screenHeight * sysInfo.pixelRatio;
同时,原来的fillRect,lineTo,moveTo......等等函数,位置大小都要乘以pixelRatio倍。为了简化修改,试了一下hook override,写一个文件wxhHook.js,把这些函数一次修改掉:
/**
* 画布缩放,只有sysInfo.pixelRatio扩大画布,贴图和文字才会清晰,但是离屏画布复制到前景时变慢很多。
*/
//如果要扩大画布(高清),注释掉这一行
//wx.tmGlobal.sysInfo.pixelRatio = 1;
wx.tmGlobal.canvas.width = wx.tmGlobal.sysInfo.screenWidth * wx.tmGlobal.sysInfo.pixelRatio;
wx.tmGlobal.canvas.height = wx.tmGlobal.sysInfo.screenHeight * wx.tmGlobal.sysInfo.pixelRatio;
wx.tmGlobal.canvas_bkg.width = wx.tmGlobal.sysInfo.screenWidth * wx.tmGlobal.sysInfo.pixelRatio;
wx.tmGlobal.canvas_bkg.height = wx.tmGlobal.sysInfo.screenHeight * wx.tmGlobal.sysInfo.pixelRatio;
wx.tmGlobal.canvas_qipan.width = wx.tmGlobal.sysInfo.screenWidth * wx.tmGlobal.sysInfo.pixelRatio;
wx.tmGlobal.canvas_qipan.height = wx.tmGlobal.sysInfo.screenHeight * wx.tmGlobal.sysInfo.pixelRatio;
wx.tmGlobal.canvas_score.width = wx.tmGlobal.sysInfo.screenWidth * wx.tmGlobal.sysInfo.pixelRatio;
wx.tmGlobal.canvas_score.height = wx.tmGlobal.sysInfo.screenHeight * wx.tmGlobal.sysInfo.pixelRatio;
let CanvasRenderingContext2D = wx.tmGlobal.context.constructor;
CanvasRenderingContext2D.prototype._moveTo=CanvasRenderingContext2D.prototype.moveTo;
CanvasRenderingContext2D.prototype.moveTo = function (x, y) {
return CanvasRenderingContext2D.prototype._moveTo.call(this,
x * wx.tmGlobal.sysInfo.pixelRatio,
y * wx.tmGlobal.sysInfo.pixelRatio);
}
CanvasRenderingContext2D.prototype._lineTo = CanvasRenderingContext2D.prototype.lineTo;
CanvasRenderingContext2D.prototype.lineTo = function (x, y) {
return CanvasRenderingContext2D.prototype._lineTo.call(this,
x * wx.tmGlobal.sysInfo.pixelRatio,
y * wx.tmGlobal.sysInfo.pixelRatio);
}
CanvasRenderingContext2D.prototype._strokeRect = CanvasRenderingContext2D.prototype.strokeRect;
CanvasRenderingContext2D.prototype.strokeRect = function (x, y, w, h) {
return CanvasRenderingContext2D.prototype._strokeRect.call(this,
x * wx.tmGlobal.sysInfo.pixelRatio,
y * wx.tmGlobal.sysInfo.pixelRatio,
w * wx.tmGlobal.sysInfo.pixelRatio,
h * wx.tmGlobal.sysInfo.pixelRatio);
};
CanvasRenderingContext2D.prototype._fillRect = CanvasRenderingContext2D.prototype.fillRect;
CanvasRenderingContext2D.prototype.fillRect = function (x, y, w, h) {
return CanvasRenderingContext2D.prototype._fillRect.call(this,
x * wx.tmGlobal.sysInfo.pixelRatio,
y * wx.tmGlobal.sysInfo.pixelRatio,
w * wx.tmGlobal.sysInfo.pixelRatio,
h * wx.tmGlobal.sysInfo.pixelRatio);
};
CanvasRenderingContext2D.prototype._rect = CanvasRenderingContext2D.prototype.rect;
CanvasRenderingContext2D.prototype.rect = function (x, y, w, h) {
return CanvasRenderingContext2D.prototype._rect.call(this,
x * wx.tmGlobal.sysInfo.pixelRatio,
y * wx.tmGlobal.sysInfo.pixelRatio,
w * wx.tmGlobal.sysInfo.pixelRatio,
h * wx.tmGlobal.sysInfo.pixelRatio);
};
CanvasRenderingContext2D.prototype._clearRect = CanvasRenderingContext2D.prototype.clearRect;
CanvasRenderingContext2D.prototype.clearRect = function (x, y, w, h) {
return CanvasRenderingContext2D.prototype._clearRect.call(this,
x * wx.tmGlobal.sysInfo.pixelRatio,
y * wx.tmGlobal.sysInfo.pixelRatio,
w * wx.tmGlobal.sysInfo.pixelRatio,
h * wx.tmGlobal.sysInfo.pixelRatio);
};
//img整图缩放绘制,如果是从img扣去部分来绘制,请使用_drawImage,并把sx,sy,sw,sh也乘以pixelRatio
CanvasRenderingContext2D.prototype._drawImage = CanvasRenderingContext2D.prototype.drawImage;
CanvasRenderingContext2D.prototype.drawImage = function (img) {
//console.log(arguments);
let params = new Array(9);
if (arguments.length == 3) {
params[0] = arguments[0]; //img
params[1] = 0; //sx
params[2] = 0; //sy
params[3] = arguments[0].width; //sw
params[4] = arguments[0].height; //sh
params[5] = arguments[1]; //dx
params[6] = arguments[2]; //dy
params[7] = arguments[0].width; //dw
params[8] = arguments[0].height; //dh
}
else if (arguments.length == 5) {
params[0] = arguments[0]; //img
params[1] = 0; //sx
params[2] = 0; //sy
params[3] = arguments[0].width; //sw
params[4] = arguments[0].height; //sh
params[5] = arguments[1]; //dx
params[6] = arguments[2]; //dy
params[7] = arguments[3]; //dw
params[8] = arguments[4]; //dh
}
else params = arguments;
for (let i = 5; i < params.length; i++) {
params[i] = params[i] * wx.tmGlobal.sysInfo.pixelRatio;
}
//console.log(params);
return CanvasRenderingContext2D.prototype._drawImage.apply(this, params);
};
CanvasRenderingContext2D.prototype._fillText = CanvasRenderingContext2D.prototype.fillText;
CanvasRenderingContext2D.prototype.fillText = function (s, x, y) {
return CanvasRenderingContext2D.prototype._fillText.call(this,
s, x * wx.tmGlobal.sysInfo.pixelRatio,
y * wx.tmGlobal.sysInfo.pixelRatio);
}
CanvasRenderingContext2D.prototype._createImageData = CanvasRenderingContext2D.prototype.createImageData;
CanvasRenderingContext2D.prototype.createImageData = function (w, h) {
return CanvasRenderingContext2D.prototype._createImageData.call(this,
w * wx.tmGlobal.sysInfo.pixelRatio, h * wx.tmGlobal.sysInfo.pixelRatio);
}
CanvasRenderingContext2D.prototype._getImageData = CanvasRenderingContext2D.prototype.getImageData;
CanvasRenderingContext2D.prototype.getImageData = function (x, y, w, h) {
return CanvasRenderingContext2D.prototype._getImageData.call(this,
x * wx.tmGlobal.sysInfo.pixelRatio,
y * wx.tmGlobal.sysInfo.pixelRatio,
w * wx.tmGlobal.sysInfo.pixelRatio,
h * wx.tmGlobal.sysInfo.pixelRatio);
}
CanvasRenderingContext2D.prototype._putImageData = CanvasRenderingContext2D.prototype.putImageData;
CanvasRenderingContext2D.prototype.putImageData = function (data, x, y) {
return CanvasRenderingContext2D.prototype._putImageData.call(this, data,
x * wx.tmGlobal.sysInfo.pixelRatio, y * wx.tmGlobal.sysInfo.pixelRatio);
}
保留了原函数,前面加了一个下划线,特殊需要调用地方使用原函数,如画布复制:
function updateCanvas(){
//没有clearRect,感觉画面偶尔会闪一下
wx.tmGlobal.context._clearRect(0, 0, wx.tmGlobal.canvas.width, wx.tmGlobal.canvas.height);
if (wx.tmGlobal.context_bkg != wx.tmGlobal.context){
//复制画布,用旧的不考虑pixelRatio的函数画
wx.tmGlobal.context._drawImage(wx.tmGlobal.canvas_bkg,0,0);
}
}
其它要注意的是字体,需要修改,如:
//const g_scoreFont = "14px Arial";
const g_scoreFont = 14 * wx.tmGlobal.sysInfo.pixelRatio+"px Arial";