• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

How do I instruct a button to play a specific range of frames (i.e. "play from frame labelled X to frame labelled Y")

Community Beginner ,
Apr 21, 2018 Apr 21, 2018

Copy link to clipboard

Copied

I'm sue this is very basic, but I cannot find the answer anywhere.  I am making an HTML5 canvas doc.

Thank you to any who can help.

Views

1.3K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

LEGEND , Apr 23, 2018 Apr 23, 2018

I thought of a safer approach, for the case where you want to either play one animation or all animations. You could have. variable that you test. On the last frame of each animation you have this:

if(playone) this.stop();

Then, when you tell them to play one animation you do this:

playone = true;

this.gotoAndPlay("animation 3");

Animation 3 would play, and it would stop on the last frame of that animation. If you want to play all animations you would do:

playone = false;

this.gotoAndPlay("animation 1"

...

Votes

Translate

Translate
Community Expert ,
Apr 21, 2018 Apr 21, 2018

Copy link to clipboard

Copied

Hi.

You code your button play from the initial label using your_movie_clip.gotoAndStop("X") and then you put a this.stop() inside of your_movie_clip in the frame where your label "Y" begins.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 21, 2018 Apr 21, 2018

Copy link to clipboard

Copied

Hi, thanks for responding!  Not sure if that would work.  I have no movie clips.  I may not have explained what I am trying to do clearly.

They easiest way to describe it would be, if I had a 100 frame animation, I need the user to be able to just play the whole thing straight through (1-100), or, when clicking a button, they play frames 70-90 (start at 70, end at 90).  And there will be several instances where they can click a button and play a specific range.  I can't put stops anywhere because that will disrupt the flow of those who want to watch it straight through. 

EDIT Sorry, I misunderstood your use of "movie clip" when stating I have no movie clips.  Basically I need the "stop and play" command to reside within the action for the button instance, and not be tied to any particular frame.  Thanks

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 21, 2018 Apr 21, 2018

Copy link to clipboard

Copied

Trying to make it more clear here -

Basically, for the following line:

_this.gotoAndPlay(XXXXX);

What would I put in place of "XXXXX" to mean "frames 70 to 90"?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 23, 2018 Apr 23, 2018

Copy link to clipboard

Copied

Nothing. The gotoAndPlay() function Does Not Work That Way. If you want playback to stop on a certain frame, you put a this.stop() on that frame.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 23, 2018 Apr 23, 2018

Copy link to clipboard

Copied

Thank you for replying.  Is there another way I can make this happen?  I don't think I can put stop () in that frame because I want the user to be able to watch the entire movie straight through if they choose (without getting stopped at that frame).

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 23, 2018 Apr 23, 2018

Copy link to clipboard

Copied

Sigh. Okay, if you're dead set on doing whatever weird thing you're doing, paste this code somewhere in your initialization where it will only ever be run once.

createjs.MovieClip.prototype.playRange = function(startFrame, stopFrame) {

    var _this = this;

    stopFrame = _this.timeline.resolve(stopFrame);

    if (_this.playingRange) {

        createjs.Ticker.removeEventListener("tick", _this.playingRange);

    }

    _this.playingRange = createjs.Ticker.addEventListener("tick", function() {

        if (_this.currentFrame >= stopFrame) {

            createjs.Ticker.removeEventListener("tick", _this.playingRange);

            _this.playingRange = 0;

            _this.stop();

        }

    });

    _this.gotoAndPlay(startFrame);

}

This adds a new movieclip method that supports playing a range of frames. Either parameter can be a frame number or a frame label. Use like this:

this.playRange(20, 50);

...or whatever. There's no error checking, so use responsibly.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 23, 2018 Apr 23, 2018

Copy link to clipboard

Copied

Thank you!  I will try this.

But, from your subtle tone , I'm thinking I've set out to do this is in a dumb way?  Is there a better way to do it?

"It" being (I'm rounding all numbers etc for simplicity sake):

  • I have a thousand frame movie.
  • Every one hundred frames represents an animation (so there are ten animations that play in order).
  • I want to have controls that:

1) Allows the user to watch all ten animations, in order, straight through (play button)

2) Allow the user to skip to the next or previous animation, and just that animation (next, previous buttons)

3) Allow the user to skip directly to any individual animation, and just that animation (go to x)

Thanks.  You've helped a lot already so if not in the mood to keep going that's totally fine, I get it, and I appreciate the responses already.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 23, 2018 Apr 23, 2018

Copy link to clipboard

Copied

A different approach, that may not always be frame accurate, but perhaps that doesn't matter, would be to use setTimeout():

