【问题标题】:Flash Player stops animating when out of viewportFlash Player 在超出视口时停止动画
【发布时间】:2012-12-04 10:44:44
【问题描述】:

我在一个网站上有几部 Flash 电影。它们都循环播放一个持续约 15 秒的动画(但这不是一成不变的)。它们都同时开始播放并且同步。

但是,当我调整浏览器窗口大小或滚动页面时,如果 Flash 播放器实例不在视口中,它将停止播放。当它返回到视口时,它会恢复并随后与其他 Flash 播放器实例不同步。

我的印象是这是一个 Flash 播放器优化。是否有可能通过 JS / AS3 禁用这种行为?它似乎发生在 Windows 上的 Firefox 和 Chrome 中。

更新

只是为了澄清。我有使用本地连接和 ExternalInterface 同步广告的方法。我正在寻找的是一种禁用 FlashPlayer“优化”的方法,它会导致帧速率大幅降低。

【问题讨论】:

  • 您是否尝试使用Event.ENTER_FRAME 推进当前帧(或您用于内容的任何容器)?行为是否相同?
  • 您能详细说明一下吗?您的意思是将当前帧推进到与其他电影相同的帧吗?
  • 这取决于电影的结构——它们是使用单个时间线还是由 ActionScript 驱动等。那里有很多变量。但基本的想法是,让加载的电影最初停止并创建一个 ENTER_FRAME 事件,它将把它带到下一帧。我能想到的另一个解决方案是在页面上使用一个固定定位的虚拟 1 x 1 像素 flash 电影,它将通过 LocalConnection 与加载的电影交互以推进它们的帧。但同样,如果每部电影的 FPS 设置不同,这将无法解决任何问题。

标签: javascript actionscript-3 flash


【解决方案1】:

您无法禁用此功能。当 Flash 应用程序不可见时,它可以降低内存和 CPU 使用率。

可供您使用的是一种叫做 Throttle API 的东西。这是一个专用 API,让 Flash 应用程序的创建者能够在他们的应用程序将要减速/节流时得到准确的通知。

这是一个例子。

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
         */
    }
}

现在您可以找到最适合您的方法,但我的建议是存储通过以下方式限制或暂停时经过的当前时间:

currentTime = getTimer();

然后计算您的应用程序恢复使用后经过了多长时间:

passedTime = getTimer() - currentTime;

然后用这些信息做你喜欢的事情。

希望这对您有所帮助,既然您熟悉了 Throttle API,应该可以为您提供更大程度的控制。有关它的更多信息,请在此处的文档中查看:ThrottleEvent

【讨论】:

    【解决方案2】:

    我相信这种行为是正常的,它是一种从未修复过的 flash 错误。

    我相信 inha 可能会为您提供解决方案,但不是在 enter_frame 事件中。这简直太残忍了。

    我会做的是:

    创建一个计时器事件.. 每 X 秒.. 所以它会调用一个 checkFunction, 在我的 checkFunction() 中。我会检查我的所有电影剪辑是否都已同步。 如果我发现 1 不是.. 我会放一个简单的 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  
        }
    

    【讨论】:

    • 感谢您的建议,但不幸的是,每个影片剪辑都包含在其自己的 Flash Player 实例版本中。据我了解,这不是错误,而是实际优化。从围绕主题的阅读来看,电影的帧速率似乎受到了限制,有时低至 2fps。理想情况下,我正在寻找禁用此限制的解决方案,而不是解决方法。
    【解决方案3】:

    如果每个 SWF 同时进行非常重要,我会通过 JavaScript 来控制它。

    假设每个 SWF 文件都是一个简单的 MovieClip,我会这样做:

    将每个 FLA 文件的 Document Class 设置为:

    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);
            }
        }
    }
    

    在 JavaScript 中,您可以将每个 SWF 实例的引用添加到数组中,然后使用计时器告诉每个 SWF 前进到帧号。

    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++;
    }
    

    请注意,此代码没有经过任何测试,仅用于说明我的思路。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-14
      • 1970-01-01
      • 2012-05-17
      • 2013-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多