Canvas(Kinetic.JS) - 克隆组没有出现?

时间:2012-08-28 14:25:45

标签: html5 canvas clone shape kineticjs

我正在玩Kinetic并且似乎无法弄清楚为什么我正在克隆的组不会出现。

小提琴:http://jsfiddle.net/DgwLd/3/

我可以克隆形状没问题 - 它只是没有出现的组。文档证实可以克隆组,所以我不确定这里有什么。这是来自小提琴的代码:

//group and original circle - appears fine
layer.add(new Kinetic.Group({id: 'group'}));
stage.get('#group')[0].add(new Kinetic.Circle({
    fill: 'orange',
    x: 200,
    y: 50,
    radius: 30
}));

//clone of group at different Y pos - doesn't appear
layer.add(stage.get('#group')[0].clone({y: 120}));

更新 - 似乎克隆群组不会制作深层副本。这可通过控制台记录组console.log(stage.get('#group2'))来验证,并且您将看到其children集合为空。这是一个错误吗?不确定为什么你想要在没有其成分的情况下克隆一个群体。

有什么想法?提前谢谢。

1 个答案:

答案 0 :(得分:1)

好像你自己想出来了 - 实际上,制作一个组克隆,或者实际上是任何容器的克隆,都会执行浅拷贝。

实际上,查看源代码可能比其他任何内容都更具信息性:

clone: function(obj) {
    // instantiate new node
    var classType = this.shapeType || this.nodeType;
    var node = new Kinetic[classType](this.attrs);

    /*
     * copy over user listeners
     */
    for(var key in this.eventListeners) {
        var allListeners = this.eventListeners[key];
        for(var n = 0; n < allListeners.length; n++) {
            var listener = allListeners[n];
            /*
             * don't include kinetic namespaced listeners because
             *  these are generated by the constructors
             */
            if(listener.name.indexOf('kinetic') < 0) {
                // if listeners array doesn't exist, then create it
                if(!node.eventListeners[key]) {
                    node.eventListeners[key] = [];
                }
                node.eventListeners[key].push(listener);
            }
        }
    }

    // apply attr overrides
    node.setAttrs(obj);
    return node;
}

如您所见,它所做的只是使用当前节点的属性实例化一个新节点,然后复制事件侦听器。这可能是设计的 - 通常你想采取阻力最小的路径,当你考虑任何一般节点(它不是专门用于容器)存在.clone()方法时,这种实现是正常的。

尽管如此,似乎应该有类似容器的.deepclone()方法。也许是这样的:

deepclone: function(obj) {
    var node = this.clone(obj);

    if (this.children) {
        for (var i = 0; i < this.children.length; i++) {
            node.add(this.children[i].clone();
        }
    }

    return node;
}