1

I'm working with Fabric.js to create an interactive canvas. When a user clicks on a button I call the addNewItem function in my diagram.js file. After clicking this I want to add a new group to the center of the canvas. The issue I have is that one of the two elements that I want to add to the group is an SVG that I'm loading via Fabric's own loadSVGFromString method. This takes time to complete which means that in the below example group is not defined in the Promise.

diagram.js (only relevant code shown)

addNewItem = (e, item) => {
  e.preventDefault();

  drawPlayer(item.svg, this.state.playerIconColor, borderColor, item.sizes[this.state.iconSize].height, item.sizes[this.state.iconSize].width, 'LM')
  .then((newItem) => {
    newItem.hasControls = false;
    canvas
      .add(newItem)
      .centerObject(newItem)
      .setActiveObject(newItem)
      .renderAll();
    newItem.setCoords();
  })
  .catch((notCreated) => {
    alert(notCreated);
  });
}

drawPlayer.js

import { fabric } from 'fabric';

const drawPlayer = (icon, iconFill, borderColor, height, width, label) => {
  // Create empty group
  let group;

  fabric.loadSVGFromString(icon, (objects, options) => {
    const canvasItem = fabric.util.groupSVGElements(objects, options);
    canvasItem.hasControls = false;
    canvasItem.setFill(iconFill);
    canvasItem.set({ borderColor });
    canvasItem.scaleToHeight(height);
    canvasItem.scaleToWidth(width);

    const playerText = new fabric.Text(label, {
      fontSize: 10,
      originX: 'center',
      originY: 'center',
    });

    group = new fabric.Group([canvasItem, playerText], { left: 200, top: 200 });
  });

  return new Promise((resolve, reject) => {
    if (group.length > 0) {
      resolve(group);
    } else {
      reject('Not created');
    }
  });
};

export default drawPlayer;
GuerillaRadio
  • 1,267
  • 5
  • 29
  • 59

1 Answers1

3

You can try resolving/rejecting the promise after loadSVGFromString is executed.

import { fabric } from 'fabric';

const drawPlayer = (icon, iconFill, borderColor, height, width, label) => {
  // Create empty group
  let group;
  let groupResolve;
  let groupReject;

  fabric.loadSVGFromString(icon, (objects, options) => {
    const canvasItem = fabric.util.groupSVGElements(objects, options);
    canvasItem.hasControls = false;
    canvasItem.setFill(iconFill);
    canvasItem.set({ borderColor });
    canvasItem.scaleToHeight(height);
    canvasItem.scaleToWidth(width);

    const playerText = new fabric.Text(label, {
      fontSize: 10,
      originX: 'center',
      originY: 'center',
    });

    group = new fabric.Group([canvasItem, playerText], { left: 200, top: 200 });
    if (group.length > 0) {
      groupResolve(group);
    } else {
      groupReject('Not created');
    }
  });

  return new Promise((resolve, reject) => {
    groupResolve = resolve;
    groupReject = reject;
  });
};

export default drawPlayer;
user700284
  • 13,540
  • 8
  • 40
  • 74