FabricJS剪贴板实现(复制/粘贴)

FabricJS Clipboard implementation (Copy/Paste)

本文关键字:粘贴 复制 剪贴板 实现 FabricJS      更新时间:2023-09-26

我在fabricjs中实现剪贴板时遇到问题。克隆组时,boundingBox/Controls位于正确的位置,但对象会被扔到画布的左上角,我只能移动控件。

以下是我到目前为止的实现:

var canvas = new fabric.Canvas("c");
var clipboard = null;
function Copy() {
    // Single Object
    if(canvas.getActiveObject()) {
        // Does this object require an async clone?
        if(!fabric.util.getKlass(canvas.getActiveObject().type).async) {
            clipboard = canvas.getActiveObject().clone();
        } else {
            canvas.getActiveObject().clone(function(clone) {
                clipboard= clone;
            });
        }
    }
    // Group of Objects (all groups require async clone)
    if(canvas.getActiveGroup()) {
        canvas.getActiveGroup().clone(function(clone) {
            clipboard = clone;
        });
    }
}

function Paste() {
    // Do we have an object in our clipboard?
    if(clipboard) {
        // Lets see if we need to clone async 
        if(!fabric.util.getKlass(clipboard.type).async) {
            var obj = clipboard.clone();
            obj.setTop(obj.top += 10);
            obj.setLeft(obj.left += 10);            
            canvas.add(obj);
            // We do not need to clone async, all groups require async clone
            canvas.setActiveObject(obj);
            clipboard = obj;
        }  else {
            clipboard.clone(function(clone) {
                clone.setTop(clone.top += 10);
                clone.setLeft(clone.left += 10);
                canvas.add(clone);
                // We need to clone async, but this doesnt mean its a group
                if(clipboard.isType("group")) {
                    canvas.setActiveGroup(clone);
                } else {
                    canvas.setActiveObject(clone);
                }
                clipboard = clone;
            });
        }
    }
}

我对这些方法和逻辑的实现可能是多余的,它们可能是一种更好、更小、更有效的方法(请告诉我)。

我不确定这是bug还是我做错了什么。请记住,我不知道哪些对象可能被克隆,这就是为什么我需要知道是否需要使用异步克隆,这是我找到的唯一方法

UPDATE:这是一个问题的jsfiddle(对对象进行分组并复制/粘贴)

看起来问题出在setActiveGroup函数中。检查一下这把小提琴。在第49&54我写了console.log()。在console中看到结果,可以看到_objects属性长度为0。这意味着组中没有对象。现在只需删除setActiveGroup函数。现在objects属性长度为2。

我不知道这是正常的,还是setActiveGroup函数中有任何错误。但后来我尝试在画布中手动添加组对象,而不是一次添加完整的组。我把你的小提琴第48行换成了下面的。

clone.forEachObject(function(obj){
    canvas.add(obj);
});
canvas.deactivateAll();

现在它起作用了。看看这把小提琴。

是的,为了安全起见,如果要手动设置活动组或对象,请使用canvas.dectivateAll()。您也可以根据需要使用canvas.discardActiveGroup()或canvas.ddiscardActiveObject()。

我认为我们不能将克隆组直接添加到画布中。相反,我们必须单独添加该组中的每个对象。请其他人确认。

我最近遇到了同样的问题;克隆对象被抛出画布的原因是,当您计算要克隆的对象的左侧时,您得到的是组内的左侧位置,而不是画布。在这里获得与画布相关的对象左侧是它对我的工作方式

var cloneGroup = canvas.getActiveGroup();
if (cloneGroup) {
            var objectsInGroup = cloneGroup.getObjects();
            objectsInGroup.forEach(function (object) {
                var cloneobj = object.clone();
                cloneobj.set({
                    left: ((object.left + object.group.left )+20),// added 20 to add some gap
                    top: ((object.top + object.group.top) + 20),
                    width: object.get('width'),
                    height: object.get('height'),
                });
                canvas.add(cloneobj);
            });
        }
 canvas.renderAll();