在解決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)