Can I do by character text color in HTML5 Canvas?
Asked Answered
M

3

13

In HTML Canvas I can set the color of a line of text using ctx.fillStyle = 'red', which is great. What I'm trying to do is by able to set the color by letter, with only having to draw the word once.

So if the text is 'Hello different colors!', is there a way I can make the letter H red, but the rest of the text white?

Marbles answered 5/10, 2011 at 17:39 Comment(0)
W
24

I present you this workaround. Basically you output your text one char at a time, and use inbuilt measureText() function to determine the width of each letter asif it was drawn. Then we offset the position where we wanted to draw by that same amount. You can modify this snippet, to produce the effect you want.

Suppose we have HTML like so:

<canvas id="canvas" width="300" height="300"/>

And Javascript like so:

var canvas = document.getElementById("canvas");  
var ctx = canvas.getContext("2d");  

function randomColor(){
    var r = Math.floor(Math.random()*256);
    var g = Math.floor(Math.random()*256);
    var b = Math.floor(Math.random()*256);
    return "rgb("+ r + "," + g + "," + b +")";
}

function texter(str, x, y){
    for(var i = 0; i <= str.length; ++i){
        var ch = str.charAt(i);
        ctx.fillStyle = randomColor();
        ctx.fillText(ch, x, y);
        x += ctx.measureText(ch).width;
    }
}

texter("What's up?", 10, 30);

We'd get an output: Sample output

Check it out in action at jFiddle. I used latest Chrome.

Whoredom answered 5/10, 2011 at 17:52 Comment(4)
Thanks. I was hoping there was a way to do this without writing more than once, but your solution is a really good alternative, especially since it won't mess up my dynamic text sizing. Thanks.Marbles
You are welcome. And welcome to stackoverflow! Meanwhile you should mark answers that strike your fancy as accepted. ;)Whoredom
Ahh, done. I've implemented what I wanted using a modified version of this method. One thing I've noticed is that in an animation if you're going to draw each letter every frame, it will get extremely lagged in firefox (IE/Chrome were fine however). Since I wanted the first color different, I wrote the first char, then the rest.Marbles
I was in similar boat but I was trying to do multiple sizes, is this possible?Westfalen
S
5

ctx.fillStyle works as a state machine. When you say ctx.fillStyle = 'red', it will color things as red. You can do what you want by setting ctx.fillStyle = 'white', then writing the letter H, then setting ctx.fillStyle = 'red', then writing the rest of the sentence.

Swanhilda answered 5/10, 2011 at 17:46 Comment(0)
K
3

If you don't want to use a "round about way" function.

You can use gradients e.g. createLinearGradient. I figured out how to hard block the colors so there was no gradient just two blocks of color. This is what I did:

var gradient = ctx.createLinearGradient(0, 0, 300, 0);
gradient.addColorStop(0, "red");
gradient.addColorStop(0.5, "red");
gradient.addColorStop(0.5, "blue");
gradient.addColorStop(1, "blue");
ctx.fillStyle = gradient;

This code allows text to look like this and also allows for multiple colors of text on one line of text. Check out this example: w3school example. Hope this helps.

Keening answered 15/5, 2018 at 16:28 Comment(1)
Interesting approach - I played around with this and created a JSFiddle to automatically calculate the addColorStop increments: jsfiddle.net/yasuom8gMinaret

© 2022 - 2024 — McMap. All rights reserved.