Adding Letter Spacing in HTML Canvas

前端 未结 2 1020
我在风中等你
我在风中等你 2021-01-06 06:10

I\'ve read a lot of StackOverflow answers and other pages talking about how to do letter spacing in Canvas. One of the more useful ones was Letter spacing in canvas element<

相关标签:
2条回答
  • 2021-01-06 06:35

    My answer got deleted. So, I'm using chrome and here is my complete code.

    second_image = $('#block_id').first();
    canvas = document.getElementById('canvas');
    canvas.style.letterSpacing = '2px';
    ctx = canvas.getContext('2d');
    canvas.crossOrigin = "Anonymous";
    canvasDraw = function(text, font_size, font_style, fill_or_stroke){
        canvas.width = second_image.width();
        canvas.height = second_image.height();
        ctx.clearRect(0,0,canvas.width,canvas.height);
        ctx.drawImage(second_image.get(0), 0, 0, canvas.width, canvas.height);
        //refill text
        ctx.font = font_size +'px '+ font_style + ',Symbola';
        $test = ctx.font;
        ctx.textAlign = "center";
        if(fill_or_stroke){
            ctx.fillStyle = "#d2b76d";
            ctx.strokeStyle = "#9d8a5e";
            ctx.strokeText(text,canvas.width*$left,canvas.height*$top);
            ctx.fillText(text,canvas.width*$left,canvas.height*$top);
        }
        else{
            ctx.strokeStyle = "#888888";
            ctx.strokeText(text,canvas.width*$left,canvas.height*$top);
        }
    };
    

    And you don't need to use this function this.fillTextWithSpacing. I didn't use and it worked like a charm)

    0 讨论(0)
  • 2021-01-06 06:36

    Well, I've written the code, based on the pseudocode above, and done a few comparisons by screenshotting and eyeballing it for differences (zoomed, using straight lines from eg clip boxes to compare X position and width for each character). Looks exactly the same for me, with spacing set at 0.

    Here's the HTML:

    <canvas id="Test1" width="800px" height="200px"><p>Your browser does not support canvas.</p></canvas>
    

    Here's the code:

    this.fillTextWithSpacing = function(context, text, x, y, spacing)
    {
        //Start at position (X, Y).
        //Measure wAll, the width of the entire string using measureText()
        wAll = context.measureText(text).width;
    
        do
        {
        //Remove the first character from the string
        char = text.substr(0, 1);
        text = text.substr(1);
    
        //Print the first character at position (X, Y) using fillText()
        context.fillText(char, x, y);
    
        //Measure wShorter, the width of the resulting shorter string using measureText().
        if (text == "")
            wShorter = 0;
        else
            wShorter = context.measureText(text).width;
    
        //Subtract the width of the shorter string from the width of the entire string, giving the kerned width of the character, wChar = wAll - wShorter
        wChar = wAll - wShorter;
    
        //Increment X by wChar + spacing
        x += wChar + spacing;
    
        //wAll = wShorter
        wAll = wShorter;
    
        //Repeat from step 3
        } while (text != "");
    }
    

    Code for demo/eyeball test:

    element1 = document.getElementById("Test1");
    textContext1 = element1.getContext('2d');
    
    textContext1.font = "72px Verdana, sans-serif";
    textContext1.textAlign = "left";
    textContext1.textBaseline = "top";
    textContext1.fillStyle = "#000000";
    
    text = "Welcome to go WAVE";
    this.fillTextWithSpacing(textContext1, text, 0, 0, 0);
    textContext1.fillText(text, 0, 100);
    

    Ideally I'd throw multiple random strings at it and do a pixel by pixel comparison. I'm also not sure how good Verdana's default kerning is, though I understand it's better than Arial - suggestions on other fonts to try gratefully accepted.

    So... so far it looks good. In fact it looks perfect. Still hoping that someone will point out any flaws in the process.

    In the meantime I will put this here for others to see if they are looking for a solution on this.

    0 讨论(0)
提交回复
热议问题