-
-
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
feat(Textbox): min/max width #8470
Conversation
Build Stats
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated from master
@@ -59,12 +103,11 @@ export class Textbox extends IText { | |||
this._clearCache(); | |||
// clear dynamicMinWidth as it will be different after we re-wrap line | |||
this.dynamicMinWidth = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be set to the default value 2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated from master
A solution could be to create a new Fabric class that extends the Fabric.Textbox class. Here's an example: const LimitedTextbox = fabric.util.createClass(fabric.Textbox, {
onInput: function (e: any) {
const oldText = this.text;
/**
* Sometimes, when you insert a line break, it doesn't appear to Fabric as an 'insertLineBreak' but simply sets the date to null.
* Therefore, it's important to check that it's not deleting any characters, and if the date is null, it means that a new line is being inserted
*/
if (e.inputType === 'insertLineBreak' || (e.inputType !== 'deleteContentBackward' && !e.data)) {
this._textBeforeEdit = oldText;
this.hiddenTextarea.value = oldText;
this.text = oldText;
return;
} else if (e.inputType !== 'deleteContentBackward') {
if (this.width > this.maxWidth) {
this._textBeforeEdit = oldText;
this.hiddenTextarea.value = oldText;
this.text = oldText;
// If you want to enable scaling to keep writing, there are issues when you delete a portion of text and not just a single character
//
// this.fontSizeList = [...(this.fontSizeList || []), this.fontSize];
// this.fontSize *= this.maxWidth / (this.width + 1);
// this.width = this.maxWidth;
return;
}
if (this._textLines.length > this.maxLines) {
this._textBeforeEdit = oldText;
this.hiddenTextarea.value = oldText;
this.text = oldText;
return;
}
} else {
// If you want to enable scaling to keep writing, there are issues when you delete a portion of text and not just a single character
//
// const lastFontSize = this.fontSizeList?.pop();
// if (lastFontSize) {
// this.fontSize = lastFontSize;
// }
/**
* It's needed because otherwise, if I write many characters, he automatically adjusts the width even if the visible text doesn't change.
* So, every time I delete something, I reset the width.
* I do it during deletion; otherwise, if I do it in the maxWidth check, I never block it, and it would keep writing
*/
this.width = this.maxWidth;
}
this.callSuper('onInput', e);
},
});
...
textbox = new LimitedTextbox('custom text', {
maxLines: 1,
maxWidth: 100,
}); |
I will probably abandon this PR for a better design. |
Stale, can be achieved by overriding |
Motivation
#7888
#7891
Wants to limit text input
#5911
Wants to avoid the textbox going out of canvas when inputing text
#5114
Wants to wrap text when reach a certain width becase of long words
It seems that maxWidth should indeed break the words.
so while starting to implement it is fine, i don't think it closes the related issues.
Originally posted by @asturur in #7981 (comment)
closes #7888
closes #7891
closes #5911
related #1184
closes #2376
closes #5114
closes #1162
Description
port #7981
This PR supports
minWidth
maxWidth
, breaking lines to fit the size. Splitting words (word-break
) is also possible when using withsplitByGrapheme
(useminWidth
as well or set it to true after initialization).Changes
I have refactored logic not to care if
maxWidth < minWidth
. Values are not changed by fabric and everything works!maxWidth
will be overriden byminWidth
and by_actualMaxWidth
(min values + largest word) in case of conflict.Gist
In Action
splitByGrapheme + maxWidth
Fabric.React.App.Sandbox.-.Google.Chrome.2022-06-10.20-48-19.mp4
maxWidth
Fabric.React.App.Sandbox.-.Google.Chrome.2022-06-10.20-48-57.mp4
onInput + maxWidth
Fabric.React.App.Sandbox.-.Google.Chrome.2022-06-10.21-04-54.mp4