简体   繁体   中英

copy and paste in fabric.js 2.0 beta6

I was using this code with fabric.js prior to 2.x beta6 to copy and paste stuff and it was working fine:

function copy() {
    var activeObject = canvas.getActiveObject(),
        activeGroup = canvas.getActiveGroup();

    if (activeGroup) {
        _clipboard = activeGroup;
    } else if (activeObject) {
        _clipboard = activeObject;
    }
    return false;
}

function paste() {
    var activeObject = canvas.getActiveObject(),
        activeGroup = canvas.getActiveGroup();
    canvas.discardActiveObject();
    if (_clipboard.size) {

        _clipboard.clone(function (clonedObj) {
            canvas.discardActiveGroup();
            clonedObj.set({
                left: clonedObj.left + 10,
                top: clonedObj.top + 10,
                evented: true
            });

            clonedObj.forEachObject(function (obj) {
                obj.set('active', true);
                canvas.add(obj);
            });

            canvas.setActiveGroup(clonedObj).renderAll();
        });
    } else {
        _clipboard.clone(function (clonedObj) {
            clonedObj
                .set("top", _clipboard.top + 5)
                .set("left", _clipboard.left + 5)
                .setCoords();

            canvas
                .add(clonedObj)
                .setActiveObject(clonedObj)
                .renderAll();
        });
    }
}

Since in the new version the selection process has been simplified by much and some methods have been removed (see here):

http://fabricjs.com/v2-breaking-changes-2

Please refere to this document and generally to this link:

http://fabricjs.com/changelog

The above solution will not work anymore. So I was trying to adopt my script to the new beta like this:

function copy() {
    var activeObject = canvas.getActiveObject();
        _clipboard = activeObject;
       console.log(_clipboard);
}


function paste() {
    var activeObject = canvas.getActiveObject();
    canvas.discardActiveObject();
    if (_clipboard.size) {

        _clipboard.clone(function (clonedObj) {
            canvas.discardActiveObject();
            clonedObj.set({
                left: clonedObj.left + 10,
                top: clonedObj.top + 10,
                evented: true,
                active: true
            });

            clonedObj.forEachObject(function (obj) {
                obj.set('active', true);
                canvas.add(obj);
            });

            canvas.setActiveObject(clonedObj);
            canvas.requestRenderAll;
        });
    } else {
        _clipboard.clone(function (clonedObj) {
            canvas.discardActiveObject();
            clonedObj.set("top", _clipboard.top + 5);
            clonedObj.set("left", _clipboard.left + 5);
            clonedObj.set('active', true);
            clonedObj.setCoords();



            canvas.add(clonedObj);
            canvas.setActiveObject(clonedObj);
            canvas.requestRenderAll;
        });
    }
}

I am facing the following problems:

  1. I am not able to copy and paste multiple selected (not grouped) objects
  2. Copy and paste of a grouped object work, but once the pasted object is deselected it is not selectable again.

See this Fiddle: https://jsfiddle.net/sharksinn/wta4pdpz/1/

EDIT: this is the working and updated Fiddle:

https://jsfiddle.net/sharksinn/wta4pdpz/13/

i'm asturur from the fabricjs issue tracker.

So then there a couple of points to better understand the selection process. One is highlighted in the doc and that is you should not discard the activeObject before trying to do things with it, even if you save a reference. An activeSelection does like autodestroy on deselect, so having it referenced will give you back a reference to an object that is empty after the deselection.

This is a suggestion:

function copy() {
// clone what are you copying since you may want copy and paste on different moment.
// and you do not want the changes happened later to reflect on the copy.
// maybe.
  canvas.getActiveObject().clone(function(cloned) {
    _clipboard = cloned;
  });
}

function paste() {
// clone again, so you can do multiple copies.
  _clipboard.clone(function(clonedObj) {
    canvas.discardActiveObject();
    clonedObj.set({
      left: clonedObj.left + 10,
      top: clonedObj.top + 10,
      evented: true,
    });
    if (clonedObj.type === 'activeSelection') {
        // active selection needs a reference to the canvas.
        clonedObj.canvas = canvas;
        clonedObj.forEachObject(function (obj) {
            canvas.add(obj);
        });
        // this should solve the unselectability
        clonedObj.setCoords();
    } else {
       canvas.add(clonedObj);
    }
    canvas.setActiveObject(clonedObj);
    canvas.requestRenderAll();
 });
}

While i could not try this code, i can tell this is more or less the right track. When you paste set your position in any case, split your logic if you have an activeSelection or something else, and then do the setActiveObject and render request.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM