1

我正在寻找一种在 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 );

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

4

4 回答 4

2

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

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

快照 FF/v21

//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 );    

如需完整修改,请单击此处

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

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);

在此处查看您的示例中包含的使用示例。

于 2013-04-08T08:10:27.323 回答
1

[编辑尝试不同的效果]

这是尝试使用多个阴影来巩固 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>
于 2013-04-07T19:29:54.797 回答
0

好吧,总是模糊不清:

ctx.shadowColor = "#000";
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 5;
于 2013-04-07T19:14:16.523 回答
0

这是我的尝试。我基本上试图将笔画缩小 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);
}
于 2013-04-07T19:35:06.807 回答