Flex: Impossible to resize the external loaded SWF's content - apache-flex

I have an application where I try to load an external SWF. So, we have:
My application: The Stage's dimensions are 768x1280. ScaleMode = EXACT_FIT.
External SWF: It's another application where its stage is: 800x600. ScaleMode = EXACT_FIT.
The problem is that the external SWF does not modify its size although I apply "scaleX, scaleY", change its width and so on.
I also tried to insert it into a Canvas container (as "How to resize an external SWF to fit into a container?" ) but it didn't solve my problem.
The interesting piece of code is when the external SWF is loaded by my application:
private function onLoadedApp( evt:Event ):void{
stage.scaleMode = StageScaleMode.EXACT_FIT;
trace("Loading Application..");
var loaderInfo:LoaderInfo = evt.target as LoaderInfo;
loaderInfo.removeEventListener( Event.COMPLETE, onLoadedApp);
trace(loaderInfo.loader.content);
var swfApplication:SpriteUIComponent = new SpriteUIComponent(evt.target.loader.content );
if( SWFContainer.width < swfApplication.explicitWidth ){
var coef:Number = SWFContainer.width/swfApplication.explicitWidth;
swfApplication.scaleX = coef;
swfApplication.scaleY = swfApplication.scaleX;
}
SWFContainer.addElement(swfApplication);
}
I also tried to do it through SWFLoader, but the external.swf's content doesn't change its original size although I add the "scaleContent" parameter.
Visual results I got:
The external SWF is loaded on the suitable position and it "seems" to have 320x240 dim. But its width is a bit cropped, since if I stretch the Flash Player I achieve to see the rest of the external swf's stage. Besides, the external SWF never is resized although I shrink/stretch the Flash Player. It always remains fixed (if I trace its dimensions, I always get 800x600, although I visually see 320x240)- If I increase the stage's width of the main application, this little clip dissapear.
Discussion:
I know the original Stage's dimensions are 800, and this is greater than the original stage of my application (768), but I think, when I do the resizing, external SWF's Stage have to be fitted in the container. It is fitted, but a part of the external SWF is not seen. It's like Flash Player remembered that the external SWF Stage's width were greater than my application's one...
Thanks in advance.

Even with scaleContent set to "true" you still need to set an exact height and width to the SWFLoader control for it to even try resizing the internal SWF. All scaleContent does is instead of showing the SWF at regular or stretched sizes, it also up-scales the SWF if needed, and if not just scales it to retain the ratio of the original SWF.

I don't think the issue is with your ScaleMode. There can only be one Stage per flash player. The "stage" property of your 'external' SWF references the Stage of your 'application' SWF after it's added to the display list. If the SWF is loaded and not added to the display list, the loaded SWF's 'stage' property will equal 'null'. Setting the stage scaleMode inside your external SWF won't dictate how it scales once loaded into another SWF.
Also, you're probably resizing the SWFContainer, not the SWF itself...thats why the SWF width and height properties are always 800x600. I'm not sure if this is what you're asking for, but from what I'm understanding, you may need to create a stage resize event listener.

Have you tried to use a scale effect on "External SWF"?
Scale Effect

Related

Flex/AS3: How to resize the external SWF's content in another SWF [duplicate]

I have an application where I try to load an external SWF. So, we have:
My application: The Stage's dimensions are 768x1280. ScaleMode = EXACT_FIT.
External SWF: It's another application where its stage is: 800x600. ScaleMode = EXACT_FIT.
The problem is that the external SWF does not modify its size although I apply "scaleX, scaleY", change its width and so on.
I also tried to insert it into a Canvas container (as "How to resize an external SWF to fit into a container?" ) but it didn't solve my problem.
The interesting piece of code is when the external SWF is loaded by my application:
private function onLoadedApp( evt:Event ):void{
stage.scaleMode = StageScaleMode.EXACT_FIT;
trace("Loading Application..");
var loaderInfo:LoaderInfo = evt.target as LoaderInfo;
loaderInfo.removeEventListener( Event.COMPLETE, onLoadedApp);
trace(loaderInfo.loader.content);
var swfApplication:SpriteUIComponent = new SpriteUIComponent(evt.target.loader.content );
if( SWFContainer.width < swfApplication.explicitWidth ){
var coef:Number = SWFContainer.width/swfApplication.explicitWidth;
swfApplication.scaleX = coef;
swfApplication.scaleY = swfApplication.scaleX;
}
SWFContainer.addElement(swfApplication);
}
I also tried to do it through SWFLoader, but the external.swf's content doesn't change its original size although I add the "scaleContent" parameter.
Visual results I got:
The external SWF is loaded on the suitable position and it "seems" to have 320x240 dim. But its width is a bit cropped, since if I stretch the Flash Player I achieve to see the rest of the external swf's stage. Besides, the external SWF never is resized although I shrink/stretch the Flash Player. It always remains fixed (if I trace its dimensions, I always get 800x600, although I visually see 320x240)- If I increase the stage's width of the main application, this little clip dissapear.
Discussion:
I know the original Stage's dimensions are 800, and this is greater than the original stage of my application (768), but I think, when I do the resizing, external SWF's Stage have to be fitted in the container. It is fitted, but a part of the external SWF is not seen. It's like Flash Player remembered that the external SWF Stage's width were greater than my application's one...
Thanks in advance.
Even with scaleContent set to "true" you still need to set an exact height and width to the SWFLoader control for it to even try resizing the internal SWF. All scaleContent does is instead of showing the SWF at regular or stretched sizes, it also up-scales the SWF if needed, and if not just scales it to retain the ratio of the original SWF.
I don't think the issue is with your ScaleMode. There can only be one Stage per flash player. The "stage" property of your 'external' SWF references the Stage of your 'application' SWF after it's added to the display list. If the SWF is loaded and not added to the display list, the loaded SWF's 'stage' property will equal 'null'. Setting the stage scaleMode inside your external SWF won't dictate how it scales once loaded into another SWF.
Also, you're probably resizing the SWFContainer, not the SWF itself...thats why the SWF width and height properties are always 800x600. I'm not sure if this is what you're asking for, but from what I'm understanding, you may need to create a stage resize event listener.
Have you tried to use a scale effect on "External SWF"?
Scale Effect

