调整 fabricjs 文本框大小以匹配文本选择
Adjust fabricjs text box size to match the text selection
我有一段代码可以这样创建一个新的 Textbox
:
new fabric.Textbox('Ajouter du texte')
问题是文本框与其内容相比太小了:
如果我设置固定宽度,我会得到一些填充:
new fabric.Textbox('Ajouter du texte', {width: 350})
如何调整文本框大小以匹配文本选择大小?我找不到有关如何获取选择尺寸的任何信息。
我正在使用结构版本 4.0.0-beta.5
。
我在 TextBox 文档中进行了搜索,但没有找到任何可以根据文本大小自动调整容器的内容。
你能做的最好的事情是获取每行的大小,如果宽度总和小于最大所需值,则将宽度设置为文本框。出于某种原因,您还需要为其添加一个小宽度。
var canvas = new fabric.Canvas("canvas");
var text = new fabric.Textbox("Ajouter du texte");
var textSize = 0;
for (var i = 0; i < text._textLines.length; i++) {
textSize += text.measureLine(i).width;
}
var augmentedTextSize = textSize + 25;
if (augmentedTextSize < 500) {
text.set({ width: augmentedTextSize });
}
canvas.add(text);
canvas.renderAll();
检查这个例子:https://codesandbox.io/s/Whosebug-60411035-fabric-js-400-beta5-7s7id
如果文本框上有某种 属性 会很好,例如 "max_width",如果文本小于它,则自动调整大小以适应文本大小。
我现在保留的解决方案是逐渐增加宽度,直到不超过 1 行:
const text = new fabric.Textbox("Ajouter du texte")
while (text.textLines.length > 1) {
text.set({width: text.getScaledWidth() + 1})
}
欢迎提出更好的解决方案,以便我更新已接受的答案。
[编辑]
要使其在文本编辑期间工作:
function adjustTextWidth(evt: fabric.IEvent) {
if (evt.target instanceof fabric.IText) {
const text = evt.target.text || ""
while (evt.target.textLines.length > text.split("\n").length) {
evt.target.set({width: evt.target.getScaledWidth() + 1})
}
}
}
canvas.on("text:changed", adjustTextWidth)
[EDIT2]
我找到了实现目标的更好方法:
fabric.Textbox.prototype._wordJoiners = /[]/;
这样,space 就不会被视为单词连接符,只有当用户键入 Enter
时,文本才会中断。我还添加了这个功能来在删除文本时调整文本框的宽度:
function fitTextboxToContent(text: fabric.IText) {
const textLinesMaxWidth = text.textLines.reduce((max, _, i) => Math.max(max, text.getLineWidth(i)), 0);
text.set({width: textLinesMaxWidth});
}
我有一段代码可以这样创建一个新的 Textbox
:
new fabric.Textbox('Ajouter du texte')
问题是文本框与其内容相比太小了:
如果我设置固定宽度,我会得到一些填充:
new fabric.Textbox('Ajouter du texte', {width: 350})
如何调整文本框大小以匹配文本选择大小?我找不到有关如何获取选择尺寸的任何信息。
我正在使用结构版本 4.0.0-beta.5
。
我在 TextBox 文档中进行了搜索,但没有找到任何可以根据文本大小自动调整容器的内容。
你能做的最好的事情是获取每行的大小,如果宽度总和小于最大所需值,则将宽度设置为文本框。出于某种原因,您还需要为其添加一个小宽度。
var canvas = new fabric.Canvas("canvas");
var text = new fabric.Textbox("Ajouter du texte");
var textSize = 0;
for (var i = 0; i < text._textLines.length; i++) {
textSize += text.measureLine(i).width;
}
var augmentedTextSize = textSize + 25;
if (augmentedTextSize < 500) {
text.set({ width: augmentedTextSize });
}
canvas.add(text);
canvas.renderAll();
检查这个例子:https://codesandbox.io/s/Whosebug-60411035-fabric-js-400-beta5-7s7id
如果文本框上有某种 属性 会很好,例如 "max_width",如果文本小于它,则自动调整大小以适应文本大小。
我现在保留的解决方案是逐渐增加宽度,直到不超过 1 行:
const text = new fabric.Textbox("Ajouter du texte")
while (text.textLines.length > 1) {
text.set({width: text.getScaledWidth() + 1})
}
欢迎提出更好的解决方案,以便我更新已接受的答案。
[编辑]
要使其在文本编辑期间工作:
function adjustTextWidth(evt: fabric.IEvent) {
if (evt.target instanceof fabric.IText) {
const text = evt.target.text || ""
while (evt.target.textLines.length > text.split("\n").length) {
evt.target.set({width: evt.target.getScaledWidth() + 1})
}
}
}
canvas.on("text:changed", adjustTextWidth)
[EDIT2]
我找到了实现目标的更好方法:
fabric.Textbox.prototype._wordJoiners = /[]/;
这样,space 就不会被视为单词连接符,只有当用户键入 Enter
时,文本才会中断。我还添加了这个功能来在删除文本时调整文本框的宽度:
function fitTextboxToContent(text: fabric.IText) {
const textLinesMaxWidth = text.textLines.reduce((max, _, i) => Math.max(max, text.getLineWidth(i)), 0);
text.set({width: textLinesMaxWidth});
}