CreateJS:TweenJS 时间轴补间多次更改属性而无需链接

CreateJS: TweenJS timeline tween change properties multiple time without chaining

在这个例子中,预期的结果是使圆圈淡出然后淡入。这适用于链接。片段中的注释行

createjs.Tween.get(circle).wait(0).to({alpha:0.1},2000).wait(2000).to({alpha:1},2000)

如果我在同一个 object 上将它们分成 2 个单独的调用,则它不起作用。回调不是一个选项,因为在淡入和淡出圆圈之间可能还有其他 children 的补间。

Tweenjs 似乎覆盖了所有其他先前的属性更改,只保留最后一个。 对此有何建议?

<!DOCTYPE html>
<html>
<head>
 <title>TweenJS: Canvas Tweening Example</title>

 <script type="text/javascript" src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>

<script id="editable">
 function init() {
  stage = new createjs.Stage("canvas1");
  var timeline=new createjs.Timeline();

  var circle = new createjs.Shape();
  circle.graphics.beginFill("#FF0000").drawCircle(50, 50, 50);
  stage.addChild(circle);
  
  timeline.addTween(
   //circle should fadeTo 0.1 then back to 1
   //createjs.Tween.get(circle).wait(0).to({alpha:0.1},2000).wait(2000).to({alpha:1},2000) //works
   createjs.Tween.get(circle).wait(0).to({alpha:0.1},2000), //this tween is ignore
   createjs.Tween.get(circle).wait(2000).to({alpha:1},2000) //only this tween fires
  )
  
  
  timeline.setPaused(false);

  createjs.Ticker.setFPS(20);
  createjs.Ticker.addEventListener("tick", stage);
 }
</script>
</head>

<body onload="init();">
<canvas id="canvas1" width="960" height="350"></canvas>
</body>
</html>

您正在使用的操作是异步的,因此您必须在第一次调用 tween 后使用方法 "call" 继续执行,如下所示:

createjs.Tween.get(circle, false, null, false).wait(100).to({alpha:0},2000).call(function() {
    createjs.Tween.get(circle, false, null, false).wait(1000).to({alpha:1},2000);
});

您还可以传递对命名函数的引用,例如

createjs.Tween.get(circle, false, null, false).wait(100).to({alpha:0},2000).call(function_name);

所以你可以通过一个包含你需要执行的所有操作的数组来模拟递归函数的链接,一个函数一次提取数组中的元素并执行它们,并将它自己作为参数传递.call 方法。

您遇到的问题是由于使用 TweenJS 补间的属性是确定性的。这意味着您可以跳转到补间中的任何点,它会在您期望的位置。如果您制作多个补间来管理单个 属性,两者都不是确定性的。

我建议要么链接(我知道你说过你不想要),要么使用链接 "call" 在另一个补间完成时启动一个补间。也许不是您所希望的,但希望能让您更好地了解为什么这不起作用。

这确实是一个问题,正如文档中所述:

Multiple tweens can point to the same instance, however if they affect the same properties there could be unexpected behaviour. To stop all tweens on an object, use removeTweens or pass override:true in the props argument.

通过覆盖意味着所有之前的补间都将被杀死——这有点违背了时间轴的目的。 正如我所解释的,我正在处理一长串用于多个选项的补间。我例外 - addTween 自动链接动画 - 这不会发生。值得庆幸的是,它可以用一个简单的 for 循环来修复。

<!DOCTYPE html>
<html>

<head>
  <title>TweenJS: Canvas Tweening Example</title>

  <script type="text/javascript" src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>

  <script id="editable">
    function init() {
      stage = new createjs.Stage("canvas1");
      var timeline = new createjs.Timeline();

      var circle = new createjs.Shape();

      circle.graphics.beginFill("#FF0000").drawCircle(50, 50, 50);
      stage.addChild(circle);

      circle.anims = [
        [0, {
            alpha: 0.1
          },
          2000
        ],
        [0, {
            alpha: 1
          },
          2000
        ]
      ]

      for (var i in circle.anims) {
        var c = createjs.Tween.get(circle)
        for (var j in circle.anims) {
          var tw = circle.anims[j];
          c.wait(tw[0]);
          c.to(tw[1], tw[2]);
        }
      }

      timeline.addTween(c)
      timeline.setPaused(false);

      createjs.Ticker.setFPS(20);
      createjs.Ticker.addEventListener("tick", stage);
    }
  </script>
</head>

<body onload="init();">
  <canvas id="canvas1" width="960" height="350"></canvas>
</body>

</html>

我只是将目标对象的所有补间属性作为数组提供,然后使用 for 循环创建完整的补间。之后,我只是将它添加到时间线上。

再次感谢您的回答。希望这会对其他人有所帮助。