【问题标题】:Canvas (Kinetic.JS) - cloned group doesn't appear?Canvas (Kinetic.JS) - 克隆组不出现?
【发布时间】:2012-08-23 02:12:00
【问题描述】:

我正在玩 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}));

UPDATE - 克隆组似乎不会进行深层复制。这可以通过控制台记录组来验证 - console.log(stage.get('#group2')) 并且你会看到它的 children 集合是空的)。这是一个错误吗?不知道为什么要克隆一个没有其成员的组。

有什么想法吗?提前致谢。

【问题讨论】:

    标签: html canvas clone shape kineticjs


    【解决方案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;
    }
    

    【讨论】:

    • 感谢您的帮助。我明白浅克隆的原因,但正如你所说,我当然认为应该有一种方法可以进行深度克隆。就我而言,我有代表游戏中角色的复杂组,我想克隆整个组。我猜我可以把每个角色放在一个图层上。这进一步模糊了组和层之间的定义线,但我想这没关系。
    猜你喜欢
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 2019-12-25
    • 1970-01-01
    • 2012-12-01
    • 2017-06-04
    • 1970-01-01
    • 2010-10-19
    相关资源
    最近更新 更多