Support colors for ranges in text
I often want to change a color of a single word in text. That's not currently possible. Not looking for any advanced features or more UI but this would be really handy.
Before finding this issue, I instinctively tried selecting a word and changing the text color, hoping it would apply to the selection only. If that flow worked, it wouldn't need any additional UI, to Dan's point.
Early thoughts on how it would be implemented:
- For the UI, selecting part of the text and changing the color sets it. If there are multiple colors within the text then mark the whole text as an undefined color.
- For the implementation, we should store a separate field for color ranges. This way we are backwards compatible and can only have this new field when there are color ranges.
- We need to use contentEditable magic in order to set the right colors. It’s likely going to be non trivial to get right across browsers.
Overall it’s not a trivial change but should be scoped enough to be implementable without too much risk.
Plus, we need to figure out collaboration. Maybe we just block multiple people from editing the same text element at the same time so we don’t have to merge edited ranges. Maybe we should use some sort of contenteditable wrapper that supports styles and normalizes the output?
Or… what if we rendered the wysiwyg text as transparent and just rerendered on keystroke? Then we would just use the wysiwyg to position the cursor and handle text input, which would fix all the rendering issues. (we could even manually position the cursor, which is a giant can of worms)
Or… what if we rendered the wysiwyg text as transparent and just rerendered on keystroke?
That's easy because I've recently started adding the element to elements right away.
(we could even manually position the cursor, which is a giant can of worms)
But, this is hard. We'd also need to reimplement text selection ~~and all other editor-specific behavior like jumping by word, drag & drop etc.~~ EDIT: actually, I misread your comment. You just want to hide the wysiwyg text via opacity or something. But selection rendering and stuff still aplies.
So I don't think this is the way to go.
I wonder if there is a wysiwyg editor with a JS API (with no UI) that we can use instead. That would be super useful instead of starting to implement our own or at least to consider our options.
What about Quill? It has everything, no UI and an API to use with our properties menu.
Also Slate.
Let me state that, these libraries providing an API means that we won't have to change our UI at all. It will remain the same, we will just replace our current custom editor with theirs and we will control its contents using our current properties list.
We just need to be able to change the color.. this seems a bit overkill.. no?
We just need to be able to change the color.. this seems a bit overkill.. no?
Well, today is the color, tomorrow is the font, opacity, size, etc.
But regardless of that, the fact remains that that would be a tricky addition and if we can get away with a ready library then why not?
Quill has UI (which is the point), and the base lib is 216Kb.
Though we may indeed end up needing to use a lib like that.
@dwelle you can disable all the UI. For bundle sizes, we may need to play around a bit, maybe they support tree-shaking.
@kbariotis I'm not just talking about the toolbar, but the whole point of editors is they provide their own UI for actually writing, which is the bulk of the library. The toolbar is minimal.
Some notes here after taking a look at the current implementation:
- For supporting different color in ranges, we will have to manipulate the DOM and create different element per range e.g.
<span style="color:red">this is red text,</span> <span style="color:blue">this is blue text</span> - At the moment, our Text Element supports raw text, not HTML. When you create a text element, we are inserting a contenteditable element, then we extract the raw text from it and applying it to the scene
- Applying it to the scene means, rendering it on the canvas. A question raises here that if start storing HTML representation of an element, how are we painting that to the canvas.
We could replace the font/text/fill/etc properties with a single content array consisting of objects containing those keys, which could be translated back and forth from the HTML representation and more easily rendered to the canvas.
I was just looking for this feature! I would love to be able to make specific words in a block of text a certain color for emphasis.
@kyldvs

Working on the edge cases in my PR, do we want to support creating a new color range by selecting a stroke color when you don't have a range selected?
The behaviour right now is to change the whole text to that color, do we want to preserve this behaviour or go with the above?
Example of what I mean in google docs below:
https://user-images.githubusercontent.com/9257001/167291645-3cad16db-3bc5-4748-9532-8a83911fb519.mov
Ok I think google docs-like behaviour is what we want. This is how both miro and figma works even though it's a change in current behaviour.
Currently my workflow to manually cut out the word from the text element, apply color to it, lock the original element and try to keep position of new element same as before. I wish I could drag&drop a word out of text element and it would create a new text element automatically adding empty space in the original element and placing a new one above.
sorry for the <<bump>>
is this possible yet?
Damn, seems like a very tough nut to crack in terms of implementation. But I also tried to select a word and click the color and to my surprise that the whole sentence changed color, so I came to this issue
This is a must-have!
Mid 2024, four years later and we still don't have this basic feature... but we do have some beta AI that no one asked for...
I've found the ~~best~~ only half-sane way to do this is:
- Write as much of the sentence you can before you come to the word you want to color in it
- Make a new text box and color the single word
- Finish the sentence and rinse and repeat
- Painstakingly move the colored word into the right structure/location so the text looks natural
- Select ALL of the elements and "group" them for more easy movement in the future when everything looks "good enough"
An utterly ridiculous workflow for something that should have been a basic day 1 feature to be honest. But hey, considering Excalidraw is basically free for personal use, beggars can't be choosers can we?