0

I used to manage object alignments selection on FabricJS with getActiveGroup as below :

canvas.on("selection:created", function(e) {
    var activeObj = canvas.getActiveObject();
    console.log('e.target.type', e.target.type);
    if(activeObj.type === "group") {
        console.log("Group created");

        var groupWidth = e.target.getWidth();
        var groupHeight = e.target.getHeight();


        e.target.forEachObject(function(obj) {
            var itemWidth = obj.getBoundingRect().width;
            var itemHeight = obj.getBoundingRect().height;

            $('#objAlignLeft').click(function() {
                obj.set({
                    left: -(groupWidth / 2),
                    originX: 'left'
                });
                obj.setCoords();
                canvas.renderAll();
            });
            ...

    }
}); 

more detailed here

But now that I use FabricJS 2 and that getActiveObject() has been removed, I don't know what to do. I read on the doc that we could use getActiveObjects(), but it does nothing.

Please how can I reproduce the action of this code with FabricJS 2 (where getActiveGroup isn't supported anymore) ?

kabrice
  • 1,475
  • 6
  • 27
  • 51

1 Answers1

1

Selections of more than one object have the type activeSelection. The group type is only used when you purposefully group multiple objects using new fabric.Group([ obj1, obj2]

When you create a multi-selection using the shift-key as opposed to drawing a selection box, you'll trigger the selection:created event only on the first object selected, while objects added to the selection will trigger the selection:updated event. By calling your alignment code from both the selection:created and selection:updated events you'll make sure that your code is executed every time a multi-selection is created.

Also, you can use getScaledWidth() and getScaledHeight() to get scaled dimensions, or just .width and .height if you just want the unscaled width/height values. Good luck!

canvas.on({
  'selection:updated': function() {
    manageSelection();
  },
  'selection:created': function() {
    manageSelection();
  }
});

function manageSelection() {
  var activeObj = canvas.getActiveObject();
  console.log('activeObj.type', activeObj.type);
  if (activeObj.type === "activeSelection") {
    console.log("Group created");

    var groupWidth = activeObj.getScaledWidth();
    var groupHeight = activeObj.getScaledHeight();

    activeObj.forEachObject(function(obj) {
      var itemWidth = obj.getBoundingRect().width;
      var itemHeight = obj.getBoundingRect().height;
      console.log(itemWidth);

      $('#objAlignLeft').click(function() {
        obj.set({
          left: -(groupWidth / 2),
          originX: 'left'
        });
        obj.setCoords();
        canvas.renderAll();
      });
    });
  }
}
melchiar
  • 2,782
  • 16
  • 27
  • Please do you have a place where I could test your solution? Because I've tried your way but it doesn't work, `activeObj.type` never returns `group`. It returns `rect` or `text` (Based on the code of my jsfiddle) – kabrice Aug 18 '18 at 05:55
  • Hi @kabrice, I've edited my answer. To check if your selection contains more than one object, use the type `activeSelection`, not `group` – melchiar Aug 18 '18 at 14:49
  • Still doesn't work, It still returns `rect` or `text` as type. For your record, I used `FabricJS 2.3.3`. – kabrice Aug 18 '18 at 15:48
  • I think I see the problem. I'm guessing you're using shift multi-select rather than the selection box to create your selection. By calling your alignment code from both the `selection:created` and the `selection:updated` events you can account for both types of selection methods. [see jsfiddle](http://jsfiddle.net/melchiar/wxrjdLsy/) – melchiar Aug 18 '18 at 19:39
  • Yes you were right. It works super great now :). Thank you very much – kabrice Aug 19 '18 at 17:36