Search code examples
javascriptanimationcreatejschainingtweenjs

CreateJS: TweenJS timeline tween change properties multiple time without chaining


In this example the expected result is to make the circle fadeOut then fadeIn. This works ok with chaining. The commented line in the snippet

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

It does not work if I separate them into 2 separate calls on the same object. Callbacks are not an option as there may be other tweens to other children between the fading in and fading out of the circle.

Tweenjs seems to override all other previous properties change and just keep the last one. Any suggestions on this?

<!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>


Solution

  • This is indeed an issue as it is stated in the documentation:

    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.

    Passing override means all previous tweens will be killed off - it kinda defeats the purpose of a the timeline. As I explained, I am working with a long list of tweens for multiple options. I was excepting - addTween to chain the animations automatically - this does not happen. Thankfully, it can be fixed with a simple for loop.

    <!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>

    I am just feeding all tween properties the target object as array then creating the full tween using a for loop. Afterwards, I just add it to the timeline.

    Thank you again for the answers. Hopefully, this will help someone else.