meta tag in AS project can't handle percentage width/height values?

I have an ActionScript project set up using the Flash Builder IDE. Using the Flex 4 compiler to compile it. At the top of my application class, I have:
[SWF(width="100%", height="100%")]
public class MediaPlayer extends MovieClip {
This is not acceptable to the compiler to do a release (it throws errors saying it can't parse the width/height values). Pretty annoying. I've tried to do things the "right" way, but none of the following work:
[SWF(percentWidth="100%", percentHeight="100%")]
[SWF(percentWidth="100", percentWidth="100")]
[SWF(widthPercent="100%", heightPercent="100%")]
[SWF(widthPercent="100", heightPercent="100")]
When I use any of those, the stageHeight is 375 (the Flex default) and stageWidth is 500 (default). What is the proper way to do this?
My flash files are being embedded on the web, and I just need the width and height attributes defining the bounds of the flash content to be respected by the SWF.
UPDATE
To give a little more context, I don't have control over how this SWF is embedded - it is handled by Facebook code for their in-stream media content.
<div id="u162171_43" style="width:398px;height:259px">
<iframe width="398" height="259" frameborder="0" src="https://s-static.ak.facebook.com/common/referer_frame.php">
<body style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">
<embed type="application/x-shockwave-flash" src="http://www.rootmusicd.com/flash/fb/rm_player.swf?v=140&d=www.rootmusicd.com&id=102199429820702" width="398" height="259" style="" id="swf_u187610_44" name="swf_u187610_44" bgcolor="#FFFFFF" quality="high" scale="scale" allowfullscreen="true" allowscriptaccess="never" salign="tl" wmode="opaque" flashvars="bridge_connection_id=_conn_4d9b46f8c10ea6089493440&payer_connection_id=_payer_4d9b46f8c10f64d23500210&width=398&height=259">
</body>
</iframe>
</div>
So the width and height attributes are being explicitly set to numbers here. I don't know much about the 'scale' attribute; maybe it is coming in to play here? And, to be clear: it will work as expected if I set the [SWF] meta tag to have width "100%" and height "100%"... so it seems like it actually is preferring the compiled arguments over the browser environment. Perhaps there are other settings I am missing?
Short answer: set the size you want in the web page where you embed the SWF, rather than in the AS source.
Full answer: As metadata, the width and height that get compiled into a SWF are essentially suggestions. When the SWF is displayed, its size is wholly decided by its container, so the only time the metadata gets honored is if the container chooses to read and honor it. Generally, they only container that does that is the standalone player - thus if you double-click the SWF it should launch at the size you specified in the source. But when you display the SWF embedded in a web page, the width/height metadata gets ignored entirely, and the SWF's size is determined similarly to all the other elements in your page (by the embedding HTML, CSS, and so on).
That's all slightly beside the question of why the metadata doesn't take percentages, but hopefully it makes more sense in this context... and since the metadata doesn't affect what happens in a browser, it's a bit academic. I can't answer for how percentWidth etc. fit into things, as it doesn't seem to be documented, but I assume that setting those values doesn't affect the SWF's size in a browser either (unless of course FlashBuilder is generating HTML based on the metadata, or something fancy like that - I'm not too up on FB).
Update
I think I see your problem here. We need to back up a bit and talk about scaling. Any time the size of a SWF differs from the size of its viewport (i.e. the size allotted to Flash by its container), Flash makes a decision about how to scale the content, depending on the stageScaleMode. The details of the four scale options are described in that link, but basically the content is left unscaled, or it's scaled up or down in such a way as to preserve, or not preserve, aspect ratio.
However, in order for Flash to know whether/how to scale the content, the content must have an "intrinsic" size. The height/width metadata we've been talking about is used as that size. So if your HTML container is 200x400 and you use the "exact fit" scalemode, then if your metadata describes a size of 100x200 your content will display at double size, and if your metadata said 400x800, the SWF will show up at half size. If you use the "no scale" scalemode, then your metadata will not affect the content's scaling. (Content still gets aligned within the container according to stageAlign.)
Taking the previous into account, I hope it will be clear that the "correct" value to use for your size metadata depends on what kind of scaling you use and how your content will adapt (or not adapt) to different sized containers. If your content is laid out statically within a 259x398 area, then 259x398 is the proper metadata size to use. That way, if you were to view it in a larger container, your content would be scaled up as one would expect, depending on scale mode. However, if your content dynamically adjusts to variably-sized containers, and automatically lays out its content at runtime, then you almost certainly need to use "no scale" mode - in which case it doesn't matter very much what size metadata you use, so the flex default size should work fine.
Incidentally, scale mode can be defined in the HTML embed parameters, but you can also override that setting at runtime. So work out what scale mode meets your needs, and set that mode before your content initializes, and then you should be able to find a metadata size that works.
Set your SWF tag to the proper aspect ratio in pixels and then use 100% as your width and height in the embed code on your page
swfobject.embedSWF('foo.swf', 'bar', '100%', '100%', '9');

Resizing container on resize of application window in Adobe Flex/AIR Application

I am working on an Adobe AIR Application. The size on Application window is 800X600 and is contains border container and border container contains many controls.
What I want is to if user re-sizes the application then that container should also be re-sized according to scale. i.e If user maximizes or minimizes the window then that border container should also be maximized or minimized respectively.
If you don't want to (or can't for some reason) use percentage based widths then you can always just do the following in MXML:
<s:BorderContainer
xmlns:mx = "http://www.adobe.com/2006/mxml"
xmlns:s = "library://ns.adobe.com/flex/spark"
width = "{parentApplication.width / 2}"
height = "{parentApplication.height / 2}">
You are just getting a reference to the component's parentApplication and directly binding to its width and height. Throw whatever math you want on the end.
An easier way to do this is to have your components declare their sizes/positions relative to their outer containers. For example, rather than setting x, y, width and height, set left, right, top and bottom in your Application component as well as the containers within your Application. If you want to enforce a minimum size of 800x600, you can set the minWidth and minHeight properties. Hope that helps.
This can be accomplished using an MVC framework. Some options include RobotLegs, Mate, Cairngorm or it is possible to use some quick design patterns and implement a custom version.
Essentially, the Application event Event.RESIZE should be detected and applied to the container. The properties of stageHeight and stageWidth will give the necessary info to resize the container.
Resize events will traverse the display hierarchy in any case, but it's convenient to intercept at the application level, should a custom event or function apply to the controls.

How to find original Flash Dimensions?

I have a flash file I want to programatically find the dimensions of in my code. Right at the beginning of the code I have the string:
[SWF(width='700', height='500')]
And several subclasses later I want to pull these "700" and "500" values up as variables.
Is there a way to find this?
I've tried referencing this.width and this.height but they always end up zero for the parent canvas.
Referencing the Stage does not work as it returns the current stage size, not the desired size. For example, if I load the SWF directly and not through a browser, I can scale the viewport to be as big or small as I like.
stage.stageWidth and stage.stageHeight will refer to the full width and height of the stage. It will change at runtime if the instance of Flash Player changes size. There's also loaderInfo.width and loaderInfo.height, which should tell you the original values specified in the [SWF] metadata, and they won't change at runtime.

Why are width & height of loaded SWFLoader zero?

I have a class which extends SWFLoader, I use it like a normal SWFLoader:
var loader:MySWFLoader = new MySWFLoader();
loader.load("myFile.SWF");
myScene.addChild(loader);
The loading works OK, except that it remains 0 because the width & height never change from 0. I had to override the width/height get properties to make it work:
class MySWFLoader extends SWFLoader
{
public override function get width():Number{ return contentWidth; }
public override function get height():Number{ return contentHeight; }
}
As well as being a big hack this isn't quite correct; especially since the SWF has multiple frames and the frames are of different width/height.
Why aren't width/height working in the first place? Shouldn't they be automatically set during loading? Is it possible the issue lies with the SWF itself somehow?
Update: Changing scaleContent to true or false makes no difference.
I'm not sure if this applies for SWF loading, but whenever I'm loading content, i cannot access width and height before the whole thing is loaded.
So make an event listener that listens when the loading is completed, and then read the height/width.
Also take a look at the loaderInfo class in AS3
I'm not sure what part of the cycle you're trying to grab the height and width (and is it of the loader object or the loaded content) but you can can access the height and width of the loaded object using SWFLoader.loaderInfo.height and SWFLoader.loaderInfo.width.
By default the SWFLoader scales the content to the size of the loader, so you have to set the size of the loader. If you want the loader to scale to the size of the content then you have to set the scaleContent property to false.
SWFLoader is a UIComponent.
It needs to be run through the UIComponent framework to set its dimensions correctly
In other words, it is waiting for calls to commitProperties(), updateDisplayList(), etc.
If you drop it in your application (so that it is part of the layout framework) it should be fine.

Resources