Kinetic js的多形状渐变会产生堆栈溢出



你好Stackoverflow社区

当我试图构建一个小游戏时,我遇到了一个问题。不知怎的,当我尝试淡出多个形状时,分别是一组包含这些形状的形状,其中一些形状不会淡出,或者浏览器出现堆栈溢出。

所以,当我试了几个小时来解决这个问题时,我需要你的帮助。

这是我制作的一把小小提琴的链接:http://jsfiddle.net/hnBPT/

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

淡出功能:

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();
}

附言:建议使用谷歌Chrome浏览器,firefox容易崩溃。

谢谢你的帮助。

编辑:很抱歉我忘了,你可以点击红色方块激活脚本。

这里发生了一些奇怪的行为。当我试图重写你的函数时,看看我的评论:

    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();
    }

让你感到困惑的是,被认为是(尽管它还没有按照函数调用的顺序添加,这对我来说是一种奇怪的行为)。因此,当您在each函数中循环遍历层的子层时,您正试图移动group-->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 问题的基本例子

第二个JSFIDDLE

看起来层的子层就是这样工作的。这证明了你必须区分形状和组,因为组总是被认为是层的子代。

命名方法通过为所有形状指定一个不包括组的通用名称来区分层之间的形状。

经过几次尝试,使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();
}

如果您有进一步的问题,请不要介意联系我。

最新更新