Copy link to clipboard
Copied
This should have not been so hard to figure it out, but here I am anyway
I have a this.stop() at the end of a timeline, and I want a button to be able to replay the main timeline animation.
Script:
this.stop();
this.btnPLAY.addEventListener("click", buttonPLAY);
function buttonPLAY()
{
gotoAndPlay(0); //THIS IS WHAT I CAN'T FIGURE OUT.
};
Thanks for helping me with this and taking pity on me.
1 Correct answer
You have to let the function know what it is you want to gotoAndPlay(). There are a couple of ways to do that, the way that the code snippets would do it is to bind the 'this' from the main timeline, so that the function uses the same value of 'this'. Your code would become:
this.stop();
this.btnPLAY.addEventListener("click", buttonPLAY.bind(this));
function buttonPLAY()
{
this.gotoAndPlay(0); //I FIGURED IT OUT!
};
Copy link to clipboard
Copied
You have to let the function know what it is you want to gotoAndPlay(). There are a couple of ways to do that, the way that the code snippets would do it is to bind the 'this' from the main timeline, so that the function uses the same value of 'this'. Your code would become:
this.stop();
this.btnPLAY.addEventListener("click", buttonPLAY.bind(this));
function buttonPLAY()
{
this.gotoAndPlay(0); //I FIGURED IT OUT!
};
Copy link to clipboard
Copied
YAY!
Thank you very much
Copy link to clipboard
Copied
The important thing to never, ever forget about Canvas event handlers is that, unlike ActionScript event handlers, they default to executing in the global context. So "this" will point to the browser window object.
There are three major ways to deal with this. The first, as Colin illustrated, is to use bind on the event handler to correct its context.
The second way is to use a variable to reference the desired context, like so:
this.stop();
var myLocalScope = this;
this.btnPLAY.addEventListener("click", buttonPLAY);
function buttonPLAY() {
myLocalScope.gotoAndPlay(0);
};
The third way is to use the global exportRoot variable. Adding global variables is generally a bad idea, but Animate creates this one when it publishes, so we may as well use it. exportRoot points to the root timeline object. So if the clip you want to control is on the main timeline, and named banana, you'd do this:
this.stop();
this.btnPLAY.addEventListener("click", buttonPLAY);
function buttonPLAY() {
exportRoot.banana.gotoAndPlay(0);
};
All of these methods work equally well, and none are particularly superior to the other. Just pick whichever one works best for the circumstances.
I'd recommend reading this for a more thorough explanation of context and scope:
Understanding Scope and Context in JavaScript | Ryan Morr
BTW, naming your event handlers like "buttonPLAY" isn't great practice. Functions should be named for what they DO. Something like even just "buttonPLAYHandler" would be more clear.

