使用Kinetic js的多个形状fadout会产生堆栈溢出

时间:2013-08-05 06:28:18

标签: javascript canvas kineticjs

Hello Stackoverflow社区

当我试图建立一个小游戏时,我遇到了一个问题。 不知何故,当我尝试淡出多个形状时,分别是一个带有形状的组,一些形状不会淡出或浏览器会出现堆栈溢出。

因此,当我尝试了几个小时来解决问题时,我需要你的帮助。

这是我做的一个小小提琴的链接:http://jsfiddle.net/hnBPT/

正如你所看到的那样,函数newFadeShapesOut()需要应该淡出的节点以及节点的层。 它将节点移动到一个组中并淡出该组。不知何故,有时,一个或多个形状不会淡出或发生致命错误。

淡出功能:

function newFadeShapesOut(shapes, layer, callback, speed){
    if(typeof(speed) == 'undefined'){
        speed = 1;
    }
    var g = new Kinetic.Group();
    console.log(layer.getChildren().length);
    console.log(shapes.length);
    layer.add(g);
    shapes.each(function(shape){
        shape.moveTo(g);
    });
    console.log(layer.getChildren().length);
    console.log(shapes.length);
    var tween = new Kinetic.Tween({
        node: g,
        opacity: 0,
        duration: speed,
        onFinish: function(){
            if(typeof(callback) != 'undefined'){
                callback();
                tween.destroy();
            }
        }
    }).play();
}

PS:建议使用Google Chrome,Firefox会崩溃。

感谢您的帮助。

编辑:对不起,我忘记了,你可以点击红色方块激活剧本。

2 个答案:

答案 0 :(得分:2)

这里有一些奇怪的行为。当我试图重写你的功能时,看看我的评论:

    function fadeShapesOut(layer, callback, speed) {
        var children = layer.children;
        //The layer here already shows some children have moved.
        //2 children remain, 1 text and 1 rect.
        console.log("LAYER");
        console.log(layer); 
        //Again, children shows that there are only 2 children of layer at this point: Test 2 and Button Rect
        console.log('CHILDREN');
        console.log(children);
        if(typeof(speed) == 'undefined'){
            speed = 1;
        }
        var group = new Kinetic.Group();
        layer.add(group);
        children.each(function(child) {
            console.log("CHILD");
            console.log(child); //This spits out Test 1, Test 3 and the newly added Group. (Strange order???
            child.moveTo(group);
        });
        //Since group is already added to the layer, you're all of layer's children to group, including group itself. Which is causing a never ending loop of references to group including itself - causing the stack overflow.
        var tween = new Kinetic.Tween({
            node: group,
            opacity: 0,
            duration: speed,
            onFinish: function(){
                if(typeof(callback) != 'undefined'){
                    callback();
                    tween.destroy();
                }
            }
        }).play();
    }

让您感到困扰的是,群组被视为图层(即使尚未添加 函数调用的顺序,这对我来说是一种奇怪的行为)。因此,当您在每个函数中遍历图层的子项时,您尝试移动组 - > group ,它会在永无止境的循环中搞砸引用。

我在我的小提琴中记录了一堆东西,所以请继续看看我上面谈到的一些奇怪的行为。

无论如何,如果你的回调是破坏图层,那么将所有内容移动到函数中的新组是什么意思?那个小组搞砸了你的代码,如果你要破坏这个层,我就没有看到它的重点。

相反,您可以通过补间图层本身来实现您想要的效果:

function fadeLayer(layer, callback, speed) {
    var tween = new Kinetic.Tween({
            node: layer,
            opacity: 0,
            duration: 2,
            onFinish: function(){
                layer.destroy();
                tween.destroy();
            }
        }).play();
}



如果您必须坚持使用原始功能格式,那么您可以使用名称抓住儿童

newsobj[n] = new Kinetic.Text({
      nid: n,
      x: 140,
      y: ((n == 0) ? 294.5 : 304.5 ),
      text: news[n],
      fill: 'white',
      fontFamily: 'Corbel W01 Regular',
      fontSize: 11.26,
      name: 'fadeThisAway'
  });

  button = new Kinetic.Rect({
        x: 10,
        y: 10,
        width: 100,
        height: 100,
        fill: 'red',
        name: 'fadeThisAway'
    });

在我的示例中,我使用了名称fadeThisAway。然后,使用旧功能:

    function newFadeShapesOut(layer, callback, speed){
      var shapes = layer.get('.fadeThisAway');
      if(typeof(speed) == 'undefined'){
          speed = 1;
      }
      var g = new Kinetic.Group();
      console.log(layer.getChildren().length);
      console.log(shapes.length);
      layer.add(g);
      shapes.each(function(shape){
          shape.moveTo(g);
      });
      console.log(layer.getChildren().length);
      console.log(shapes.length);
      var tween = new Kinetic.Tween({
          node: g,
          opacity: 0,
          duration: speed,
          onFinish: function(){
              if(typeof(callback) != 'undefined'){
                  callback();
                  tween.destroy();
              }
          }
      }).play();
  }

不要将shapes传递给函数,只需调用

即可

var shapes = layer.get('.fadeThisAway');

在函数的开头(你已经通过函数传递图层)来抓取名为fadeThisAway的子节点。 (注意:这是有效的,因为未命名为fadeThisAway

内部的工作示例和评论:JSFIDDLE


<强>更新

好的,所以我用layer.children

作了一个基本的问题示例

2nd JSFIDDLE

看起来这就是图层的孩子们的工作方式。这证明您必须区分形状和组,因为该组将始终被视为图层的子项。

命名方法通过为所有形状提供排除组的通用名称来区分图层之间的形状。

答案 1 :(得分:2)

经过多次尝试将projeqht的功能弯曲到我的方式后,我终于做到了! 不知何故,集合形状只是在将图层添加到图层时自行更新! 如果我改为使用数组,它就可以工作。

希望它有所帮助!

所以我的解决方案就像一个魅力。

function fadeShapesOut(shapes, callback, speed){
    layer = shapes[0].getLayer();
    if(typeof(speed) == 'undefined'){
        speed = 1;
    }
    var g = new Kinetic.Group();
    layer.add(g);
    for(i in shapes){ 
        shapes[i].moveTo(g);
    }
    var tween = new Kinetic.Tween({
        node: g, 
        opacity: 0, 
        duration: speed, 
        onFinish: function(){
            if(typeof(callback) != 'undefined'){
                callback();
            }
            tween.destroy();
        }
    }).play();
}

如果您还有其他问题,请不要介意与我联系。