Files
Fichero/web/src/fabric-object/textbox-ext.ts

90 lines
2.8 KiB
TypeScript

import * as fabric from "fabric";
interface UniqueTextboxExtProps {
fontAutoSize: boolean;
}
const TEXTBOX_PROPS: Array<keyof UniqueTextboxExtProps> = ["fontAutoSize"];
export const textboxExtDefaultValues: Partial<fabric.TClassProperties<TextboxExt>> = {
fontAutoSize: false,
};
export interface TextboxExtProps extends fabric.TextboxProps, UniqueTextboxExtProps {}
export interface SerializedTextboxExtProps extends fabric.SerializedTextboxProps, UniqueTextboxExtProps {}
export class TextboxExt<
Props extends fabric.TOptions<TextboxExtProps> = Partial<TextboxExtProps>,
SProps extends SerializedTextboxExtProps = SerializedTextboxExtProps,
EventSpec extends fabric.ITextEvents = fabric.ITextEvents,
>
extends fabric.Textbox<Props, SProps, EventSpec>
implements UniqueTextboxExtProps
{
declare fontAutoSize: boolean;
private widthBeforeEditing?: number;
constructor(text: string, options?: Props) {
super(text, options);
Object.assign(this, textboxExtDefaultValues);
this.setOptions(options);
this.setControlsVisibility({
mb: false,
mt: false,
});
}
/** Set text and reduce fontSize until text fits to the given width */
setAndShrinkText(text: string, maxWidth: number, maxLines?: number) {
const linesLimit = maxLines ?? this._splitTextIntoLines(this.text).lines.length;
let linesCount = this._splitTextIntoLines(text).lines.length;
this.set({ text });
while ((linesCount > linesLimit || this.width > maxWidth) && this.fontSize > 2) {
this.fontSize -= 1;
this.set({ text, width: maxWidth });
linesCount = this._splitTextIntoLines(text).lines.length;
}
}
/** Reduce fontSize until text fits to the given width */
shrinkText(maxWidth: number, maxLines: number) {
let linesCount = this._splitTextIntoLines(this.text).lines.length;
while ((linesCount > maxLines || this.width > maxWidth) && this.fontSize > 2) {
this.fontSize -= 1;
this.set({ width: maxWidth });
linesCount = this._splitTextIntoLines(this.text).lines.length;
}
}
override enterEditingImpl() {
super.enterEditingImpl();
this.widthBeforeEditing = this.width;
}
override exitEditingImpl() {
super.exitEditingImpl();
this.widthBeforeEditing = undefined;
}
override updateFromTextArea(): void {
super.updateFromTextArea();
if (this.widthBeforeEditing !== undefined && this.fontAutoSize) {
const lines = this.text.split("\n").length;
this.shrinkText(this.widthBeforeEditing, lines);
}
}
override toObject<T extends Omit<Props & fabric.TClassProperties<this>, keyof SProps>, K extends keyof T = never>(
propertiesToInclude: K[] = [],
): Pick<T, K> & SProps {
return super.toObject([...propertiesToInclude, ...TEXTBOX_PROPS] as (keyof T)[]);
}
}