問題:
用canvas繪制圖片的時候會模糊,但是用img顯示的時候就不會,canvas和img的大小是相同的
至於為什么會變模糊,這和瀏覽器處理 canvas 的方式有關,相關的文章可以參考這篇 High DPI Canvas,這里不作深入介紹。
https://www.npmjs.com/package/hidpi-canvas
<!-- 通過 img 標簽引入圖片,以便繪制到 canvas 中 --> <img src="html5rocks.png" alt="" width="300" height="90">
<!-- canvas --> <canvas width="300" height="90"></canvas> <script> function init() { var canvas = document.querySelector('canvas'); var ctx = canvas.getContext('2d'); ctx.drawImage(document.querySelector('img'), 0, 0, 300, 90); } window.onload = init; </script>
解決問題:
首先,引入 hidpi-canvas
其實,不只是繪制圖片時會出現模糊的問題,正常情況下,在高清屏的設備下,任何繪制canvas中的圖形(包括文字)都會出現模糊的問題。上面這個就是為了解決這個問題,但是他沒有處理圖片。
接下來,修改繪制圖片的代碼
將 init 含稅修改成下面的代碼
function init() { var canvas = document.querySelector('canvas'); var ctx = canvas.getContext('2d'); // polyfill 提供了這個方法用來獲取設備的 pixel ratio var getPixelRatio = function(context) { var backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1; return (window.devicePixelRatio || 1) / backingStore; }; var ratio = getPixelRatio(ctx); // 注意,這里的 width 和 height 變成了 width * ratio 和 height * ratio ctx.drawImage(document.querySelector('img'), 0, 0, 300 * ratio, 90 * ratio); }
這個解決方案本質上是:
不管當前的devicePixelRatio
的值是多少,統一將canvas
DOM節點的width屬性設置為其css
width屬性的兩倍,同理將height屬性也設置為css
height屬性的兩倍,即:
<canvas width="320" height="180" style="width:160px;height:90px;"></canvas>
這樣整個 canvas 的坐標系范圍就擴大為兩倍,但是在瀏覽器的顯示大小沒有變,canvas畫圖的時候,按照擴大化的坐系來顯示,不清晰的問題就得以改善了
測試成功:母親節H5小游戲
https://act.mcake.com/fangli/2022/wap/motherDay-h5/index.html
<canvas id="myCanvas" width="750" height="1333"></canvas> <script src="scripts/hidpi-canvas.js"></script> <script src="scripts/canvas.js"></script>
canvas.js 繪制海報
/*繪制照片*/
function drawAndShareImage(windW,windH,canvasImg, imgArr,num,textT,textL){
var canvas=document.getElementById("myCanvas");
//var canvas = document.createElement("myCanvas");
canvas.width = windW;
canvas.height = windH;
var context = canvas.getContext("2d");
var getPixelRatio = function(context) {
var backingStore = context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1;
return (window.devicePixelRatio || 1) / backingStore;
};
var ratio = getPixelRatio(context);
context.rect(0 , 0 , canvas.width*ratio , canvas.height*ratio);
context.fillStyle = "#743700";
context.fill();
var myImage = new Image();
myImage.src = canvasImg.src; //背景圖片 你自己本地的圖片或者在線圖片
myImage.crossOrigin = 'Anonymous';
myImage.onload = function(){
//繪制背景圖
context.drawImage(myImage , 0 , 0 , windW*ratio , windH*ratio);
//繪制文字
context.font = "22px Courier New";
context.fillText(num,textL,textT+15);
var imglist = [];
var item = {}
var base64 = ""
var img = ""
$.each(imgArr, function(index,item){
imglist[index] = new Image();
imglist[index].src = item.src; //你自己本地的圖片或者在線圖片
imglist[index].crossOrigin = 'Anonymous';
imglist[index].onload = function(){
context.drawImage(imglist[index] ,item.offsetLeft*ratio, item.offsetTop*ratio, item.with*ratio, item.height*ratio);
base64 = canvas.toDataURL("image/png");
img = document.getElementById('myCanvas');
img.setAttribute('src' , base64);
$(".downImg").attr("src",base64);
}
})
}
}
// drawAndShareImage(
// windW,
// windH,
// {
// with:windW,
// height:windH,
// src:"images/down-img-bg.png"
// },photoArr, 6,textT,textL
// );