來源: http://www.css88.com/archives/9297

使用 canvas 繪制圖片或者是文字在 Retina 屏中會非常模糊。如圖:
因為 canvas 不是矢量圖,而是像圖片一樣是位圖模式的。高 dpi 顯示設備意味着每平方英寸有更多的像素。也就是說二倍屏,瀏覽器就會以2個像素點的寬度來渲染一個像素,該 canvas 在 Retina 屏幕下相當於占據了2倍的空間,相當於圖片被放大了一倍,因此繪制出來的圖片文字等會變模糊。 因此,要做 Retina 屏適配,關鍵是知道當前屏幕的設備像素比,然后將 canvas 放大到該設備像素比來繪制,然后將 canvas 壓縮到一倍來展示。 解決思路 在瀏覽器的 window 對象中有一個 devicePixelRatio 的屬性,該屬性表示了屏幕的設備像素比,即用幾個(通常是2個)像素點寬度來渲染1個像素。 舉例來說,假設 devicePixelRatio 的值為 2 ,一張 100×100 像素大小的圖片,在 Retina 屏幕下,會用 2 個像素點的寬度去渲染圖片的 1 個像素點,因此該圖片在 Retina 屏幕上實際會占據 200×200 像素的空間,相當於圖片被放大了一倍,因此圖片會變得模糊。 類似的,在 canvas context 中也存在一個 backingStorePixelRatio 的屬性,該屬性的值決定了瀏覽器在渲染canvas之前會用幾個像素來來存儲畫布信息。 backingStorePixelRatio 屬性在各瀏覽器廠商的獲取方式不一樣,所以需要加上瀏覽器前綴來實現兼容。 解決問題 1.首先一樣,獲取 Canvas 對象: JavaScript 代碼: var myCanvas = document.getElementById("my_canvas"); var context = myCanvas.getContext("2d"); 2.獲取像素比,將 Canvas 寬高進行放大,放大比例為:devicePixelRatio / webkitBackingStorePixelRatio , 我們寫了一個兼容的方法。 JavaScript 代碼: 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); 3.按實際渲染倍率來縮放canvas。 注意基礎知識點: 要設置canvas的畫布大小,使用的是 canvas.width 和 canvas.height; 要設置畫布的實際渲染大小,使用的 style 屬性或CSS設置的 width 和height,只是簡單的對畫布進行縮放。 2倍屏幕下示例代碼: HTML 代碼: <canvas width="640" height="800" style="width:320px; height:400px"></canvas> canvas的實際大小的640px × 800px,但是實際渲染到頁面的大小是320px × 400px,相當於縮小一倍來顯示。 那么在3倍屏幕下就是: HTML 代碼: <canvas width="960" height="1200" style="width:320px; height:400px"></canvas> 因此,要使canvas適配高倍屏,就是要將canvas放大到設備像素比來繪制,最后將canvas壓縮成一倍的物理大小來展示。如下: JavaScript 代碼: myCanvas.style.width = myCanvas.width + 'px'; myCanvas.style.height = myCanvas.height + 'px'; myCanvas.width = myCanvas.width * ratio; myCanvas.height = myCanvas.height * ratio; 4.繪制 由於 Canvas 放大后,相應的繪制圖片時也要放大,有兩種方式: 第一種方法:每一個繪制相應的放大,比如我們繪制文字 JavaScript 代碼: context.font = "36px Georgia"; //一倍屏下18px字體 context.fillStyle = "#999"; context.fillText("我是清晰的文字", 50*ratio, 50*ratio);// 坐標位置乘以像素比 相對來說這個方法非常繁瑣麻煩。 第二種方法:直接使用 scale 方法: JavaScript 代碼: // 放大倍數 context.scale(ratio, ratio); context.font = "18px Georgia"; context.fillStyle = "#999"; context.fillText("我是清晰的文字", 50, 50); 這樣就可以解決 canvas 在高清屏中繪制模糊的問題 完整的demo:http://www.css88.com/demo/canvas_retina/index.html