During canvas initialization there's no font used on it. The text is rendered with a default one (times?)
Then i load fonts and do canvas rerender. The font is changed on the canvas but the text box remains the original size

And it fits the size only after i set different font size to the text.
Is there anyway to force rerender text selection box?
there are 2 caches:
itext/textbox/text cache that avoid the library to recalculate lot of things
and the font character cache.
Try to do:
myText._charWidthsCache = { };
myText._clearCache();
this will reset everything in a "to be calculated" state.
Please close the issue if this solve.
At what moment should i do this?
I tried to do the following: after all fonts are loaded (it happens later than all the text layers are rendered)
I call a method that iterates through all the objects and clears cache as you pointed
canvas.forEachObject(function (o) {
if (o.type == 'text')
{
o._charWidthsCache = { };
o._clearCache();
}
});
But after this when i click on the text - the box size is still the same (the size of original default text)
are you on text or textbox?
Text, fabric.Text
vitalniko, from what i understand, you do not have any issue with the font itself, but with the box around it.
You can just call text.setCoords() before calling canvas.renderAll() to fix this issue
i'm sorry the text rendering methods are mess for me.
myText._forceClearCache = true,
this will return true at myText.shouldClearCache() that will trigger myText.initDimensions();
render: function(ctx, noTransform) {
// do not render if object is not visible
if (!this.visible) {
return;
}
ctx.save();
this._setTextStyles(ctx);
if (this._shouldClearCache()) {
this._initDimensions(ctx);
}
if (!noTransform) {
this.transform(ctx);
}
if (this.transformMatrix) {
ctx.transform.apply(ctx, this.transformMatrix);
}
if (this.group && this.group.type === 'path-group') {
ctx.translate(this.left, this.top);
}
this._render(ctx);
ctx.restore();
},
myText._forceClearCache = true,
Doesn't help (
text.setCoords()
neither (
seteCoords for sure wont't. it recalculates the mouse interaction points based on some parameters.
What you need is to recalculate width and height.
can you make a fiddle? i'm sure is possible to force a recalculation
I made a fiddle
http://jsfiddle.net/vital_n/205n1qfe/14/
Select the text string and observe the text box is the original font size
http://jsfiddle.net/asturur/205n1qfe/15/
this should work anyway
txt._forceClearCache = true;
but it doesn't.
Thanks a lot!
@asturur Probably the connected issue:
1) Change the text layer fontFamlly or fontSize
2) Move cursor over the layer - cursor becomes "move" and click reacts only over the old dimensions
I do ._forceClearCache = true;
._initDimensions();
after setting layer props. But it doesn't help
thx @asturur, worked like a charm. also @vniko for the initDimensions
... EDIT
I tested a bit the part of the dimensios part doesnt work... :(
on what issue/ version if fabricjs
I have a similar problem, when I'm updating some properties of the textbox, for example - fill.
After I call renderAll(), the text is not updating.
To update it, I do
mytext.dirty = true;
to mark the cache of the object as dirty when the object is changed. It solves my problem.
The font loading is asyncronous.
You should use a library that clearly warns you when the font is loaded and then create your text object.
I had the same problem. It was solved by loading fonts before using it in canvas
@vitalniko @asturur @eugene-ilyin
https://github.com/typekit/webfontloader - I have used this library from Google
When working with custom fonts on a fabric canvas, it is recommended to
use a font preloader. Not doing so is likely to cause texts that are
imported onto the canvas to be rendered with a wrong (default) font. It
can also cause you to see a FOUT (Flash of Unstyled Text) right after
changing the font of a text. The reason behind this is that the browser
will only load a font after it is used in the DOM. Preloading fonts
prevents this from happening.
I am having the same problem with 2.2.2.
I use Google's WebFontLoader. My users are able to add text with custom fonts to a fabric js canvas. This preloads the font.
This design is then saved. It can also be reloaded at a later time. This loads the fonts after the canvas has already been initialized. Read: the fonts aren't preloaded.
When the fonts aren't preloaded, the selection boxes will be wrong. The cursor will appear in the wrong location. Upon resizing the selection box, parts of the text may even become 'cut off'.
The above suggested solutions (dirty, forceClearCache, initDimensions, renderAll, etc.) do not work for me.
I realize I can rebuild my app to preload the fonts upon loading. However, Google's WebFontLoader sometimes times out for some fonts. These failed fonts can then be successfully applied, despite having failed to load. The problem is that this takes a long time, since it happens on the timeout, which is currently 500 ms. So this would mean my fabric js canvas would take 500 ms to show, in case there's a font used that 'could not be loaded'.
Decreasing the timeout would make it faster, but then I risk timing out while loading a large bunch of fonts that can be successfully loaded. Increasing the timeout will decrease said risk, but will increase the time for my fabric js canvas to init.
For this reason, I would really like a way to force fabric js to recompute its textbox selection boxes. So what can I do to force fabric js to reconsider its selection boxes for text with google fonts that were loaded but not preloaded?
Update:
I've written a function that will 'reset' the canvas, where it loads its own json if it's already been initialized in a previous call. I make this function fire on my google font load events.
Preloading custom google fonts before initting the canvas with loadFromJSON(), does not (always) work to resolve the textbox selection problem. Not when I reload my browser with CTRL+F5, anyway. It also seems other font types need to be on the canvas in order for this to go wrong.
The selection actually looks pretty good at first sight. But double clicking the text makes the cursor appear in the wrong place (not at the end of the text). When this happens, it also always follows that if you resize your selection box, text will get cut off, or go outside the selection box.
Long story short: preloading fonts before loadFromJSON() in an attempt to reinitialize goes awry, preloading fonts before add() works fine.
So I guess a workaround would be to remove/readd the textboxes. I could also ensure that loadFromJSON() is only called once: on the last event of my font loader. But the last event is a timeout event, which means the user's gotta wait for it. This is a hassle, and I'd prefer things to work cleanly.
It would help if fabric js had a native hard reset event that worked to ensure correct selection boxes for custom font text objects.
@asturur Should I create an issue for this?
if you load them, it has to work.
I updated my last comment with a bit more info while you commented. It works on the first loadFromJSON(), but not subsequent calls to it in an attempt to reinit.
can we reproduce this behaviour in some way it can be observed and understood by me too?
I will work on a reproduction, so you can see it with your own eyes. Will keep you posted.
Most helpful comment
http://jsfiddle.net/asturur/205n1qfe/15/
this should work anyway
but it doesn't.