var startframe = 20;

var endframe = 53;

//and for this example the frame rate is 24 fps

var framerate = 24;

var self = this;

this.gotoAndPlay(startframe);

setTimeout(dostop, (endframe - startframe + 1) / 24 * 1000);

function dostop() {

  self.stop();

  alert(self.currentFrame);

}

I tried it a lot of times, and it stopped on the right frame each time.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 23, 2018 Apr 23, 2018

Copy link to clipboard

Copied

I thought of a safer approach, for the case where you want to either play one animation or all animations. You could have. variable that you test. On the last frame of each animation you have this:

if(playone) this.stop();

Then, when you tell them to play one animation you do this:

playone = true;

this.gotoAndPlay("animation 3");

Animation 3 would play, and it would stop on the last frame of that animation. If you want to play all animations you would do:

playone = false;

this.gotoAndPlay("animation 1");

The last frame of the last animation would have:

this.stop();

so that it stops whether you were playing one or all animations.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 24, 2018 Apr 24, 2018

Copy link to clipboard

Copied

Sorry for the late response!  Thank you for these two replies Colin.  I will try the latter approach.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 24, 2018 Apr 24, 2018

Copy link to clipboard

Copied

So you're going with the solution that requires adding timeline code to every single chunk of frames.

People confuse me.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 29, 2018 Apr 29, 2018

Copy link to clipboard

Copied

I don't really know what I'm doing and therefore I actually don't know which solution is best.  I'm not sure which one I will eventually end up implementing.  I'm going to experiment with what I've learned here, and I'm thankful for everyone's input.  I didn't mark this as answered, if that's what you are referring to.  I'm not sure how that happened (unless I did it by accident).

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 19, 2023 Apr 19, 2023

Copy link to clipboard

Copied

LATEST

Thanks for this ClayUUID, it worked perfectly.  My use case was similar except I did not need to play through all the animations.   Our designer created a bunch of actions on the timeline with labels for each action,  we just wanted to make each action playable from outside of the animation.  So I walked through each label and used your PlayRange aproach to play just the frames in that label.  Then attached each method to a global object so we could access from outside of the animation file.  For good measure I wrapped it in a promise for chaining and pass in a boolean for optionall looping.   So I could control the animation like this: 

// window.<instanceName>Animations.<anyLabelName>(loop: bool);
window.rockyAnimations.idle(true)
window.rockyAnimations.lip_flap()
window.rockyAnimations.lip_flap().then(()=> {window.rockyAnimations.idle(true)})

 

If there is a better way of doing this, I would be very interested.  But here is what I ended up with:

// drop this code in an action on the first frame
var _this = this;
// this should be renamed to whatever you named your <instanceName>
const uniqueInstanceName = "rocky";

// with some help from this suggestion: https://community.adobe.com/t5/animate-discussions/how-do-i-instruct-a-button-to-play-a-specific-range-of-frames-i-e-quot-play-from-frame-labelled-x-to/td-p/9849836
cjs.MovieClip.prototype.playRange = function(startFrame, stopFrame, loop) {
	return new Promise((resolve, reject) => {
		var _this = this;
		stopFrame = _this.timeline.resolve(stopFrame);
		if (_this.playingRange) {
			cjs.Ticker.removeEventListener("tick", _this.playingRange);
		}
		_this.playingRange = createjs.Ticker.addEventListener("tick", function() {
			if (_this.currentFrame >= stopFrame) {
				cjs.Ticker.removeEventListener("tick", _this.playingRange);
				_this.playingRange = 0;
				if(loop) {
					_this.playRange(startFrame, stopFrame, loop);
					resolve();
				}
				else {
					_this.stop();
					resolve();
				}
			}
		});
		_this.gotoAndPlay(startFrame);
	});
}

const animationList = window[uniqueInstanceName + "Animations"] = {};
const instance = _this[uniqueInstanceName];
const labelsWithEndPosition = [];

for(let i = 0; i < _this.labels.length; i++) {
	let endPosition = _this.timeline.duration - 1;
	if(i + 1 < _this.labels.length) {
		endPosition = _this.labels[i+1].position - 1;
	}
	labelsWithEndPosition.push({
		label: _this.labels[i].label,
		start: _this.labels[i].position,
		end: endPosition
	});
}
labelsWithEndPosition.forEach(
	labelObj => {
		animationList[labelObj.label] = function (loop = false) {
			return instance.playRange(labelObj.start, labelObj.end, loop);
		};
	}
)

animationList.stop = function() { instance.stop(); }
instance.stop();

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines