Drawing text with an outer stroke with HTML5's

2020-02-26 06:24发布

I'm currently using HTML5's canvas to render a number of strings using the fillText method. This works fine, but I'd also like to give each string a 1px black outer stroke. Unfortunately the strokeText function seems to apply an inner stroke. To counter this, I've written a drawStrokedText function that achieves the effect I'm after. Unfortunately it's horrible slow (for obvious reasons).

Is there a fast, cross-browser way of achieving a 1px outer stroke using native canvas functionality?

drawStrokedText = function(context, text, x, y)
{
    context.fillStyle = "rgb(0,0,0)";
    context.fillText(text, x-1, y-1);
    context.fillText(text, x+1, y-1);
    context.fillText(text, x-1, y);
    context.fillText(text, x+1, y);
    context.fillText(text, x-1, y+1);
    context.fillText(text, x+1, y+1);

    context.fillStyle = "rgb(255,255,255)";
    context.fillText(text, x, y);
};

Here's an example of the effect at work:

enter image description here

4条回答
倾城 Initia
2楼-- · 2020-02-26 06:34

Simon's answer is a good solution, yet it may have mitering glitches in some cases, especially with capital 'M', 'V', & 'W':

drawStroked("MVW", 50, 150);

http://jsfiddle.net/hwG42/1/

In this case, it's best to utilize:

ctx.miterLimit=2;

http://jsfiddle.net/hwG42/3/

Best of luck!

查看更多
孤傲高冷的网名
3楼-- · 2020-02-26 06:45

For a smooth shadow you can try this

ctx.beginPath();
ctx.fillStyle = 'white';
ctx.font = "bold 9pt Tahoma";
ctx.shadowBlur = 3;
ctx.textAlign = "center";
ctx.shadowColor = "#000000";
ctx.shadowOffs = 0;                 
ctx.fillText('www.ifnotpics.com', 100, 50);        
ctx.closePath();
查看更多
别忘想泡老子
4楼-- · 2020-02-26 06:47

The above answers are great, using some of these solutions* and some of my own ideas, I made a quick reference and some creative alternatives in the below fiddle.

*All credits given where due in the fiddle code

drawStrokedText   ( text, x, y );
drawShadowedText  ( text, x, y, shadowBlur);
drawGlowingText   ( text, x, y, glowColorHex, glowDistance);
drawBlurredText   ( text, x, y, blurAmount);
drawReflectedText ( text, x, y, reflectionScale, reflectionOpacity);

https://jsfiddle.net/vtmnyea8/

Output of the fiddle:

Output of the below fiddle

What it supports:

  • Outline text
  • Shadow text
  • Glowing text
  • Blurred text
  • Reflected text

Some performance metrics:

Considering using this in a game or at high frame rates? Check out this jsperf using the above methods.

https://jsperf.com/various-text-effects-html5-2d-context

查看更多
爱情/是我丢掉的垃圾
5楼-- · 2020-02-26 06:51

What's wrong with stroke? Since half the stroke will be outside of the shape, you can always draw the stroke first with a line width of double what you want. So if you wanted a 4px outer stroke you could do:

function drawStroked(text, x, y) {
    ctx.font = '80px Sans-serif';
    ctx.strokeStyle = 'black';
    ctx.lineWidth = 8;
    ctx.strokeText(text, x, y);
    ctx.fillStyle = 'white';
    ctx.fillText(text, x, y);
}


drawStroked("37°", 50, 150);

Which makes:

enter image description here

live fiddle here: http://jsfiddle.net/vNWn6/


IF that happens to not look as accurate at smaller text rendering scales, you can always draw it large but scale it down (in the above case you'd do ctx.scale(0.25, 0.25))

查看更多
登录 后发表回答