Skip to main content
Participating Frequently
September 27, 2020
Answered

Play until frame?

  • September 27, 2020
  • 2 replies
  • 1750 views

There's gotoAndPlay() and gotoAndStop(), but is there a function to play until a frame number?

 

The functions I mentioned directly jump to that frame, I want the animation to play until that frame and then stop. 

    This topic has been closed for replies.
    Correct answer ClayUUID

    I have a bunch of buttons numbered from one to ten.

     

    Then I have a shape tween that goes from size zero to size ten.

     

    If I press the button six, the shape tween should grow to size six. I can get the frame number to which it should go and stop, but I don't want it to just jump to that frame and stop. 

     

    I want the shape tween to animate until that frame and then stop.


    I see. Tricky. Well, this is somewhat abusing the way Animate wants to work, but give this a shot:

     

    createjs.MovieClip.prototype.playTo = function(dest) {
    	this.playtoFrame = this.timeline.resolve(dest);
    	this.timeline.removeEventListener("change", this.playtoListener);
    	if (this.playtoFrame > this.timeline.position) {
    		this.playtoListener = this.timeline.addEventListener("change", (function(evt) {
    			if (this.timeline.position === this.playtoFrame) {
    				this.paused = true;
    				evt.remove();
    			}
    		}).bind(this));
    		this.play();
    	}
    }

    Just paste somewhere in your setup code, probably the first frame. Then call as e.g.--

    this.myClip.playTo(5);

    2 replies

    JoãoCésar17023019
    Community Expert
    Community Expert
    September 28, 2020

    Hi.

     

    Here is an experiment in which I add a goUntil method to any MovieClip instance. Just add these lines in the beginning of your code:

    createjs.MovieClip.prototype.goUntil = function(positionOrLabel)
    	{
    		var duration;
    		var to = this.timeline.resolve(positionOrLabel);
    		
    		this.tweenFrame = this.timeline.position;
    		
    		if (this.tweenFrame == null)
    			return;
    
    		duration = Math.abs(((to - this.tweenFrame) / lib.properties.fps) * 1000);
    		
    		createjs.Tween.get(this, { override: true }).to({ tweenFrame: to }, duration).addEventListener("change", function(e)
    		{
    			var target = e.currentTarget.target;
    			
    			target.gotoAndStop(Math.round(target.tweenFrame));
    			
    			if (target.tweenFrame === to)
    				e.currentTarget.removeAllEventListeners("change");			
    		});
    	};

     

    Then you can call the goUntil method in any instance like you would do with the gotoAndStop and gotoAndPlay methods. Like this:

    this.yourAnim.goUntil(19);
    // or
    this.yourOtherAnim.goUntil("intro");

     

    Preview:

    https://bit.ly/2FYu3Hz

     

    Files / code / FLA / source:

    https://github.com/joao-cesar/adobe/tree/master/animate%20cc/html5_canvas/play_until_frame

     

    Please let me know if the code needs to be fixed or improved or if you need further assistance.

     

    Regards,

    JC

    Jeffery.Wright
    Inspiring
    February 28, 2023

    JC, That is incredibly handy code and works a treat.

     

    Your code captures clicks on a MC on the parent/root timeline, from within the MC that does the animating between Labeled frames. I am trying to alter it to capture clicks from within the same MC that animates between the frames but having no luck. ( I am trying to emulate an accordion-style navigation menu) 

    On the root I have a MC named main_NAV. main_NAV has labelled frames to tween to and from. main_NAV also has the buttons that when clicked should initiate the animation. 

     

    I tried altering the code: 

     

     

    // Referring to the MC to itself from the root didn't work:
    exportRoot.main_NAV.on("click", function(e)
    // nor did:
    this.parent.main_NAV.on("click", function(e)
    // Referring to the MC to itself locally didn't work:
    this.on("click", function(e)
    	{ // I always get scope wrong, neither of these worked:
    this.goUntil(e.target.name);
    // nor:
    root.goUntil(e.target.name);
    	});

     

     

     

    It would be very efficient, modular and compact to have a self contained MC that tweened from one Labelled frame to another. The solution may be very obvious to you, but I'm stumped, am I missing something simple?

     

     

    Grateful for any insight, thanks!

     

     

     

    JoãoCésar17023019
    Community Expert
    Community Expert
    February 28, 2023

    Hi, Jeffery!

     

    I'm glad you liked and that that's useful to you.

     

    If I understand correctly what you want, the code to play a Movie Clip instance by clicking on a button that lives inside of this same Movie Clip instance could be something like this:

    this.main_NAV.yourButton.on("click", function(e)
    {
        this.parent.goUntil(this.name);
    });

     

    In this case, this.parent is the timeline that you want to animate and this is the button that received the event listener.

    If this is confusing, is always a good idea to save the context in an outer scope first. Like this:

    var targetAnim = this;
    
    this.main_NAV.yourButton.on("click", function(e)
    {
    	targetAnim.goUntil(this.name);
    });

     

    I hope this makes sense.

     

    Regards,

    JC

    Legend
    September 27, 2020

    If you want playback to stop on a frame, put a stop() on that frame.

    ruturaj20Author
    Participating Frequently
    September 27, 2020

    I do not know in advance which frame it is going to be. 

    Legend
    September 27, 2020

    Explain. It sounds like you're trying to use Animate in a wrong way.