Skip to main content
Participating Frequently
December 22, 2022
Question

Changing the target of gotoAndStop

  • December 22, 2022
  • 6 replies
  • 432 views

Using an HTML canvas with Animate, looking a the first three pages (frames) the first is the home page, the second a bio page, the third is a contact me page. On all pages are three common buttons: home, previous and next. The home botton always takes you back to the home page. The actions for the previous and next buttons will change depending on what page you are on: on the home page, the previous button will take you to the home page and the next button will take you to the bio page. On the bio page, the previous button will take you to the home page and the next button will take you to the contact me page. On the contact me page, the previous button will take you to the bio page and the next button will take you to the next page in the sequence.

 

At frame 15 I have defined the actions for all of the used in  te Animate file. The definitions where the target of the gotoAndStop is static, such as the home page, it is pretty straightforward. However, I am having a difficult time for the next and previous button definitions. I first tried re-declaring the action at the first frame of these other pages but that did not seem to override the initial definition setup in frame 15. I then tried using a variable in the definition, such as (for the home page):

  var _previous = home

  var _next = bio

  _this.previous_btn.on('click', function() {

    _this.gotoAndStop(_previous);

})

_this.next_btn.on('click', function() {

    _this.gotoAndStop(_previous);

})

 

This completely failed. The buttons did not perform any actions (with hardcoded 'home' and 'bio' the same code works).

 

Is it possible to dynamically change the target of a gotoAndStop/gotoAndPlay action?? Or, within the previous and next function definitions, will I need to determine where I am in the timeline and use IF/THEN or SWITCH constructs to vary the target of the button actions?

 

Thank you,

    Al

 

 

 

 

 

    This topic has been closed for replies.

    6 replies

    Participating Frequently
    December 24, 2022

    Well, I decided to go with simply using a select statement within the next and previous botton clicks. This works most of the time, but I did run into a problem. However, it does not have to do with gotoAndStop so I will open a new discussion topic for it if I can't find a reference to a similar question in the forum.

     

    Thanks for all of the suggestions. When I have more time, I will revisit exploring a more elegant solution.

    kglad
    Community Expert
    Community Expert
    December 24, 2022

    @Alan27594372b2mr 

     

    your welcome. 

     

    p.s.  what's a select statement?

    JoãoCésar17023019
    Community Expert
    Community Expert
    December 22, 2022

    Here is a FLA containing the latest code example I provided:
    https://bit.ly/3BVFpWk

     

    Is fairly straightforward to use, IMHO.

     

    Regards,

    JC

    kglad
    Community Expert
    Community Expert
    December 22, 2022

    @JoãoCésar17023019's solution will work (though there are potential future problems with it) only if all your "pages" are in frame 0, 1 and 2.

     

    you'll have problems using that code with any other setup.

     

    a more flexible and reliable solution is to label the 3 keyframes ("home, "bio", "contact") and use:

     

    this.previous_btn.addEventListener("click" prevF.bind(this));

    this.next_btn.addEventListener("click",nextF.bind(this));

     

    function prevF(e){

    switch(e.currentLabel){

    case:"bio":

    this.gotoAndStop("home");

    break;

    case:"contact":

    this.gotoAndStop("bio");

    break;
    }

    }

    function nextF(e){

    switch(e.currentLabel){

    case:"home":

    this.gotoAndStop("bio");

    break;

    case:"bio":

    this.gotoAndStop("contact");

    break;
    }

    }

    JoãoCésar17023019
    Community Expert
    Community Expert
    December 22, 2022

    If it's important to rely on labels, than I would do something like this:

    var root = this;
    var labels = root.labels;
    
    function main()
    {
    	root.stop();
    	root.labelIndex = 0;
    	root.home_btn.on("click", navigate);
    	root.bio_btn.on("click", navigate);
    	root.contact_btn.on("click", navigate);
    	root.previous_btn.on("click", navigate, null, false, { offset: -1 });
    	root.next_btn.on("click", navigate, null, false, { offset: 1 });
    }
    
    function navigate(e, data)
    {
    	if (data)
    	{
    		root.labelIndex = clamp(0, root.labelIndex + data.offset, labels.length - 1);
    		root.gotoAndStop(labels[root.labelIndex].position);
    	}
    	else
    	{
    		var label = e.currentTarget.name.split("_")[0];
    		root.labelIndex = labels.indexOf(labels.find(function(obj){ return obj.label === label; }));
    		root.gotoAndStop(label);
    	}
    }
    
    function clamp(min, value, max)
    {
    	if (value < min)
    		return min;
    	
    	if (value > max)
    		return max;
    	
    	return value;
    }
    
    if (!this.started)
    {
    	main();
    	this.started = true;
    }

     

    In this way the user can change the labels as much as he wants to without worrying too much about the code.

    kglad
    Community Expert
    Community Expert
    December 22, 2022

    @JoãoCésar17023019imo, that's making the code more abstract with no, or little, benefit.  ie, it depends on button names being tied to frame labels and that's really hidden in your code.  at a minium, that should be added as a comment.

    JoãoCésar17023019
    Community Expert
    Community Expert
    December 22, 2022

    Hi.

     

    I think it's easier to just add 1 or subtract 1 frame:

    var _this = this;
    
    _this.previous_btn.on('click', function()
    {
        _this.gotoAndStop(_this.currentFrame - 1);
    });
    
    _this.next_btn.on('click', function()
    {
        _this.gotoAndStop(_this.currentFrame + 1);
    });

     

    Regards,

    JC

     

    Participating Frequently
    December 22, 2022
    I'm not very experienced with Animate but in my case I don't think that
    would work. Some of my content contain motions that span multiple frames.
    Thus, my labels can be several frames apart. I did convert some to clips
    but others I can't (e.g. ones with audio or other complexities that can't
    be converted to symbols). Because of this, I need to resort to using frame
    labels instead of frame numbers.

    At least the above is my understanding. Again, I'm very new to Animate so
    my thinking could be flawed.

    I could go with a very long switch statement but I was trying to come up
    with a more elegant solution.

    Thank you,
    Al
    kglad
    Community Expert
    Community Expert
    December 22, 2022

    then use this and use gotoAndPlay instead of gotoAndStop

     

    this.previous_btn.addEventListener("click" prevF.bind(this));

    this.next_btn.addEventListener("click",nextF.bind(this));

     

    function prevF(e){

    switch(e.currentLabel){

    case:"bio":

    this.gotoAndStop("home");

    break;

    case:"contact":

    this.gotoAndStop("bio");

    break;
    }

    }

    function nextF(e){

    switch(e.currentLabel){

    case:"home":

    this.gotoAndStop("bio");

    break;

    case:"bio":

    this.gotoAndStop("contact");

    break;
    }

    }

    kglad
    Community Expert
    Community Expert
    December 22, 2022

    yes, just put those 3 buttons on one keyframe with their code, and use if-then, or a little cleaner, switch-case branching to account for the different actions on to be taken depending on the current frame label.

    Participating Frequently
    December 22, 2022

    In looking up information about frame labels, I found a reference to an array of frame labels... which looked like:

    var root = this;
    var labels = root.labels;

     

    However, when I code this, the arrey labels appears to be empty. When I display labels[0] I get:

    [object Object]

     

    When I display the size of the array (.count) I get: undefined

     

    Is there a built-in element that contains an array of frame labels? I was thinking of using an array of labels to determine the next and previous labels to go to.

     

    Thank you,

      Al

     

     

     

     

    Participating Frequently
    December 22, 2022

    Oops, typing too fast... the first sentence of the second paragraph should be:

    At frame 15 I have defined the actions for all of the buttons used in the Animate file.