javascripthtmlhtml5-canvasgsapanimate-cc

Can't use GSAP inside function to target MovieClip on stage (Animate CC)


I'm an HTML5 newbie and I was wondering if someone could tell me what I'm doing wrong here. I would like to be able to use GSAP to animate a vector file I'd add to the stage and would need to be able to make it animate when I call a function, however when I try to do this I keep getting cannot tween a null object, but if it's not wrapped in a function the animation plays fine.

I created a new HTML5 canvas to see if the issue persisted and it did, so this is what I did:

  1. Added a symbol to a blank HTML5 canvas, made it a Movie Clip and drew a circle. I called the instance mcThing
  2. In the Timeline, I selected the first frame and went into Actions
  3. I wrote:

    function playAnimation() {
        TweenMax.to(this.mcThing, 3, {y:500});
    }
    playAnimation();
    
  4. When testing in Chrome, I get cannot tween a null object. If I reference it as mcThing (omitting the this. I instead get mcThing is not defined.
  5. If I then remove the function and just have this:

    TweenMax.to(this.mcThing, 3, {y:500});
    

    It plays fine, but now I can't call it when I need to.

Some context:

Essentially what I currently have is a WebSocket listening for messages. When it receives a message, it's added to the queue. I am trying to get it to play an animation and insert the text from that message. The text itself should be okay: I used CreateJS to instantiate a text in the code and TweenMax works there, the problem is animating shapes/drawings. I suppose I could instantiate all the shapes in the code itself and TweenMax would work then but I don't think this is realistic as the animation/shapes are fairly complex, so I'm trying to target the stage. The animation would play out, stop, then the message would be removed from the queue and the next one would play (same animation, different text).

I think this is a scope issue, but I'm not sure what I need to change. Any help would be much appreciated!


Solution

  • This issue is because of the scope. Your playAnimation is not scoped to this, so it is called in the global scope.

    Try this:

    this.playAnimation = function() {
        TweenMax.to(this.mcThing, 3, {y:500});
    }
    this.playAnimation();
    

    Putting your mcThing into the function scope would also work:

    var thing = this.mcThing;
    function playAnimation() {
        TweenMax.to(thing, 3, {y:500});
    }
    playAnimation();
    

    Or you could scope the function call itself!

    function playAnimation() {
        TweenMax.to(this.mcThing, 3, {y:500});
    }
    playAnimation.call(this);
    

    There are lots of ways to get around it once you understand how the scoping works. I recommend the first approach.

    Hope that helps!