Центрирование и масштабирование объекта canvas внутри другого объекта canvas по ширине / высоте в Fabric.js - PullRequest
0 голосов
/ 06 ноября 2019

Цель: Центрирование объекта (по горизонтали и вертикали) внутри другого объекта (прямоугольника или группы) на canvas с помощью Fabric.js или с помощью Javascript, который сохраняет исходное соотношение сторон объекта таким же, нотакже не превышать пропорции ширины / высоты родительского объекта?

Родительский объект (прямоугольник или группа) не будет центрирован на элементе canvas.

Вот код, который у меня есть до сих пор: https://stackblitz.com/edit/angular-my8hky

Пока что app.component.ts:

canvas: fabric.Canvas;

ngOnInit() {
  this.canvas = new fabric.Canvas('canvas');
  var rect = new fabric.Rect({
    left: 100,
    top: 50,
    width: 300,
    height: 200,
    fill: '#eee'
  });
  this.canvas.add(rect);

  fabric.Image.fromURL('https://angular.io/assets/images/logos/angular/logo-nav@2x.png', (img) => {
    let bounds = rect.getBoundingRect();
    let oImg = img.set({
      left: bounds.left,
      top: bounds.top,
      width: rect.width
    }).scale(1);
    this.canvas.add(oImg).renderAll();
  });
}

Новый объект не только центрируется не по вертикали, но и не центрируется по горизонтали, если высота объекта прямоугольника уменьшается (дляпример для высоты 50px.

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

Текущее решение:

Родительский прямоугольник width: 300 и height: 200:

300px x 200px - Undesired Fabric.js centering solution

Родительский прямоугольник width: 300 и height: 50:

300px x 50px - Undesired Fabric.js centering solution

Желаемое решение:

Родительский прямоугольник width: 300 и height: 200:

300px x 200px - Desired Fabric.js centering solution

Родительский прямоугольник width: 300 и height: 50:

300px x 50px - Desired Fabric.js centering solution

Кто-нибудь может помочь?

1 Ответ

0 голосов
/ 06 ноября 2019

Понял. Вот StackBlitz: https://stackblitz.com/edit/angular-pg4fis

Хитрость заключалась в том, чтобы сначала добавить прямоугольник в группу Fabric, например, так:

var rect = new fabric.Rect({
  left: 100,
  top: 50,
  width: 450,
  height: 200,
  fill: '#e3e3e3',
});

var rectGroup = new fabric.Group([rect], {
  name: 'Rectangle',
});

this.canvas.add(rectGroup);

Затем,Мне удалось установить границы родительского (группового) элемента и использовать переменный коэффициент масштабирования для установки изображения с помощью функции Math:

fabric.Image.fromURL('https://angular.io/assets/images/logos/angular/logo-nav@2x.png', (img) => {
  let bounds = rectGroup.getBoundingRect();

  const scaleFactor = Math.min(
    Math.min(1, bounds.width / img.width),
    Math.min(1, bounds.height / img.height)
  );
  img.scale(scaleFactor);

  img.set({
    top: bounds.top + Math.max(bounds.height - img.height * scaleFactor, 0)/2,
    left: bounds.left + Math.max(bounds.width - img.width * scaleFactor, 0)/2,
  });

  rectGroup.addWithUpdate(img);
  this.canvas.renderAll();
});
...