【问题标题】:HTML5 Canvas and ugly text-borderHTML5 Canvas 和丑陋的文本边框
【发布时间】:2013-04-08 17:27:58
【问题描述】:

我正在寻找一种在 HTML5 画布中呈现带有黑色边框的白色文本的方法。 我没有找到获得漂亮结果的解决方案,尝试了一些不同的方法(shadow、strokeText、...),结果总是很差(可能是因为 AA)。

这里是我要复制的基地:

你可以在这里看到我的测试:http://jsfiddle.net/7H79m/

ctx.font         = "12px Arial";
ctx.textBaseline = "top"; 
ctx.fillStyle    = "white";
ctx.strokeStyle  = "black";
ctx.lineWidth    = 2;

ctx.strokeText( "HappyEnd", x, y );
ctx.fillText( "HappyEnd", x, y );

如果您知道解决方案,请分享! :)

【问题讨论】:

    标签: javascript html canvas


    【解决方案1】:

    您将无法通过文本的内置描边效果获得准确的结果,因为由于子像素问题,文本渲染目前在各种浏览器中有点马马虎虎 (IMO)(请参阅Chrome 与 FF)。

    不过,您可以通过这种方式模拟笔触(在 FF21 中渲染):

    //Force anti-alias
    ctx.translate(0.5, 0.5);
    
    //...
    //Create stroke effect:
    ctx.fillStyle    = "black";
    ctx.fillText( "HappyEnd", x-1, y );
    ctx.fillText( "HappyEnd", x,   y-1 );
    ctx.fillText( "HappyEnd", x+1, y );
    ctx.fillText( "HappyEnd", x,   y+1 );
    
    //draw normal text
    ctx.fillStyle    = "white";
    ctx.fillText( "HappyEnd", x, y );    
    

    如需完整修改,请click here。

    当然,你总是可以将“大纲”合并到一个函数中:

    function outlineText(ctx, color, txt, x, y) {
        ctx.fillStyle    = color;
        ctx.fillText( txt, x-1, y );
        ctx.fillText( txt, x,   y-1 );
        ctx.fillText( txt, x+1, y );
        ctx.fillText( txt, x,   y+1 );
    }
    

    或者改为扩展画布上下文:

    if (CanvasRenderingContext2D != 'undefined') {
        CanvasRenderingContext2D.prototype.outlineText = 
            function outlineText(txt, x, y) {
                this.fillText( txt, x-1, y );
                this.fillText( txt, x,   y-1 );
                this.fillText( txt, x+1, y );
                this.fillText( txt, x,   y+1 );
            }
    }
    

    用法:

    ctx.outlineText("HappyEnd", x, y);
    

    查看incorporated in your example here的使用实例。

    【讨论】:

    • 我在 Firefox 中使用了你的代码,在 Chrome 中使用了另一个代码(不好做一些检查取决于浏览器..)。谢谢。
    【解决方案2】:

    [编辑以尝试不同的效果]

    这里尝试使用多个阴影来固化 AA

    http://jsfiddle.net/m1erickson/BSU7P/

    <!doctype html>
    <html>
    <head>
    <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    
    <style>
        body{ background-color: ivory; }
        canvas{border:1px solid red;}
    </style>
    
    <script>
    $(function(){
    
        var canvas = document.getElementById('canvas');
        var ctx    = canvas.getContext('2d');
    
        // Load background
        var bg = new Image();
        bg.onload = function() {
            canvas.width  = this.width;
            canvas.height = this.height;
            ctx.drawImage(this, 0, 0);
            process();
        };
        bg.src = "http://upload.robrowser.com/bg-test-text.jpg";
    
    
        function process() {
            var x = canvas.width /2;
            var y = canvas.height/2;
    
            ctx.font="12px Arial";
    
            try1(x,y);
            try2(x,y+20);
        }
    
        function try1(x,y){
        multiShadow("HappyEnd",x,y,0,-1,0);
        multiShadow("HappyEnd",x,y,0,1,0);
        multiShadow("HappyEnd",x,y,-1,0,0);
        multiShadow("HappyEnd",x,y,1,0,0);
        ctx.fillStyle="white";
        ctx.strokeStyle="black";
        ctx.strokeText("HappyEnd",x,y);
        ctx.fillText("HappyEnd",x,y);
        }
    
        function try2(x,y){
        multiShadow("HappyEnd",x,y,0,-1.5,8);
        multiShadow("HappyEnd",x,y,0,1.5,8);
        multiShadow("HappyEnd",x,y,-1.5,0,8);
        multiShadow("HappyEnd",x,y,1.5,0,8);
        ctx.fillStyle="white";
        ctx.fillText("HappyEnd",x,y);
        }
    
    
        function multiShadow(text,x,y,offsetX,offsetY,blur){
            ctx.textBaseline = "top"; 
            ctx.lineWidth    = 1;
            ctx.shadowColor = '#000';
            ctx.shadowBlur    = blur;
            ctx.shadowOffsetX = offsetX;
            ctx.shadowOffsetY = offsetY;
            ctx.fillStyle="black";
            ctx.fillText( "HappyEnd", x, y ); 
        }
    
    }); // end $(function(){});
    </script>
    
    </head>
    
    <body>
    
        <canvas id="canvas" width=300 height=300></canvas>
    
    </body>
    </html>
    

    【讨论】:

    • 这是我以前做过的,但不是我要搜索的:jsfiddle.net/gXqdd/3
    • 这是另一个尝试使用多个阴影来固化 AA
    • 太糟糕了,我不能接受两个答案,我 +1 你的帖子,因为我用它来生成文本以防 Chrome(找不到更好的方法),谢谢。
    【解决方案3】:

    嗯,总是模糊不清:

    ctx.shadowColor = "#000";
    ctx.shadowOffsetX = 0;
    ctx.shadowOffsetY = 0;
    ctx.shadowBlur = 5;
    

    【讨论】:

    • 是的,我已经测试过了。它给出了一个阴影,而不是真正的边框,并且 chrome 和 firefox 之间的结果太不同了(我在 Firefox 上看不到阴影)。
    【解决方案4】:

    这是我的尝试。我基本上试图将笔画缩小 1 个像素,并将笔画放在填充内。唯一的问题是很难把它全部集中起来

    // Create canvas, add it to body.
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext('2d');
    document.body.appendChild(canvas);
    
    // Load background
    var bg = new Image();
    bg.src = "http://upload.robrowser.com/bg-test-text-original.jpg";
    bg.onload = function () {
        canvas.width = this.width;
        canvas.height = this.height;
        ctx.drawImage(this, 0, 0);
        process();
    };
    
    // Do whatever you want here
    function process() {
        var x = 62;
        var y = 30;
    
        ctx.font = "12px Arial";
        ctx.textBaseline = "top";
        ctx.fillStyle = "white";
        ctx.strokeStyle = "black";
        ctx.lineWidth = 2;
    
        ctx.font = "11.75px Arial";
        ctx.strokeText("HappyEnd", x, y);
    
        ctx.font = "12px Arial";
        ctx.fillText("HappyEnd", x, y);
    }
    

    【讨论】:

    • 不抱歉,结果和我第一次尝试一样差:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-19
    相关资源
    最近更新 更多