Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fabric.js: Get objects by name

Is it possible to get Fabric.js objects by name? I can add subclass which will allow me to add custom name property to objects. But after that can I call objects by name instead of index? e.g

calling by index canvas.getItem(0);

I want something like canvas.getItemByName(itemName);

like image 944
Imran Ahmed Avatar asked Dec 29 '13 10:12

Imran Ahmed


2 Answers

You can do this on application level with the following code:

/**
 * Item name is non-unique
 */
fabric.Canvas.prototype.getItemsByName = function(name) {
  var objectList = [],
      objects = this.getObjects();

  for (var i = 0, len = this.size(); i < len; i++) {
    if (objects[i].name && objects[i].name === name) {
      objectList.push(objects[i]);
    }
  }

  return objectList;
};

If the object name is unique you can do something like this:

/**
 * Item name is unique
 */
fabric.Canvas.prototype.getItemByName = function(name) {
  var object = null,
      objects = this.getObjects();

  for (var i = 0, len = this.size(); i < len; i++) {
    if (objects[i].name && objects[i].name === name) {
      object = objects[i];
      break;
    }
  }

  return object;
};

Now you can call canvas.getItemByName('name1'); or canvas.getItemsByName('name1');.

like image 78
Kienz Avatar answered Oct 19 '22 15:10

Kienz


I expanded the idea a little to include group objects and searching by any attribute, not just name.

When many elements are expected to match (non-unique attribute), or when only one element is expected to match (unique attribute, like ID):

/**
 * Non-unique attributes
 */
fabric.Canvas.prototype.getItemsByAttr = function(attr, val) {
    var objectList = [];
    traverseObjects(this.getObjects(), attr, val, objectList);
    return objectList;
};

/**
 * Unique attribute
 */
fabric.Canvas.prototype.getItemByAttr = function(attr, val) {
    var objectList = [];
    traverseObjects(this.getObjects(), attr, val, objectList);
    return objectList[0];
};

/**
 * Traverse objects in groups (and subgroups)
 */
function traverseObjects(objects, attr, val, objectList){
    for(i in objects){
        if(objects[i]['type'] == 'group'){
            traverseObjects(objects[i].getObjects(),attr,val, objectList);
        } else if(objects[i][attr] == val){
            objectList.push(objects[i]);
        }
    }
}

Now you can call canvas.getItemByAttr('name','name1'); or canvas.getItemsByAttr('someAttr','someValue');.

like image 42
dearsina Avatar answered Oct 19 '22 14:10

dearsina