繪製高清晰度HTML canvas適配不一樣移動設備,將文字轉換成圖片並自動換行(解決中英文混雜文字狀況)

繪製高清晰度HTML canvas適配不一樣移動設備

最近在作項目的時候,須要把文字以圖片形式在前端顯示出來,發現canvas這個好東西。可是在手機端顯示的時候老是很模糊,查找資料發現是devicePixelRatio惹的禍javascript

下面是作的簡單測試,先貼代碼:html

    <script type="text/javascript">
        var canvas = document.createElement("canvas");
        canvas.width = 414;
        var ctx = canvas.getContext("2d");
        ctx.font = "30px Arial";
        ctx.fillText("Low DPI Text", 10, 40);
        document.body.appendChild(canvas);

        var HiDPIcanvas = document.createElement("canvas");
        HiDPIcanvas.width = 414 * window.devicePixelRatio;
        HiDPIcanvas.style.width = 414;
        var HiDPIctx = HiDPIcanvas.getContext("2d");
        HiDPIctx.scale(window.devicePixelRatio,window.devicePixelRatio);
        HiDPIctx.font = "30px Arial";
        HiDPIctx.fillText("High DPI Text", 10, 40);
        document.body.appendChild(HiDPIcanvas);
    </script>

 

Chrome開發模式下,能夠看出前者是正常的,然後者「太」清晰了,由於電腦屏幕通常devicePixelRatio都是1,沒有影響前端

 

 

而在手機上顯示就不一樣了,iPhone 6sp下,後者正常,而前者其實有些模糊了,iPhone 6sp的devicePixelRatio爲3html5

文字轉成圖片(解決中英文混雜字符串如何按字節截斷問題)

因爲canvas的fillText方法不支持自動換行,因此須要手動截斷字符串,找好canvas的X和Y座標位置後,像畫畫同樣把文字畫上去。java

代碼以下,(自定義字節長度進行截斷,不截斷數字)canvas

 1 // Create HiDPI canvas based on custom ratio or device pixel ratio
 2 function createCanvas(str, pixelRatio) {
 3     var w = window.screen.width * 0.935; // 0.935 is the canvas' width proportion     
 4     if (!pixelRatio) { pixelRatio = window.devicePixelRatio || 1; }
 5     var can = document.createElement("canvas");
 6     can.width = w * pixelRatio;
 7     can.style.width = w + "px";
 8     return drawImage(str, can, pixelRatio);
 9 }
10 
11 // Draw text on HTML canvas
12 function drawImage(text, canvas, pixelRatio) {    
13     var ratio = window.screen.width / 414; // Fit with iPhone 6sp as the standard
14     var rowLength = 39; // Byte length of canvas row
15     var k = 0; // rowLength counter
16     var fontSize = 20 * ratio;
17 
18     // adjust canvas height according to text byte length
19     var h = (function (text) {
20         var strLength = 0; // text byte length
21         for (var j = 0; j < text.length; j++) {
22             if (text.charCodeAt(j) > 255) {
23                 strLength += 2;
24             } else {
25                 strLength++;
26             }
27         }
28         return (strLength / rowLength + 1) * (fontSize*1.3);
29     })(text);
30     canvas.height = h * pixelRatio;
31     canvas.style.height = h + "px";
32     canvas.getContext("2d").scale(pixelRatio,pixelRatio);
33 
34     var ctx = canvas.getContext("2d");
35     ctx.font = fontSize + "px Arial";
36     var x = 10 * ratio; // X axis position of canvas
37     var y = 20 * ratio; // Y axis position of canvas
38     
39     for (var j = 0; j < text.length; j++) {
40         if (k == rowLength || k == rowLength - 1) {
41             // move forward when you encounter numbers
42             while (text.charCodeAt(j - 1) >= 48 && text.charCodeAt(j - 1) <= 57) {
43                 j--;
44             }
45             text = text.substr(0, j) + "<br>" + text.substr(j);
46             k = 0; // truncate for next line
47             j += 4; // plus the "<br>" length
48         }
49         // plus 2 bytes when you encounter chinese character
50         if (text.charCodeAt(j) > 255) {
51             k += 2;
52         } else {
53             k++;
54         }
55     }
56     var textArray = text.split("<br>"); // truncate text to array
57     // Fill text on canvas
58     for (var j = 0; j < textArray.length; j++) {
59         ctx.fillText(textArray[j], x, y);
60         y += 25 * ratio;
61     }
62     return canvas;
63 }

 

 

 參考:(這篇文章寫得很好,能夠看看,不過須要注意提到的backingStorePixelRatio已經棄用)app

www.html5rocks.com/en/tutorials/canvas/hidpi/測試

https://stackoverflow.com/questions/15661339/how-do-i-fix-blurry-text-in-my-html5-canvasspa

https://stackoverflow.com/questions/24332639/why-context2d-backingstorepixelratio-deprecatedcode

相關文章
相關標籤/搜索