FabricJS Catch an Object Inside a Group

I have tried many things, such as calculating the location, handling the event that we have in the original structure. Have you done this before?

+6
source share
7 answers

You can listen to events on the internal object by adding the parameter: subTargetCheck: trueto the fabric.Group object.

    // create a group
    let group = new fabric.Group([circle, rect], {
        subTargetCheck: true
    });

    circle.on('mousedown', function(e) { 
        // e.target should be the circle
        console.log(e.target);
    });
+6
source

I downloaded fabricjs from asturur repo . build fabric.js file

node build.js modules=ALL exclude=json,gestures

and it works!

Then you can use events for objects in groups.

canvas._objects[0]._objects[0].on('mousedown', function(e){ this.stroke = 'black'});

In my application, I decided to look for events from the mousedown callback

group.on('mousedown', function(e){
    var innerTarget  = group._searchPossibleTargets(e.e);
    console.log(innerTarget);
});

group._searchPossibleTargets = function(e) {
    var pointer = this.canvas.getPointer(e, true);
    var i = objects.length,
        normalizedPointer = this.canvas._normalizePointer(this, pointer);

    while (i--) {
        if (this.canvas._checkTarget(normalizedPointer, this._objects[i])) {
            return this._objects[i];
        }
    }
    return null;
}
+2
source

FabricJS, , , , , .

var g = new fabric.Group([ rect, text ], {
g.on('mousedown', function(e) {
    // Inspect, for a collection of the objects in this group
    this._objects
});

โ€‹โ€‹, : (

+1

, http://jsfiddle.net/UKbaseduser/Kt9Mk/1/

$("#1").click(function(){
  ZoomIn('tmp1');
});
$("#2").click(function(){
  ZoomOut('tmp1');
});
$("#3").click(function(){
  ZoomIn('tmp2');
});
$("#4").click(function(){
  ZoomOut('tmp2');
});

var canvas = new fabric.Canvas('c');

var rect1 = new fabric.Rect({ left: 150, top: 150, width: 100, height: 100, fill: 'green'});
var rect2 = new fabric.Rect({ left: 250, top: 250, width: 100, height: 100, fill: 'green'});
rect1.grp='tmp1';
rect2.grp='tmp1';
var c = new fabric.Circle({
        left: 200,
        top: 200,
        radius: 50,
        fill: 'red',
        opacity:0.8
      });
c.grp='tmp2';
canvas.add(rect1);
canvas.add(rect2);
canvas.add(c);
canvas.renderAll();

function ZoomIn(inGrp){
    var SCALE_FACTOR = 1.2;
    var objects = canvas.getObjects();
    objects.forEach(function(obj){
        if (obj.grp==inGrp){     
            var scaleX = obj.scaleX;
            var scaleY = obj.scaleY;
            var left = obj.left;
            var top = obj.top;

            var tempScaleX = scaleX * SCALE_FACTOR;
            var tempScaleY = scaleY * SCALE_FACTOR;
            var tempLeft = left * SCALE_FACTOR;
            var tempTop = top * SCALE_FACTOR;
            obj.scaleX = tempScaleX;
            obj.scaleY = tempScaleY;
            obj.left = tempLeft;
            obj.top = tempTop;
            obj.setCoords();
            }
        });
    canvas.renderAll();
 }
function ZoomOut(inGrp){
    var SCALE_FACTOR = 1.2;
    var objects = canvas.getObjects();
    objects.forEach(function(obj){
        if (obj.grp==inGrp){     
            var scaleX = obj.scaleX;
            var scaleY = obj.scaleY;
            var left = obj.left;
            var top = obj.top;

            var tempScaleX = scaleX * 1/SCALE_FACTOR;
            var tempScaleY = scaleY * 1/SCALE_FACTOR;
            var tempLeft = left * 1/SCALE_FACTOR;
            var tempTop = top * 1/SCALE_FACTOR;
            obj.scaleX = tempScaleX;
            obj.scaleY = tempScaleY;
            obj.left = tempLeft;
            obj.top = tempTop;
            obj.setCoords();
            }
        });
    canvas.renderAll();
 }

https://groups.google.com/forum/#!topic/fabricjs/hQwHxGfyx6w, .

0

:

// create a group
let group = new fabric.Group([circle, rect], {
    subTargetCheck: true
});

canvas.on('mouse:down', function (e) {
// clicked item will be
  console.log(e.subTargets[0])  
});
0

, , . v2.X Fabric, . , , false containsPoint, .

js
const getSelectedObject = (target, e) => {
  const point = target.canvas.getPointer(e, false);

  const objects = findSubTargets(target, []);

  const objectIndex = objects
    .reduce((reduction, object, index) => {
      reduction.push(
        getBoundingPoints(
          object,
          index === 0 ? 0 : reduction[0].start.x,
          index === 0 ? 0 : reduction[0].start.y
        )
      );

      return reduction;
    }, [])
    .reverse()
    .findIndex((bounds) => pointIsInBounds(point, bounds));

  return objects.reverse()[objectIndex];
};

and auxiliary functions

js
const getBoundingPoints = (object, deltaX, deltaY) => {
  const coords = object.get("aCoords");

  const x1 = coords.tl.x + deltaX;
  const y1 = coords.tl.y + deltaY;
  const x2 = coords.br.x + deltaX;
  const y2 = coords.br.y + deltaY;

  return {
    start: { x: x1, y: y1 },
    finish: { x: x2, y: y2 }
  };
};


const pointIsInBounds = (point, bounds) => {
  const xIsInBounds = point.x >= bounds.start.x && point.x <= bounds.finish.x;
  const yIsInBounds = point.y >= bounds.start.y && point.y <= bounds.finish.y;

  return xIsInBounds && yIsInBounds;
};


const findSubTargets = (target, objects) => {
  if (target.isType("group")) {
    objects.push(target);
    target.forEachObject((object) => findSubTargets(object, objects));
  }

  return objects;
};

I checked this with simple groups, nested groups and groups within groups within groups.

0
source

You can add subTargetto the group. The subtask will be added to the target event.

let group = new fabric.Group([circle, rect], {
    subTargetCheck: true
});

canvas.on('mouse:down', (event) => {
    const { subTargets } = event; // subTargets will include circle object
    .... 
})
0
source

Source: https://habr.com/ru/post/1618308/


All Articles