关于canvas:canvas-字体自动换行-线条粗细解决1px线条模糊问题

8次阅读

共计 1797 个字符,预计需要花费 5 分钟才能阅读完成。

ctx.fillText 主动更换行

<!DOCTYPE HTML>
<html>

<head>
    <meta charset="UTF-8">
    <title>fillText Auto-wrap</title>
</head>

<body>
    <canvas id="mycanvas"> 您的浏览器不反对 canvas。</canvas>
    <br>
    <textarea id="input" row="6" col="60" style="width:300px;height: 100px;"> 文本主动换行 auto-wrap 文本主动换行 auto-wrap 文本主动换行 auto-wrap 文本主动换行 auto-wrap 文本主动换行 auto-wrap</textarea>
</body>

</html>

(function() {function writeTextOnCanvas(cns, lh, rw, text) {var cns = document.getElementById(cns);
        var ctx = cns.getContext("2d");
        var lineheight = lh;
        var text = text;

        ctx.width = cns.width;
        ctx.height = cns.height;

        ctx.clearRect(0, 0, ctx.width, ctx.height);
        ctx.font = "16px 微软雅黑";
        ctx.fillStyle = "#f00";

        function getTrueLength(str) { // 获取字符串的实在长度(字节长度)var len = str.length,
                truelen = 0;
            for (var x = 0; x < len; x++) {if (str.charCodeAt(x) > 128) {truelen += 2;} else {truelen += 1;}
            }
            return truelen;
        }

        function cutString(str, leng) { // 按字节长度截取字符串,返回 substr 截取地位
            var len = str.length,
                tlen = len,
                nlen = 0;
            for (var x = 0; x < len; x++) {if (str.charCodeAt(x) > 128) {if (nlen + 2 < leng) {nlen += 2;} else {
                        tlen = x;
                        break;
                    }
                } else {if (nlen + 1 < leng) {nlen += 1;} else {
                        tlen = x;
                        break;
                    }
                }
            }
            return tlen;
        }
        for (var i = 1; getTrueLength(text) > 0; i++) {var tl = cutString(text, rw);
            ctx.fillText(text.substr(0, tl).replace(/^\s+|\s+$/, ""), 10, i * lineheight + 50);
            text = text.substr(tl);
        }
    }
    writeTextOnCanvas("mycanvas", 22, 40, document.getElementById("input").value);
    document.getElementById("input").onkeyup = function() {writeTextOnCanvas("mycanvas", 22, 40, this.value);
    }
})();

效果图:

1px 线条设置
canvas 的线条画法不一样,canvas 的每条线都有一条有限细的“中线”,线条的宽度是从中线向两侧延长的。
如果咱们还是从像素点画一条线,那么线条的中线就会靠齐到像素的终点,
而后咱们开始画了,问题也就来了:Canvas 的线条以中线向两侧延长,而不是向某一边延长
(比方如果只是往单侧延长,那么咱们的问题就不再是问题了)
此时又有个问题:计算机不容许呈现小于 1px 的图形,所以他做了一个折中的事:把这两个像素都绘制了。
所以,如此一来,原本 1px 的线条,就成了看起来 2px 宽的线条。
失败的起因找到了:Canvas 中的 line 把中线与像素的终点对齐了,而不是像素的两头点。

总结:以上就是解决 1 像素宽度的线条带来的含糊,解决办法是在定位的时候平移半个像素就能够。然而:对于宽度较宽的线条,每一半都是像素的整数,所以您须要一个位于像素之间(即(3,1)到(3,5))的门路,而不是像素的两头。

字符间距设置
canvas.style.letterSpacing = range.value + ‘px’;

正文完
 0