Flash Player stops animating when out of viewport

I have several flash movies on a site. They all loop through an animation which lasts for approximately 15 seconds (but this is not set in stone). They all begin to play at the same time and are in sync.

However, when I resize the browser window, or scroll the page, if a flash player instance is not in the viewport, it stops playing. When it returns to the viewport, it resumes and subsequently is out of sync with the other flash player instances.

I am under the impression this is a flash player optimisation. Is there anyway of disabling this behaviour, possibly through JS / AS3? It appears to happen in Firefox and Chrome on Windows.

UPDATE

Just to clarify. I have methodologies in place using local connection and ExternalInterface to sync the ads. What I am looking for is a method to disable the "optimisation" of FlashPlayer which results in the frame rate being drastically reduced.

Answers:

Answer

You can't disable this feature. It's put in place to lower the memory and CPU use when the flash application isn't visible.

What is available for you though is something called the Throttle API. This is a dedicated API created to allow creators of Flash applications the ability to be notified exactly when their application is going to be slowed down/throttled.

Here's an example.

addEventListener(ThrottleEvent.THROTTLE, onThrottleEventHandler);

function onThrottleEventHandler(e:ThrottleEvent):void
{
    if(e.state == ThrottleType.THROTTLE)
    {
        /**
         * the player is about to be slowed down to a frame rate
         * set in e.targetFrameRate
         */
    }
    else if(e.state == ThrottleType.PAUSE)
    {
        /**
         * the player is going to be paused completely, AKA 0 fps
         */
    }
    else if(e.state == ThrottleType.RESUME)
    {
        /**
         * the player is now back to normal as it has resumed
         * from the paused or throttled state
         */
    }
}

Now you can figure out a way that works best for you but my suggestion is to store the current time that has passed whenever being throttled or paused via:

currentTime = getTimer();

Then calculate how much time has passed once your application has resumed using:

passedTime = getTimer() - currentTime;

Then do what you like with this information.

Hopefully this has helped, should offer you a greater degree of control now that you're familiar with the Throttle API. For more information on it, check it out in the documentation here: ThrottleEvent

Answer

I belive this kind of behavior its normal, its kind of a bug of flash that has never been fixed.

I belive inha may got u a solution, but not on an enter_frame event. that just to brutal.

what I would do is:

create a timer event.. each X seconds.. so it will call a checkFunction, in my checkFunction(). I would check if all my movieClips are syncronized. and if I found 1 that is not.. ill put a simple gotoAndPlay(xFrame);

    var aMovieClips:Array; //get all ur movieclips into this array.

    var timeToCheck = 1000; //time to check for a unsincronized movieclip
    var time:Timer=new Timer(timeToCheck,0);//do inifinite call each 1000 seconds
    time.start();
    time.addEventListener(TimerEvent.TIMER, checkFunction);

    public function checkFunction(e:TimerEvent):void
    {
    var aCurrentFrames:Array;
    for (var n:int = 0;n<aMovieClips.length();n++)
        aCurrentFrames.push(aMovieClips[n].currentFrame);
    //so now u have all current frames of all movie clips.. so u can add a
    //gotoAndPlay(x); to any unsyncronized movieclip  
    }
Answer

If it is very important that each SWF progresses simultaneously, I would control it by JavaScript.

Assuming each SWF file is a simple MovieClip, something like this is how I would go about it:

Set the Document Class of each FLA file to this:

package {
    import flash.display.MovieClip;
    import flash.external.ExternalInterface;

    public class ExternalInterfaceControlledMC extends MovieClip {

        public function ExternalInterfaceControlledMC() {
            this.stop();
            if (ExternalInterface.available) {
                try {
                    ExternalInterface.addCallback("setFrame", jsSetFrame);
                } catch (error:Error) {
                    trace("An Error occurred:", error.message);
                }
            } else {
                trace("ExternalInterface is not available");
            }
        }

        private function jsSetFrame(value:String):void {
            var frameNumber = int(value) % this.totalFrames;
            this.gotoAndStop(frameNumber);
        }
    }
}

In the JavaScript, you would add a reference of each instance of the SWFs into an array, then use a timer to tell each SWF to progress to a frame number.

var swfElements; //Array
var currFrame = 1;

function onPageLoad() {
    //Init timer
    setInterval("progressFrame", 1000 / 30); //30 fps
}

function progressFrame() {
    for (var i = 0; i < swfElements.length; i++) {
        swfElements[i].setFrame(currFrame);
    }
    currFrame++;
}

Please beware that nothing about this code is tested and is only meant to be used to illustrate my train of thought.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.