Copy link to clipboard
Copied
Using HTML5 canvas.
I have a movie clip (mcTurn) on my timeline that plays in a loop and I have a button (button_1) that I want to use to control the movie clip with a play/stop function.
So far I got the movie clip to stop by using the following script:
this.button_1.addEventListener("click", stopAnim.bind(this));
function stopAnim()
{
this.mcTurn.stop();
}
But how do I add a play function to this code? I want the movie to resume playing again when clicked.
Back in the day I used the on(press) and on(release) functions for this, so I'm a little behind... I am not well-versed with action script 3 nor with HTML5 canvas functions.
Thank you very much!
Or this pointlessly clever version:
this.button_1.addEventListener("click", stopStartAnim.bind(this));
function stopStartAnim() {
var clip = this.mcTurn;
clip[clip.paused ? "play" : "stop"]();
}
Copy link to clipboard
Copied
Can you read through this discussion, the last messages should be the most useful:
https://forums.adobe.com/message/9748910?et=watches.email.outcome#9748910
Copy link to clipboard
Copied
Thanks for your reply Colin, I did try this but didn't work:
var playing:Boolean = false;
mcTurn.stop();
function startmcTurn(event:MouseEvent):void
{
if(mcTurn.currentFrame == mcTurn.totalFrames) {
playing = false;
}
if(playing){
mcTurn.stop();
} else {
mcTurn.play();
}
playing = !playing;
}
button_1.addEventListener(MouseEvent.CLICK, startmcTurn);
Copy link to clipboard
Copied
Of course that doesn't work, it's AS3 code. Try this instead:
this.button_1.addEventListener("click", stopStartAnim.bind(this));
function stopStartAnim() {
var clip = this.mcTurn;
if (clip.paused) {
clip.play();
}
else {
clip.stop();
}
}
Copy link to clipboard
Copied
Good point, and I should have noticed the mention of HTML5 Canvas. This might work for Canvas:
var playing = false;
this.mcTurn.stop();
function startmcTurn() {
if(this.mcTurn.currentFrame >= mcTurn.totalFrames-1) {
playing = false;
}
if(playing){
this.mcTurn.stop();
} else {
this.mcTurn.play();
}
playing = !playing;
}
this.button_1.addEventListener("click", startmcTurn.bind(this));
The this.mcTurn.stop() part may fail, and so from another discussion you could do this, if the movieclip in question is on the main timeline:
setTimeout(s,0);
function s(){
exportRoot.mcTurn.paused = true;
}
var playing = false;
function startmcTurn() {
if(this.mcTurn.currentFrame >= mcTurn.totalFrames-1) {
playing = false;
}
if(playing){
this.mcTurn.stop();
} else {
this.mcTurn.play();
}
playing = !playing;
}
this.button_1.addEventListener("click", startmcTurn.bind(this));
Copy link to clipboard
Copied
Using the Canvas specific 'paused' feature is a good idea.
Copy link to clipboard
Copied
Or this pointlessly clever version:
this.button_1.addEventListener("click", stopStartAnim.bind(this));
function stopStartAnim() {
var clip = this.mcTurn;
clip[clip.paused ? "play" : "stop"]();
}
Copy link to clipboard
Copied
Thank you!!! That did the trick! Clever indeed.
Copy link to clipboard
Copied
Just for your interest, it's the same as his other answer, just in a more obtuse syntax.
Copy link to clipboard
Copied
Thanks Colin, I will check out the Canvas specific pause function.
Copy link to clipboard
Copied
You are good at being pointlessly clever! I've never been fond of that syntax, I can never understand what it's doing.
Copy link to clipboard
Copied
It's just a combination of bracket notation and the ternary operator.
clip.bob is equivalent to clip["bob"]
Since you add () to perform a function call, then...
clip.stop() is equivalent to clip["stop"]()
The practical difference being that bracket notation allows accessing object properties by a variable value, unlike dot notation, which is strictly literal.
This ternary operator...
clip.paused ? "play" : "stop"
...returns the string "play" when paused is true, and "stop" when paused is false. So when you stick the above ternary operator between the brackets, you get this...
clip[ clip.paused ? "play" : "stop" ]()
The end result is that when paused is true it executes clip["play"](), and when paused is false it executes clip["stop"]().
For ultimate unmaintainable cleverness you can pack this entire thing into a one-liner by also using an anonymous function:
this.button_1.addEventListener("click", function(){this.mcTurn[this.mcTurn.paused ? "play" : "stop"]();}.bind(this));
Copy link to clipboard
Copied
That's very insightful, and unmaintainable is what I strive for... Thanks again!
Copy link to clipboard
Copied
Thanks for the explanation. Did I mention that I didn't want to understand that way of working?
Copy link to clipboard
Copied
Here's another clever solution that let's you reuse the function for different movieclips. The EventTogglePlaying function returns another function, which get triggered by the click event.
this.button_1.addEventListener("click", EventTogglePlaying(this.mcTurn));
function EventTogglePlaying (mc) {
return function () {
mc.paused? mc.play() : mc.stop();
}
}
Copy link to clipboard
Copied
Now you get to explain closures to everyone.
Copy link to clipboard
Copied
What do you mean by closures in this case?
Copy link to clipboard
Copied
It... it's literally what you just used in that code you posted. You haven't been using that code without understanding how it works, have you?
Copy link to clipboard
Copied
I'm trying to understand closures and everything else, but wonder if it would help my similar issue.
Using HTML5 Canvas I have a simple button that will open a box, and it works fine. But if I click the button again it opens the box again. I probably would not have noticed, but as I'm using TweenMax to open/animate the box its pretty obvious. Ideally I would like the box to disappear when the same button is clicked again.
My code
this.mc_Contact_Box.visible = false;
this.Contact_Btn.addEventListener("click", fl_ClickToShow_4.bind(this));
var tl = new TimelineMax({}) //<-----nothing here but I had tried the pause feature without success.
function fl_ClickToShow_4()
{
this.mc_Contact_Box.visible = true;
tl.from(this.mc_Contact_Box, .8, {y:300, scaleX:0, scaleY:0, ease:Back.easeOut});
}
I know TweenMax has a reverse function but no success implementing it. I was also trying an if else statement, but failed with that too! Any help appreciated.
Copy link to clipboard
Copied
Why are you weighting down your project with a third-party tween library, when Animate already has a perfectly good tween library built in? Unless you need some specific functionality that GSAP provides, or are tweening thousands of particles, there's no good reason not to use EaselJS instead. It is, after all, the same tween library Animate itself uses internally for Canvas documents.
That being said, you haven't stated what your problem is. The box opening animation plays every time you click the button. That's exactly what you've coded it to do, so it sounds like it's working correctly.
Copy link to clipboard
Copied
Hi, I've moved my question to a new topic and removed any tweening for now. Open and close action with single button
Copy link to clipboard
Copied
I mentioned that "The EventTogglePlaying function returns another function, which get triggered by the click event", which I thought explained how it worked. I could have explained the ternary operator, but you already did that.
Copy link to clipboard
Copied
To add the play function, you can toggle between play and stop like this:
```javascript
this.button_1.addEventListener("click", toggleAnim.bind(this));
function toggleAnim() {
if (this.mcTurn.isPlaying) {
this.mcTurn.stop();
this.mcTurn.isPlaying = false;
} else {
this.mcTurn.play();
this.mcTurn.isPlaying = true;
}
}
```
This will allow your button to both play and stop the movie clip.