I've created a Textbox object with width 400px

When entering text that doesn't have any newlines, it expands the Textbox beyond 400px

Not sure if this is intended behaviour
If it is, would be great to be able to pass in a property to preserve the width and force the text to a newline
Textbox has a minimum width that is the length of the biggest word.
Textbox split lines with fixed with, using space.
So what are you asking is reverse its behaviour.
Thanks for the quick response @asturur!
My thinking is that when someone defines the bounding-box, they've decided "I only want text to appear in this area"
So if they drop in text like a link, it's expanding the box, even though they've already decided what width they'd like.
Is it possible to have it limit the width to what's defined, rather than automatically expanding it?
Maybe adding a limit to the width is possible.
But where would go the extra text?
2015-07-30 17:10 GMT+02:00 Oliver Nassar [email protected]:
Thanks for the quick response @asturur https://github.com/asturur!
My thinking is that when someone defines the bounding-box, they've decided
"I only want text to appear in this area"So if they drop in text like a link, it's expanding the box, even though
they've already decided what width they'd like.Is it possible to have it limit the width to what's defined, rather than
automatically expanding it?—
Reply to this email directly or view it on GitHub
https://github.com/kangax/fabric.js/issues/2376#issuecomment-126366042.
The extra text would go to the next line
we need space to split words. is an acceptable requirement i think. don't you?
With html/css, you use the word-wrap: break-word property
Here's before: https://i.imgur.com/ElaH8zI.png
Here's after: https://i.imgur.com/PLkbom1.png
Here's the fiddle: https://jsfiddle.net/nkgmr06a/
There's also an option of reducing text size when it doesn't fit. That's what Apple's Keynote does, for example.
Sent from my iPad
On Jul 30, 2015, at 11:28 AM, Oliver Nassar [email protected] wrote:
With html/css, you use the word-wrap: break-word property
Here's before: https://i.imgur.com/ElaH8zI.png
Here's after: https://i.imgur.com/PLkbom1.pngHere's the fiddle: https://jsfiddle.net/nkgmr06a/
—
Reply to this email directly or view it on GitHub.
@kangax The reducing text size is probably the best solution. Working on trying to figure that in to an app I am making using Fabric.
@kangax what do you think? I think it makes sense for the text to wrap to the next line rather than lowering the font size (especially if the size has been explicitly defined)
@onassar I think so too; especially if the size is explicitly defined (and it always is; whether by user or through default value)
@jafferhaider @inssein what do you think?
I am away on vacation right now, but the behaviour that @onassar described originally is what is supposed to happen. The box has a fixed width and should never change. If that doesn't work, it's a bug I haven't seen in my implementation.
Furthermore, I think we should add the option to lower font size instead of adding lines, that was something I was hoping to implement later down the road.
Ah wait a minute, I just realized that there were no spaces. Currently minimum width is longest word. We could add word breaking, but I think the current implementation is already complex due to the way we store metadata about the text (formatting and style).
I think word-breaking makes sense, since that would mimic the behaviour of css (see here: https://jsfiddle.net/nkgmr06a/). How tough is something like this?
Any movement here?
@onassar we could certainly add a different word-wrap strategy, but I don't have the time in the near future to implement it.
Thanks @inssein
Any chance anyone else has some bandwidth? Would be happy to help test things out
@onassar In my original implementation I had written word wrapping; a long word would get wrapped just like other text. I'd go with that behaviour instead of reducing font size. In general I believe the text box should only wrap lines and not mess with any other property of the text entered by the user. That is what text box controls in HTML and Flash do. The Keynote behaviour that @kangax mentions makes a lot of sense within the context of a presentation making application, but I think our Textbox class should be more general purpose.
I'm on vacation this week. I haven't looked at the formatting and styling code yet which seems to have made things more complicated. I'd definitely want to fix this soon.
Sure, I'm ok with word wrapping for now
This adds word wrapping, i cannot push it because i have first to merge the stupid bug i introduced yesterday.
_wrapLine: function(ctx, text, lineIndex) {
var lineWidth = 0,
lines = [],
line = '',
words = text.split(' '),
word = '',
letter = '',
offset = 0,
infix = ' ',
wordWidth = 0,
infixWidth = 0,
+ letterWidth = 0,
largestWordWidth = 0;
for (var i = 0; i < words.length; i++) {
word = words[i];
+ lineWidth += infixWidth;
+ if (this.breakWords) {
+ word = word.split('');
+ while (word.length) {
+ letterWidth = this._getWidthOfChar(ctx, word[0], lineIndex, offset);
+ if (lineWidth + letterWidth > this.width) {
+ lines.push(line);
+ line = '';
+ lineWidth = 0;
+ }
+ line += word.shift();
+ offset++;
+ lineWidth += letterWidth;
+ }
+ }
+ else {
wordWidth = this._measureText(ctx, word, lineIndex, offset);
- lineWidth += infixWidth + wordWidth;
+ lineWidth += wordWidth;
+ }
if (lineWidth >= this.width && line !== '') {
lines.push(line);
line = '';
lineWidth = wordWidth;
}
if (line !== '' || i === 1) {
line += infix;
}
line += word;
offset += word.length;
infixWidth = this._getWidthOfChar(ctx, infix, lineIndex, offset);
offset++;
// keep track of largest word
if (wordWidth > largestWordWidth && !this.breakWords) {
largestWordWidth = wordWidth;
}
}
i && lines.push(line);
if (largestWordWidth > this.dynamicMinWidth) {
this.dynamicMinWidth = largestWordWidth;
}
return lines;
},
Awesome work @asturur
Happy to give it a go and test once it's merged in
Update this thread once the bug is fixed?
Based on @asturur work with a fix to only use the break word function if the word is greater than the textbox width.
fabric.Textbox.prototype._wrapLine = function(ctx, text, lineIndex) {
var lineWidth = 0,
lines = [],
line = '',
words = text.split(' '),
word = '',
letter = '',
offset = 0,
infix = ' ',
wordWidth = 0,
infixWidth = 0,
letterWidth = 0,
largestWordWidth = 0;
for (var i = 0; i < words.length; i++) {
word = words[i];
wordWidth = this._measureText(ctx, word, lineIndex, offset);
lineWidth += infixWidth;
// Break Words if wordWidth is greater than textbox width
if (this.breakWords && wordWidth > this.width) {
line += infix;
var wordLetters = word.split('');
while (wordLetters.length) {
letterWidth = this._getWidthOfChar(ctx, wordLetters[0], lineIndex, offset);
if (lineWidth + letterWidth > this.width) {
lines.push(line);
line = '';
lineWidth = 0;
}
line += wordLetters.shift();
offset++;
lineWidth += letterWidth;
}
word = '';
} else {
lineWidth += wordWidth;
}
if (lineWidth >= this.width && line !== '') {
lines.push(line);
line = '';
lineWidth = wordWidth;
}
if (line !== '' || i === 1) {
line += infix;
}
line += word;
offset += word.length;
infixWidth = this._measureText(ctx, infix, lineIndex, offset);
offset++;
// keep track of largest word
if (wordWidth > largestWordWidth && !this.breakWords) {
largestWordWidth = wordWidth;
}
}
i && lines.push(line);
if (largestWordWidth > this.dynamicMinWidth) {
this.dynamicMinWidth = largestWordWidth;
}
return lines;
};
Usage:
var breakingTextbox = new fabric.Textbox(longText, {
width: 200,
breakWords: true
});
i think that css propery breakwords, break the words always and they wanted a similar behavior.
I do not really like word breaking.
Depends on the use case. Its required for our use-case (fixed width textbox in canvas that the text should remain in, its okay if it goes beyond the height, but not the width) and we were looking at dropping Fabric entirely because it didnt provide this, which would have been a shame considering how many awesome features it provides.
This provides similar functionality to the word-wrap: break-word, the difference between it and your original code is that it prioritizes breaking at space first, then breaking the word only if it has to.
Did you manage to solve the multiple space issue with textbox?
What multiple space issue?
using word break having mulitple spaces between words always gave me weird
results with cursor position, even more with with textAlign justify.
2015-09-18 9:26 GMT+02:00 Jordan Hess [email protected]:
What multiple space issue?
—
Reply to this email directly or view it on GitHub
https://github.com/kangax/fabric.js/issues/2376#issuecomment-141369351.
Ohyeah, cursor is full on broken in the Textbox, but thats even without wordbreak, although we are using Google Webfonts inside it.
Don't think the cursor issues are specifically wordbreak or space related, something else is going on. Haven't had time to look into the cursor problem myself yet, Was hoping someone else had already been looking into it and had code that was close like yours.
lets talk about normal browser integrates fonts.
it should behave normally but not very good with justify and more than one spaces.
Any progress here by chance?
Is this feature still under development?
is deployed, and in development as anything else here.
the word-breaking did not go in.
On Jul 14, 2016 4:38 PM, "Marcin" [email protected] wrote:
Is this feature still under development?
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
https://github.com/kangax/fabric.js/issues/2376#issuecomment-232684647,
or mute the thread
https://github.com/notifications/unsubscribe/ABI4QHzkIDlli3Ye3j49nZxk_4S0ubpvks5qVknvgaJpZM4Fi0qx
.
Is there any plan to introduce worb-breaking? If not, I will rely on @jojobyte's code.
that code runs ok. we are not planning to introduce now. i m alone with
development and bugfixing i need to clear old bugs before thinking of new
features. otherwise bugs stacks one over anothet
On Jul 15, 2016 10:51 AM, "Marcin" [email protected] wrote:
Is there any plan to introduce worb-breaking? If not, I will rely on
@jojobyte https://github.com/jojobyte's code.—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
https://github.com/kangax/fabric.js/issues/2376#issuecomment-232897469,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABI4QJFWfbIqQ5ZonimN3u6MqZCoaCqJks5qV0oSgaJpZM4Fi0qx
.
@jojobyte's code above did not work correctly (it resulted in weird line shifts and inconsistent cursor position).
I have managed to fix it (patched the _wrapLine method based on it's last version - fabric 1.6.4):
fabric.Textbox.prototype._wrapLine = function(ctx, text, lineIndex) {
var lineWidth = 0,
lines = [],
line = '',
words = text.split(' '),
word = '',
offset = 0,
infix = ' ',
wordWidth = 0,
infixWidth = 0,
letterWidth = 0,
largestWordWidth = 0,
lineJustStarted = true,
additionalSpace = this._getWidthOfCharSpacing();
for (var i = 0; i < words.length; i++) {
word = words[i];
wordWidth = this._measureText(ctx, word, lineIndex, offset);
offset += word.length;
// Break Words if wordWidth is greater than textbox width
if (this.breakWords && wordWidth > this.width) {
var wordLetters = word.split('');
while (wordLetters.length) {
letterWidth = this._getWidthOfChar(ctx, wordLetters[0], lineIndex, offset);
if (lineWidth + letterWidth > this.width) {
lines.push(line);
line = '';
lineWidth = 0;
}
line += wordLetters.shift();
offset++;
lineWidth += letterWidth;
}
word = '';
} else {
lineWidth += infixWidth + wordWidth - additionalSpace;
}
if (lineWidth >= this.width && !lineJustStarted) {
lines.push(line);
line = '';
lineWidth = wordWidth;
lineJustStarted = true;
}
else {
lineWidth += additionalSpace;
}
if (!lineJustStarted) {
line += infix;
}
line += word;
infixWidth = this._measureText(ctx, infix, lineIndex, offset) + additionalSpace;
offset++;
lineJustStarted = false;
// keep track of largest word
if (wordWidth > largestWordWidth) {
largestWordWidth = wordWidth;
}
}
i && lines.push(line);
if (largestWordWidth > this.dynamicMinWidth) {
this.dynamicMinWidth = largestWordWidth - additionalSpace;
}
return lines;
};
I also had to slightly change _initDimensions (compare it with original):
fabric.Textbox.prototype._initDimensions = function(ctx) {
if (this.__skipDimension) {
return;
}
if (!ctx) {
ctx = fabric.util.createCanvasElement().getContext('2d');
this._setTextStyles(ctx);
}
// clear dynamicMinWidth as it will be different after we re-wrap line
this.dynamicMinWidth = 0;
// wrap lines
this._textLines = this._splitTextIntoLines();
// clear cache and re-calculate height
this._clearCache();
this.height = this._getTextHeight(ctx);
};
Lastly, passing breakWords: true as a field in options object to Textbox constructor seems to be ignored (it is not present on the instance). That's why it needs to be set explicitly on Textbox's instance:
var breakingTextbox = new fabric.Textbox(...)
breakingTextbox.breakWords = true;
See this fiddle.
Should it be accepted, I can send a PR later.
That jsfiddle looks good, @belfz! Would be great to see this make its way in.
+1
I believe @belfz 's workaround no longer works on the latest version of Fabric (tested on 1.7.11). However the workaround here by @asturur on stack overflow works.
it requires some adaption at least.
in 2.0 for sure not.
Hi. Any news on this feature for fabric 2.0? I am attempting to adapt the code posted above, but I'm not sure how the new _measureChar function works. That's the main thing I'm missing
is not in the plan currently. we are talking about word breaking right?
On Oct 9, 2017 20:03, "Adam Gaskins" notifications@github.com wrote:
Hi. Any news on this feature for fabric 2.0?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/kangax/fabric.js/issues/2376#issuecomment-335238457,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABI4QBp1g3HpU9h3NH42vvl3xBBxQv64ks5sql_5gaJpZM4Fi0qx
.
Right.
I'd just fork it and add the feature myself but, like I said, I got stuck on replacing _getWidthOfChar with _measureChar.
I have successfully implemented breakword property in textbox of fabric 1.7 but for enhancing feature I have to upgrade fabricjs from 1.7 to 2. In fabricjs 2 Breakword property is not their, I want same behaviour of breakword property in fabricjs 2.
any solution for the same, any suggestion would be appreciated
Here's my attempt at breakWords for fabric 2.0 https://jsfiddle.net/jjwilly16/sd03g4t4/. It works well for the most part, but I can still break it by adding a lot of spaces.
Hope this helps someone.
This would be awesome! Unfortunately the fiddles contains a few bugs.
Here's a screenshot of what I mean:

anyone did it for version2? with the problem that are above?
@fahadnabbasi Try #4513
@njofce thanks but that would lead to the same problem like wrong cursor position, wrong selection rendering
Why you close this issue, the question is still there.
This would be awesome! Unfortunately the fiddles contains a few bugs.
- Overflowing text is pushed to start at the row above ignoring that rows space, ideally it should stay on it's own row and break word from there.
- The cursor is not in the correct position, one character to the right, most likely because of the ignored space.
- Selection "races" ahead of mouse position increasingly with the amount of text selected.
Here's a screenshot of what I mean:
I got the same effect.

This would be awesome! Unfortunately the fiddles contains a few bugs.
- Overflowing text is pushed to start at the row above ignoring that rows space, ideally it should stay on it's own row and break word from there.
- The cursor is not in the correct position, one character to the right, most likely because of the ignored space.
- Selection "races" ahead of mouse position increasingly with the amount of text selected.
Here's a screenshot of what I mean:
@jjwilly16
If anyone is still interested in this feature, I think I have some of the above issues fixed. I've updated my fiddle https://jsfiddle.net/jjwilly16/sd03g4t4/. This will work with version 2.6. Let me know if it still sucks
@jjwilly16 awesome, found this which seems a bit off:

Might this already been fixed in this update? #5402
@Tsourdox Yeah, I thought #5479 was a possible fix for this, but I get lots of weird cursor behavior when using the splitByGrapheme option.
i have an open branch to fix splitByGrapheme
The selection issues is still there, I can not select the last 4 letters

fabric v 2.7.0
var canvas = new fabric.Canvas(document.getElementById('c'),{
width:500,
height:500
});
var textbox = new fabric.Textbox('å‘œå‘œå‘œå‘œå‘œå‘œå‘œå‘œæ— æ— æ— æ— æ— æ— æ— æ— æ— æ— æ— æ— æ— æ— æ— æ— æ— æ— æ— æ— æ— æ— æ— æ— æ— ', {
left: 50,
top: 50,
width: 150,
fontSize: 20,
splitByGrapheme: true,
});
canvas.add(textbox).setActiveObject(textbox);
@xiangpaopao this is a different issue not related to this.
I thought i fixed it but i did not fix it enough.
Is related to splitByGrapheme: true and i need to look at it better.
I'm seeing the same thing. splitByGrapheme: true helps control the textbox width but introduces other bugs with the cursor and text rendering.
@Tsourdox Yeah, I thought #5479 was a possible fix for this, but I get lots of weird cursor behavior when using the splitByGrapheme option.
Hi ~ , Any movement , here?
As said splitByGrapheme: true isn't solving this issue
splitByGrapheme does something different, the breakWord scenario won't be supported by me for now. We have too many things to keep an eye on and as everyone of you that is trying to solve the break word issue has probably noticed, this is not plain simple
@asturur Can we do an online voting system( https://feathub.com/ Perhaps we will know the most important features that the user needs)?I just think this feature is very important.You know,it's very unfriendly to two byte word(chinese,japanese,korean),some people waiting for resolve this problem for years(from 1.0 to 2.0 ~3.0).When we copy long word from office word or txt, then paste on https://shutterstock.com, the textbox width will be very very long.
I know it's an open source project. I'm sorry to make such an unreasonable request. If it bothers you, please ignore my suggestion,sorry.
It does not bother me, but i can't support this feature.
Adding to the code the knowloedge to split words only when needed, is harder than it looks.
splitByGrapheme now works and solve the problem of asian langauges that were the users with most problems. For english/latin users that want a break-word feature they need to figure out an override somehow.
I can't, i really can't. I have 310 open issues, of which at least 30% are probably solvable. I need to write docs and examples, this problem is very far in my priority list.
Are you an asian language user? Did you try to user splitByGrapheme option?
Yes, the splitByGrapheme option, I've used it before.As mentioned above(@treyhoover), It's has many bugs now. I'll try to get around these bugs first.
Thank you for your reply.
it should not have bugs since fabric 3, if it has them you should report them.
Yes, i updated it(to 3) in my projects, it works now . Thanks a lot.
It seems somebody made a bug free implementation of it here: https://jjwilly.com/fabric-js-2-0-breakwords-implementation/
Would it be okay to add it to the library? (I can do it)
As mentioned by others, this seems to be the biggest issue with Textbox, first thing that I discovered.
You can open a PR so we can check the diffs, i always felt this feature was unnecessary, but somehow people do not think so. We also needs tests to verify we do not break it later.
Unless the amount of code added is not much, i m not against it.
@lcswillems are you thinking about creating a PR for it? Otherwise, I will make an attempt.
I also thought about adding a new property called "max-width" that would adjust the size of the container to the text but stop at the max-width. It will also solve the issue raised here: https://stackoverflow.com/questions/60411035/adjust-fabricjs-text-box-size-to-match-the-text-selection
@AdamMadrzejewski I finally don't have the time to do a PR so you can do it :)
Most helpful comment
Here's my attempt at breakWords for fabric 2.0 https://jsfiddle.net/jjwilly16/sd03g4t4/. It works well for the most part, but I can still break it by adding a lot of spaces.
Hope this helps someone.