[英]Drawing text with an outer stroke with HTML5's canvas
我目前正在使用 HTML5 的畫布使用 fillText 方法呈現多個字符串。 這很好用,但我也想給每個字符串一個 1px 黑色外筆划。 不幸的是,strokeText 函數似乎應用了內部筆划。 為了解決這個問題,我編寫了一個 drawStrokedText 函數來實現我想要的效果。 不幸的是,它太慢了(原因很明顯)。
有沒有一種快速、跨瀏覽器的方式來使用原生畫布功能實現 1px 的外部筆划?
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);
};
下面是一個工作效果的例子:
中風是怎么回事? 由於一半的筆畫將在形狀之外,因此您始終可以先繪制筆畫,線寬為您想要的兩倍。 所以如果你想要一個 4px 的外部筆划,你可以這樣做:
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);
這使得:
現場小提琴:http: //jsfiddle.net/vNWn6/
如果碰巧在較小的文本渲染比例下看起來不那么准確,您始終可以將其畫大但按比例縮小(在上述情況下,您會執行ctx.scale(0.25, 0.25)
)
西蒙的回答是一個很好的解決方案,但在某些情況下可能會出現斜接故障,尤其是大寫字母“M”、“V”和“W”:
drawStroked("MVW", 50, 150);
在這種情況下,最好使用:
ctx.miterLimit=2;
祝你好運!
上面的答案很棒,使用其中一些解決方案*和我自己的一些想法,我在下面的小提琴中做了一個快速參考和一些創造性的替代方案。
*在小提琴代碼中到期的所有學分
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);
// Author: Aaron Edmistone // Text effects using HTML5 Canvas with 2D Context. // https://stackoverflow.com/questions/7814398/a-glow-effect-on-html5-canvas var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); // prepare the presentation of the canvas ctx.fillStyle = 'black'; ctx.fillRect(0,0,250,450); ctx.fillStyle = 'gray'; ctx.fillRect(250,0,250,450); ctx.fillStyle = 'white'; ctx.fillRect(500,0,250,450); ctx.fillStyle = '#0066CC'; ctx.fillRect(750,0,250,450); // prepare the font and fill ctx.font = "80px Sans-serif"; ctx.fillStyle = "white"; function drawStrokedText(text, x, y) { // using the solutions from @Simon Sarris and @Jackalope from // https://stackoverflow.com/questions/7814398/a-glow-effect-on-html5-canvas ctx.save(); ctx.strokeStyle = 'black'; ctx.lineWidth = 8; ctx.lineJoin="round"; ctx.miterLimit=2; ctx.strokeText(text, x, y); ctx.fillText(text, x, y); ctx.restore(); } function drawShadowedText(text, x, y, shadowBlur = 3) { ctx.save(); ctx.shadowBlur = shadowBlur; ctx.shadowColor = "#000000"; ctx.shadowOffsetX = 4; ctx.shadowOffsetY = 4; ctx.fillText(text, x, y); ctx.restore(); } function drawGlowingText(text, x, y, glowColorHexString, glowDistance = 10) { ctx.save(); ctx.shadowBlur = glowDistance; ctx.shadowColor = glowColorHexString; ctx.strokeText(text, x, y); for(let i = 0; i < 3; i++) ctx.fillText(text, x, y); //seems to be washed out without 3 fills ctx.restore(); } function drawBlurredText(text, x, y, blur = 5) { //using technique from https://www.html5rocks.com/en/tutorials/canvas/texteffects/ ctx.save(); let width = ctx.measureText(text).width + blur * 2; ctx.shadowColor = ctx.fillStyle; ctx.shadowOffsetX = width + x + ctx.canvas.width; ctx.shadowOffsetY = 0; ctx.shadowBlur = blur; ctx.fillText(text, -width + -ctx.canvas.width, y); ctx.restore(); } function drawReflectedText(text, x, y, reflectionScale = 0.2, reflectionAlpha = 0.10) { ctx.save(); ctx.fillText(text, x, y); ctx.scale(1, -reflectionScale); ctx.globalAlpha = reflectionAlpha; ctx.shadowColor = ctx.fillStyle; ctx.shadowBlur = 15; ctx.fillText(text, x, -(y * (1 / reflectionScale))); ctx.restore(); } for(let i = 0; i < 4; i++) { drawStrokedText ("MVW", 20 + i * 250, 80 * 1); drawShadowedText ("MVW", 20 + i * 250, 80 * 2, 3); drawGlowingText ("MVW", 20 + i * 250, 80 * 3, "#FF0000", 10); drawBlurredText ("MVW", 20 + i * 250, 80 * 4, 5); drawReflectedText ("MVW", 20 + i * 250, 80 * 5, 0.5, 0.5); }
<canvas id="myCanvas" width="1000" height="500"></canvas>
考慮在游戲中或以高幀速率使用它? 使用上述方法檢查這個jsperf 。
對於平滑的陰影,你可以試試這個
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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.