-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Entering text in a Textbox object expands it when there aren't newlines #2376
Comments
Textbox has a minimum width that is the length of the biggest word. So what are you asking is reverse its behaviour. |
Thanks for the quick response @asturur! 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. 2015-07-30 17:10 GMT+02:00 Oliver Nassar [email protected]:
|
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 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
|
@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 |
@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 |
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. |
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 |
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 2015-09-18 9:26 GMT+02:00 Jordan Hess [email protected]:
|
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. |
Any progress here by chance? |
|
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 |
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
|
@xiangpaopao this is a different issue not related to this. |
I'm seeing the same thing. |
As said |
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. |
It does not bother me, but i can't support this feature. 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 |
Yes, the |
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 :) |
@asturur @ShaMan123 looks like this issue is getting some traction. Great news. We have this issue too and we're looking forward to have it fixed. |
If someone wants to recover https://jjwilly.com/fabric-js-2-0-breakwords-implementation/ this and make a PR we can talk about it. What is your use case @kirill-konshin ? can you make a small example with a gif or a clear explanation? |
Does anyone know where the issue of wrong cursor position, wrong selection rendering is tracked? I also encountered this problem, in version 5.2.4. |
I've created a
Textbox
object with width400px
When entering text that doesn't have any newlines, it expands the
Textbox
beyond400px
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
The text was updated successfully, but these errors were encountered: