【问题标题】:addChild(): How can I know when a DisplayObject is actually displayed on the stage?addChild():如何知道 DisplayObject 何时实际显示在舞台上?
【发布时间】:2012-12-22 19:30:45
【问题描述】:

我已经将一个大 (4096x4096) 图像加载到内存中,但是当我尝试使用 addChild 时,它实际上会被绘制到屏幕上之前有很长的延迟。这是意料之中的。但是,是否有一个事件可以让我知道 DisplayObject(一个 .png 图像)实际被绘制到屏幕上的那一刻?

我正在尝试将图像加载到屏幕上,然后在它们实际绘制后执行一些操作。

【问题讨论】:

  • 到目前为止,我的解决方法是以 100 毫秒运行一个计时器,不断检查 DisplayObject 的宽度。一旦数字大于0,我就知道它终于被绘制到屏幕上了。
  • Event.ADDED_TO_STAGE 有效吗?还是仅在添加后,在实际渲染之前直接调度?
  • 您是从外部加载图像还是在 swf 中编译此图像?
  • 除了 Additional_To_Stage(如果为时过早的话),您可能需要查看 RENDER 事件。当然,如果您只需要能够操作 bitmapData,您可以使用 Loader 中的 COMPLETE 事件(如果它是在运行时加载而不是嵌入)。
  • 啊,那好吧。认为这可能值得一试。据我所知,您在第一条评论中的解决方案可能会尽可能好,但也许使用 ENTER_FRAME 而不是每 100 毫秒在每个新帧上检查它可能会更好。我对优化了解不多,但是由于您检查渲染时间,因此检查每一帧可能会更有效。

标签: actionscript-3 flash addchild displayobject


【解决方案1】:

如果您使用的是 Loader 类,那是因为内容尚未加载。

您的代码中的某处可能有这样的内容:

var loader : Loader = new Loader();
loader.load( new URLRequest( "theURL" ) );
stage.addChild( loader );

现在,这一切都在几毫秒内发生。您正在加载的内容实际上尚未加载。加载器在舞台上,但内容在加载完成之前不会放入加载器中。

这是你需要做的。

var loader : Loader = new Loader();
loader.contentLoaderInfo.addEventListener( Event.COMPLETE, onImageLoaded, false, 0, true );
loader.load( new URLRequest( "theURL" ) );
stage.addChild( loader );

然后在同一个作用域内拥有这个函数。

function onImageLoaded( evt : Event ) : void
{
    loader.contentLoaderInfo.removeEventListener( Event.COMPLETE, onImageLoaded );
}

在该函数中,可以访问图像及其所有属性。它可能还没有真正绘制到屏幕上,但这将在下一帧发生,可能在几毫秒内,但就代码而言,它已经在舞台上。

希望有帮助!

【讨论】:

  • 谢谢,你说得对,我使用的是加载器(具体来说是 greensock LoaderMax 库)。获取对象的属性不是问题。即使我将图像完全加载到内存中(甚至在编译时将它们嵌入到 SWF 中,而不是使用加载器),通过 addChild 将它们添加到显示器的行为似乎会增加延迟(对于 10MP+ 的大图像) .如果我尝试将 addChild 用于可见 = false 的父级。然后在加载和添加子级后将该父级设置为 visible.true 时,会导致同样的问题。
  • 似乎您无法使用 DisplayList 渲染器来解决您的问题,但使用完全不同的渲染方法可能会有所帮助。您是否尝试过使用 Starling 或其他基于 Stage3D 的 2D 框架?使用 Stage3D,您的纹理尺寸被限制为 2048x2048,但您可以将较大的图像分成几块。
  • @borisgolovnev - 我已经研究了 Starling 以提高性能,如果随着开发的继续,这个问题变得更加普遍,我可能确实需要走这条路。谢谢,我会继续将其视为一种选择。我也考虑过使用像 DeepZoom 这样的东西,它将高分辨率图像分割成许多不同的图块,但是大多数项目都被放弃了,而且它也不是一个完美的选择。但是带有剔除功能的图块系统将是另一个不错的选择……如果它已经存在的话。
【解决方案2】:

延迟是由于 Flash Player 解压缩图像以准备渲染。

诀窍是在需要之前强制 Flash Player 解压缩 - 然后它会“立即”出现在舞台上。

我不能把任何想法归功于我 - 但我会接受赏金;)。这是启发我并充分解释它的文章:http://jacksondunstan.com/articles/2080

【讨论】:

  • 哇,正是我想要的,谢谢。它仍然是一个 hack - 但它似乎是我希望的最佳答案。
  • 太棒了。我不知道它是这样工作的,那篇文章既有趣又非常有帮助。我有时也会处理大量图像,所以我将来肯定会使用它。并不是说我完全需要这个功能,但它仍然会有所帮助。非常感谢。也感谢你的生产主义,因为你提出了这个问题并设置了赏金来得到这个答案;)
  • np,很高兴这也可以帮助其他人。仅供参考,这是一个更详细的链接。显然,您可以设置加载程序的 loaderContext 属性,以便在解压缩之前它不会触发 COMPLETE 事件。它甚至指定这对于 AIR 应用程序的 10MP+ 图像很有用。不能要求比这更多的信息了! help.adobe.com/en_US/as3/dev/…
  • 哇哦,谢谢。也是异步的! Lee 的解决方案虽然很棒,但从我所看到的来看似乎是同步的。因此,如果您有一个真正庞大的图像,它可能会锁定应用程序一段时间。当然,如果您不使用Loader,那么您可能无论如何都不会遇到如此巨大的图像,但仍然如此。无论哪种方式都很棒,谢谢分享!
  • 很好地使用了 loaderContext 信息!这绝对是要走的路。它也应该适用于嵌入式图像;通过使用 Loader.loadBytes(byteArray, loaderContext);
猜你喜欢
  • 2014-06-23
  • 1970-01-01
  • 1970-01-01
  • 2011-05-06
  • 1970-01-01
  • 2011-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多