我会定义一个文本框(单行)
默认情况下,字符大小为16(举例)
当文本变得比文本框大时,我不希望它换行或文本框变大,我希望文本大小适合文本框的最大大小。文本。当文本恢复到较小尺寸时,它可以恢复其初始尺寸(在我们的示例 16 中)。可能管理最小尺寸
如果你有想法,我会采纳:)
提前致谢
测试用例:http://jsfiddle.net/Da7SP/273/
// initialize fabric canvas and assign to global windows object for debug
var canvas = window._canvas = new fabric.Canvas('c');
// ADD YOUR CODE HERE
var canvas = window._canvas = new fabric.Canvas('c');
var t1 = new fabric.Textbox('My Text', {
width: 200,
top: 5,
left: 5,
fontSize: 16,
textAlign: 'center'
});
var t2 = new fabric.Textbox('My text is longer, but I do not want the box to grow, or the text to wrap. I only want the text to fit the available size', {
width: 200,
height: 200,
top: 250,
left: 5,
fontSize: 16,
textAlign: 'center'
});
canvas.add(t1);
canvas.add(t2);
一个小视频来解释我想要什么:
当文本大于文本框时,我希望文本大小适合文本框的最大大小。
这是一个可以复制你的想法的基本小提琴。 要点是,您有一个在每次文本更改时触发的事件,并且可用于在渲染文本框之前执行某些操作。
在这种情况下,我根据添加到文本框中的名为
fixedWidth
的非标准参数缩小字体大小
// ADD YOUR CODE HERE
var canvas = new fabric.Canvas('c');
var t1 = new fabric.Textbox('MyText', {
width: 150,
top: 5,
left: 5,
fontSize: 16,
textAlign: 'center',
fixedWidth: 150
});
canvas.on('text:changed', function(opt) {
var t1 = opt.target;
if (t1.width > t1.fixedWidth) {
t1.fontSize *= t1.fixedWidth / (t1.width + 1);
t1.width = t1.fixedWidth;
}
});
canvas.add(t1);
canvas {
border: 1px solid #999;
}
<script src="https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>
这里有一个与https://stackoverflow.com/a/41335051/1469525类似的答案,但此示例将 fontSize 修改为 maxFontSize (初始 fontSize)。这允许文本缩小然后恢复到原始大小,并防止换行。
(注意,如果你使用这个,你必须找到一种方法来阻止用户使用
enter
键。我放入了一个检查,如果检测到回车键,基本上会取消它。我的应用程序实际上有一个单独的表单来输入文本,这样我就可以通过普通的 JavaScript 来控制预防。我不太确定当画布元素可编辑时如何直接在画布元素上执行此操作,如下所示...)
var canvas = new fabric.Canvas('c');
var t1 = new fabric.Textbox('MyText', {
width: 150,
top: 5,
left: 5,
fontSize: 16,
textAlign: 'center',
maxFontSize: 16,
});
canvas.on('text:changed', function(opt) {
var t1 = opt.target;
if (t1.text.match(/[\r\n]/)) return;
t1.set({
fontSize: t1.maxFontSize,
});
while (t1._textLines.length > 1) {
t1.set({
fontSize: t1.fontSize - 1,
});
}
});
canvas.add(t1);
canvas {
border: 1px solid #999;
}
<script src="https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>
解决方案可能是创建一个新的 Fabric 类来扩展 Fabric.Textbox 类。这是一个例子:
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,
});