Fabric.js Текст внутри пользовательского подкласса неправильно масштабируется

#javascript #canvas #fabricjs

Вопрос:

Мне нужно иметь пользовательские объекты, похожие на текстовые поля, поэтому я создал класс под названием TextQuide.

 import { fabric } from "fabric";

interface ITextQuide extends fabric.IRectOptions {
  text?: Partial<fabric.TextOptions>;
  value: string;
}

class TextQuide extends fabric.Rect {
  text: fabric.Text;
  value: string;

  constructor(options: ITextQuide = { value: "placeholder" }) {
    super(options);
    this.type = "textQuide";
    this.value = options.value;
    this.text = new fabric.Text(this.value, options.text);
    this.text.selectable = false;
    this.fill = "transparent";
    this.stroke = "navy";
    this.strokeWidth = 2;
    this.objectCaching = false;
    this.text.objectCaching = false;
  }

  toObject = (propertiesToInclude?: string[]) => ({
    ...super.toObject(propertiesToInclude),
    text: this.text.toObject(propertiesToInclude)
  });
  toSVG = (reviver?: Function) => {
    const rectSvg = super.toSVG(reviver);
    let textSvg = this.text.toSVG();
    this.text.clone((clone: fabric.Object) => {
      clone.set("left", this.left);
      clone.set("top", this.top);
      textSvg = clone.toSVG();
    });
    return rectSvg   textSvg;
  };

  adjustTextWidth = () => {
    const bbox = this.getBoundingRect();
    const { textLines } = this.text;
    let longestLine = 0;
    for (let i = 0; i < textLines.length; i  ) {
      longestLine = Math.max(longestLine, this.text.measureLine(i).width);
    }

    if (longestLine > bbox.width) {
      const scale = bbox.width / longestLine;
      console.log(scale);
      this.text.set("scaleX", scale);
      this.text.setCoords();
      this.setCoords();
    }
  };

  _render = (ctx: CanvasRenderingContext2D) => {
    this.text.set("text", this.value);
    this.adjustTextWidth();

    super._render(ctx);
    this.text._render(ctx);
  };
}

fabric.TextQuide = TextQuide;

export default TextQuide;

 

По сути, это просто класс, который расширяет ткань.Выпрямляет и также отображает текст.

Мне не очень нравится синтаксис подклассов по умолчанию, поэтому я использовал более новый синтаксис класса, и все работает так, как планировалось execpt для настройки this.text.scaleX .

Код работает теоретически и выглядит правильно при экспорте в SVG, но по какой-либо причине он не устанавливает масштаб для текста на холсте.

Я воспроизвел здесь минимальный пример https://codesandbox.io/s/fabric-text-scaling-demo-h6t84

В нем также есть некоторые другие вещи, такие как контроллер масштабирования, который я использую в своем приложении, на случай, если они окажут влияние.