Как сделать группу объектов в ткани JS версии 1.7.22 после загрузки объекта из JSON с пользовательскими атрибутами? - PullRequest
4 голосов
/ 03 апреля 2019

Я использую fabricJS версии 1.7.22. Я хочу реализовать функциональность группировки и разгруппировки.

Когда я конвертирую свой холст в json, используя toJSON (list_of_custom_attribute). Мой пользовательский атрибут не добавлен в JSON. (пользовательский атрибут subObject, включаемый в группу, не добавляется в json).

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

Мой код группировки выглядит следующим образом (я позаимствовал этот код из функции fabricJS toGroup () последней версии 2.J.0 fabricJS):

var activeObject = this.canvas.getActiveGroup();
    var objects = activeObject._objects.concat();
    activeObject._objects = [];
    var options = fabric.Object.prototype.toObject.call(activeObject);
    var newGroup = new fabric.Group([]);
    delete options.type;
    newGroup.set(options);
    objects.forEach(function (object) {
        if (object) {
            object.canvas.remove(object);
            object.group = newGroup;
        }
    });
    newGroup._objects = objects;
    if (!activeObject.canvas) {
        return newGroup;
    }
    else {
        var canvas = activeObject.canvas;
        that.extend(newGroup, that.randomId());
        canvas.add(newGroup);
        canvas._activeObject = newGroup;
        newGroup.setCoords();
    }

Я пробую сценарий, который может помочь понять проблему. (мой объект Canvas должен содержать атрибут custom_attribute с именем 'id')

1) добавить одно изображение и клонировать это изображение. теперь конвертируем canvas в json. (JSON содержит все мои пользовательские атрибуты, такие как это => [rect [id], circle [id]]).

2) добавить одно изображение и клонировать это изображение и сгруппировать это изображение теперь конвертируем canvas в json. (JSON содержит все мои пользовательские атрибуты, такие как: => group (rect [id], circle [id]))

3) добавить одно изображение и клонировать это изображение. теперь конвертируем canvas в json (это как первый сценарий). Теперь очистите холст и снова загрузите этот json в холст. Теперь сделайте группу из этого объекта. и преобразовать canvas в json, это будет выглядеть следующим образом => group (rect [], circle [])

Основная проблема после выполнения loadfromJSON. (сценарий 3) после loadfromJSON мои объекты группы не содержат пользовательский атрибут. потому что мой холст json не содержит этот атрибут.

1 Ответ

0 голосов
/ 09 апреля 2019

Чтобы получить JSON, используйте selected.toJSON (allCustomAttr) , а для клонирования используйте object # clone .

var canvas = document.getElementById('c');
var c = new fabric.Canvas(canvas);
c.setHeight(500);
c.setWidth(500);
var allCustomAttr = ['customSourceType', 'id'];
var groupbtn = document.getElementById('group');
var unGroupbtn = document.getElementById('ungroup');
var reload = document.getElementById('reload');
var getJSON = document.getElementById('getJSON');
var selected;

function extend(object, attr) {
  //object.set(attr);
  object.toObject = (function(toObject) {
    return function() {
      return fabric.util.object.extend(toObject.call(this), attr);
    };
  })(object.toObject);
}

c.on({
  'object:selected': function(e) {
    selected = e.target;
    console.log('selected', selected);
    console.log('selected', selected.toJSON(allCustomAttr));
  }
})

getJSON.addEventListener('click', function() {
  console.log('canvas json', c.toJSON(allCustomAttr));
});

reload.addEventListener('click', function() {
  var json = c.toJSON(allCustomAttr);
  c.clear();
  c.loadFromJSON(json, function() {
    c.renderAll();
  })
});

unGroupbtn.addEventListener('click', function() {
  var activeObject = c.getActiveObject();
  if (activeObject && activeObject.type != "group") {
    return;
  }
  var items = activeObject.getObjects();
  activeObject.destroy();
  c.remove(activeObject);
  for (var i = 0; i < items.length; i++) {
    c.add(items[i]);
  }
  c.renderAll();
  c.loadFromJSON(c.toJSON(allCustomAttr));
});


groupbtn.addEventListener('click', function() {
  if (!c.getActiveGroup) {
    return;
  }
  var activegroup = c.getActiveGroup() || c.getActiveObject();
  var objectsInGroup = activegroup.getObjects();
  var grp = new fabric.Group();
  objectsInGroup.forEach((element, index) => {
    element.clone((clonedElement) => {
      grp.addWithUpdate(clonedElement);
    });
  });
  grp.set({
    top: activegroup.top,
    left: activegroup.left
  })
  c.discardActiveGroup();
  c.deactivateAllWithDispatch();
  objectsInGroup.forEach(function(object) {
    c.remove(object);
  });
  c.add(grp);
  c.renderAll();
});

var rect = new fabric.Rect({
  height: 100,
  width: 100,
  top: 100,
  left: 100,
  fill: 'red'
});

extend(rect, {
  "customSourceType": "rect",
  "id": 123456
})
c.add(rect);

var text = new fabric.IText('this is text', {
  fill: 'green',
  top: 150,
  left: 220,
  fontSize: 30
});

extend(text, {
  "customSourceType": "ITEXT",
  "id": 987654
})

c.add(text);
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.20/fabric.js"></script>
<button id="reload">
   Load from json
</button>
<button id="group">
Group
</button>
<button id="ungroup">
UnGroup
</button>
<button id="getJSON">
GEt json
</button>
<canvas id="c" style="border:1px solid"></canvas>

<ol>
  <li>Select both object and group it.</li>
  <li> now select that group. and check in console. </li>
  <li>please check second log.(there are two log placed on selected event.)</li>
  <li>(console) there are objects array in group</li>
  <li>expand rect object (first object of array)</li>
  <li>try to find custom attributes (customSourceType, id) </li>
  <br/>
  <li> above step will perfect. </li>
  <br/>
  <li> Now click on loadFromJson button</li>
  <li> now select that group. and check in console. </li>
  <li>please check second log.(there are two log placed on selected event.)</li>
  <li>(console) there are objects array in group</li>
  <li>expand rect object from that array(first object of array)</li>
  <li>try to find custom attributes (customSourceType, id) </li>
  <li>After loadfromjson there is no custom attributes.</li>
</ol>
...