Hi,

I've created a 'fake' sound equalizer which acts as a sound toggle button. When the music plays the animation plays with the sound and when you click the animation it stops as does the sound.

However, i want the animation to play on ENTER_FRAME, but cant figure out how to do it :confused:

here's the code i have

toggleButton.addEventListener(MouseEvent.MOUSE_OVER, rolloverToggle);
toggleButton.addEventListener(MouseEvent.MOUSE_OUT, rolloutToggle);
toggleButton.addEventListener(MouseEvent.CLICK,toggleClick);



var song:Sound = new Sound();
var songChannel:SoundChannel = new SoundChannel();
song.load(new URLRequest("nyc.mp3"));

function rolloverToggle(event:MouseEvent) {
	toggleButton.gotoAndStop(toggleButton.buttonState+" over");
}

function rolloutToggle(event:MouseEvent) {
	toggleButton.gotoAndStop(toggleButton.buttonState);
}
function toggleClick(event:MouseEvent) {
	if (toggleButton.buttonState == "on") {
		toggleButton.buttonState = "off";
		stopSong();
	} else {
		toggleButton.buttonState = "on";
		startSong();
	}
	toggleButton.gotoAndStop(toggleButton.buttonState+" over");
}
function startSong(){ 
	songChannel = song.play();
	songChannel.addEventListener(Event.SOUND_COMPLETE, songCompleteHandler);
}
function stopSong() {
	songChannel.stop();
}
function songCompleteHandler(event:Event) {
	toggleButton.buttonState = "off";
	toggleButton.gotoAndStop(toggleButton.buttonState+" off");
}

any help would be appreciated :)

Dani AI

Generated

For — the approach in the replies is on the right track. A few practical clarifications and troubleshooting tips will make an ENTER_FRAME-driven equaliser robust and easier to maintain.

Keep the animation separate from the button states. Put the bars in a child MovieClip inside the button (so the parent manages "on/off/over" labels while the child handles per-frame animation). That avoids fighting the parent timeline and lets the child be play()/stop()-driven or updated from an ENTER_FRAME handler. Note that 's example is correct in principle but contains a small typo (addEventListenter); also make sure the handler signature uses Event (not MouseEvent) so the ENTER_FRAME callback is accepted.

Common failure points to check:

  • The listener was added before the clip was actually on stage (ENTER_FRAME will not fire if the target is not on display list).
  • The listener was removed with a mismatched function reference or misspelt method name.
  • Multiple plays produce overlapping channels — always stop an existing SoundChannel (or guard for null) before starting a new one to avoid dupe playback.
  • Leaving ENTER_FRAME handlers active after stopping the sound causes CPU cost and unexpected behavior; always remove the handler when stopping.

If the goal is a real, sound-reactive equaliser rather than a fake/random animation, use ActionScript audio analysis (SoundMixer.computeSpectrum for FFT-like spectrum data, or Sound.extract/SampleDataEvent for sample-level work). Also base motion on frame time (or stage.frameRate) so the animation runs consistently across machines.

Quick checklist:

  • Use a MovieClip for animated bars, not a SimpleButton timeline.
  • Nest the equaliser as a child clip so parent labels stay simple.
  • Spell addEventListener/removeEventListener correctly and use Event for ENTER_FRAME.
  • Guard SoundChannel before calling stop().
  • Remove the ENTER_FRAME handler when stopping to avoid leaks and extra CPU.

Recommended Answers

All 2 Replies

So toggleButton is also the equaliser animation?

If that is the case, then perhaps you could do something like this in your startSong function:

function startSong(){ 
	songChannel = song.play();
	songChannel.addEventListener(Event.SOUND_COMPLETE, songCompleteHandler);
	toggleButton.addEventListenter(Event.ENTER_FRAME, animateToggleButton);
}

You should also remove the ENTER_FRAME event handler in your stopSong function.

The animateToggleButton function, or whatever you decide to call it should then contain whatever code is necessary to animate the button.

This function will be then be called every frame while the song is playing.

Not sure if that's what you're after.

Alternatively, you could perhaps make the animation code a part of the toggleButton class. So if you want the animation to be done on a per frame basis using the ENTER_FRAME event, you could create a private event handler function in the toggleButton's class declaration to deal with the ENTER_FRAME event (I'll call it doAnimation, but you can call it whatever you like!) and then you just create two public functions in the class called something like startAnimation and stopAnimation. The functions should do something like this:

private function doAnimation(e:Event):void
{
 	// TODO: Your frame based animation code here
}

public function startAnimation():void
{
 	this.addEventListener(Event.ENTER_FRAME, doAnimation);
}

public function stopAnimation():void
{
	this.removeEventListener(Event.ENTER_FRAME, doAnimation);
}

That way from your startSong you can do this:

function startSong(){ 
	songChannel = song.play();
	songChannel.addEventListener(Event.SOUND_COMPLETE, songCompleteHandler);
	toggleButton.startAnimation();
}

Likewise in stopSong you can call toggleButton.stopAnimation(); to stop the animation.

Cheers for now,
Jas.

Member Avatar for Member #334542

Jason, you explained clearly and one more thing I want to add to Mr. amistry:

If your animation want to play using onEnterFrame, you should keep a single frame for that to do. (ie) your equalizer animation should be done with the event handler of onEnterFrame with code in a single frame.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.