H5 canvas 解决合成图模糊(canvas真机下scale不起作用,无法缩放显示的问题)
在解决canvas合成图片模糊的问题想必我们已经了解了
- window.devicePixelRatio
window接口的devicePixelRatio
返回当前显示设备的物理像素分辨率与CSS像素分辨率之比。此值也可以解释为像素大小的比率:一个CSS像素的大小与一个物理像素的大小。简单来说,它告诉浏览器应使用多少屏幕实际像素来绘制单个CSS像素。 - 使用 ctx.scale(scale, scale)来解决合成后图片模糊的问题,但是移动端真机测试时候却发现scale却不生效,并且微信开发社区也已经明确指出原生组件的使用限制 部分 CSS 样式无法应用于原生组件,例如:
-
- 无法对原生组件设置 CSS 动画
- 无法定义原生组件为 position: fixed
- 不能在父级节点使用 overflow: hidden 来裁剪原生组件的显示区域
如下面回复:
其实解决问题很简单,既然scalse 不生效,手动放大倍数不就行了吗!
解决思路:
1.拿到devicePixelRatio
var ratio = window.devicePixelRatio;
2.把画布放大
canvas.width = Math.floor(size * ratio);
canvas.height = Math.floor(size * ratio);
只放大画布的情况下合成效果如
3.合成时候同样把文字位置、大小进行放大(替换scale的效果)
ctx.fillRect(10 * ratio, 10 * ratio, 300 * ratio, 300 * ratio);
var x = size / 2;
var y = size / 2;
var textString = "I love MDN";
ctx.fillText(textString, x * scale, y * ratio)
下面是MDN一个解决方案:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// Set display size (css pixels).
var size = 200;
canvas.style.width = size + "px";
canvas.style.height = size + "px";
// Set actual size in memory (scaled to account for extra pixel density).
var scale = window.devicePixelRatio; // Change to 1 on retina screens to see blurry canvas.
canvas.width = Math.floor(size * scale);
canvas.height = Math.floor(size * scale);
// Normalize coordinate system to use css pixels.
ctx.scale(scale, scale);
ctx.fillStyle = "#bada55";
ctx.fillRect(10, 10, 300, 300);
ctx.fillStyle = "#ffffff";
ctx.font = '18px Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
var x = size / 2;
var y = size / 2;
var textString = "I love MDN";
ctx.fillText(textString, x, y)
更改后的兼容代码
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// Set display size (css pixels).
var size = 200;
canvas.style.width = size + "px";
canvas.style.height = size + "px";
// Set actual size in memory (scaled to account for extra pixel density).
var scale = window.devicePixelRatio; // Change to 1 on retina screens to see blurry canvas.
canvas.width = Math.floor(size * scale);
canvas.height = Math.floor(size * scale);
// Normalize coordinate system to use css pixels.
ctx.fillStyle = "#bada55";
ctx.fillRect(10 * scale , 10 * scale , 300 * scale , 300 * scale );
ctx.fillStyle = "#ffffff";
ctx.font = '18px Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
var x = size / 2;
var y = size / 2;
var textString = "I love MDN";
ctx.fillText(textString, x* scale, y * scale)