Monday, December 6, 2010

Resizing Dynamically Loaded swfs using swfloader

In my current project, I am using RobotLegs and a parent application to load in "modules".  However, I don't use modules, because frankly, I don't quite get why I should.  Instead, I have separate swfs that I can load, and pass information to them, if necessary.  The biggest frustration that I have is that when I resize the parent application, my child, which is a loaded swf, doesn't know it's stage has been resized, and thus doesn't resize itself.  To fix that, I tried a few different options, including resizing the loader, the system manager, the loaded application, the screen, everything!!!

The problem I was running into is that my loaded swf was getting it's size clipped.  This was unacceptable.

For example, if I loaded my swf into my app, if the window was sized at 700x400 (w x h), if I resized my window to something smaller, the controls inside the loaded swf would follow accordingly. However when I resized the window larger than 700x400, the controls would get clipped by an auto-assumed max size of the loaded swf's stage.

GRRRRRRR!!!!!!

So I have lost countless hours of sleep, including the time it's taking me to post this incoherent message.  But I feel I must share about resizing a loaded swf without scaling.   Right now I have some jerkiness in the movement, but it forces a scale and resize of the loaded swf's width and height.

I avoid using the _loadedSwf.scaleContent and _loadedSwf.maintainAspectRatio.  These together were fun to figure out, but the end result was that my controls were scaling, and I didn't want that.  If I turned off scaleContent, then nothing would resize.  If I turned off aspect ration, then things started looking wonky.

because I had added my _loadedSwf to a SkinnableContainer, and that container was getting resized, I wanted my _loadedSwf to update to that container's size.  On initialization I do use a method inside _loadedSwf.  And to use that, I have something like the following:

var loadedSM:SystemManager = SystemManager(_loadedSwf.content)
loadedSM.application["updateDimensions"](container.width, container.height);

This worked great for the initial setup, but resizing still didn't work.  I won't recount the countless hours I've tried to make it work.  Needless to say, and the reward for reading this post is to see that to make this work, I did the following on the resizeMyApp(), called by the parent application whenever an EVENT.RESIZE_EVENT is dispatched:

_loadedSwf.content.width = container.width;
_loadedSwf.content.height = container.height;
Object(_loadedSwf.content).setActualSize(container.width, container.height);
loadedSM.application["updateDimensions"] (container.width, container.height);

I got the idea on page 48 of this manual (Thank you Matt Horn!!!)

http://livedocs.adobe.com/flex/3/loading_applications.pdf 


These last 2 lines seem a bit hazy to me, but if I remove one of them, then the resizing doesn't work.  I do have some jerkiness that I need to work out, but the overall resizing now commits correctly.  I think there is something in the updateDisplayList() that I've missed, but somehow this makes the call work.

3 comments:

  1. Thanks a ton! I've been banging my head against this for two days now!

    your code did not fit exactly for me, so I did some modifications to it. Have a look and maybe drop me a line on what you think about it.

    http://lifesdev.blogspot.com/2011/02/resizing-dynamically-loaded-swfs-using.html

    cheers rob

    ReplyDelete
  2. Hi Rob,

    It's an interesting way to do it, so I'm mostly curious about frame rate and smoothness of transition. Thx,

    LordB8r

    ReplyDelete
  3. Thanks for the post.. It really helps.

    ReplyDelete