Why are width & height of loaded SWFLoader zero? - apache-flex

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.

Related

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

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

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

How can I force Flex to load a particular element first?

I have a read-only accessor whose value depends on the width of an image. The width of this image determines all sorts of positional values defined in flex. It turns out that, when I load, the accessor returns 0 for a while, and then, about when the thing starts to accept input, it returns its proper value.
Is there any way that I can force Flex to load the image first, thereby specifying its width?
why don't u load the image using Loader class, and loader class has load complete event, and then on load complete of image, do whtever u want,
var loader:Loader = nee Loader();
loader.load(new URLRequest('tree.png');
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,productLoadingComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,productLoadingError);
private function productLoadingComplete(event:Event):void
{
}

Flex: How to get the image size of an Image?

Give an Image component, how can I tell the size [width and height] of the bitmap image that the Image is containing (not the size of the Image component)
Also I want to know this as soon as possible, so I think this needs to be in the Event.COMPLETE event?
Thanks!!
Since Image extends SWFLoader, properties contentWidth and contentHeight are both publicly available. They are available on the "complete" event.
Accessing the Image's bitmap data might not be allowed if the Image is loaded from another domain.
The BitmapData class will give you the width and height properties.
This should be available in the
protected measure()
method, which you can override if you need to do things to it.

How can I create a Flex application with dynamic height?

Is there a way to allow a flex application to have a dynamic height while embedded in an HTML wrapper?
I want the Flex application to grow in height in a way that it will not cause vertical scroll bars.
The best way should be overriding the Application's measure method like:
private var _lastMeasuredHeight:int;
override protected function measure():void
{
super.measure();
if (measuredHeight != _lastMeasuredHeight)
{
_lastMeasuredHeight = measuredHeight;
if (ExternalInterface.available)
{
ExternalInterface.call("setFlashHeight", measuredHeight);
}
}
}
This function assumes that you have a javascript function named setFlashHeight which can accept a height (or whatever you name it) parameter. An example would be:
function setFlashHeight(newHeight){
//assuming flashDiv is the name of the div contains flex app.
var flashContentHolderDiv = document.getElementById('flashDiv');
flashContentHolderDiv.style.height = newHeight;
}
I use swfobject to embed my flex applications. So the flash object resides inside a div. If yours not; the js function could easily be altered to set the flash object's height. When you implement this solution, you'll notice that scrollBars aren't working as flash consumes the event. But that's another subject...
This is possible. For an example, see the new Kontain by fi. You can see it directly in action by creating a new blog post and adding lines to the entry field. As the entry field grows in size, the page gets taller.
You'll have to coordinate between Flash and Javascript via ExternalInterface. When your Flex app needs to change size, find the new size (probably by digging into Flex's layout engine) and throw that up to a Javascript function via ExternalInterface. The javascript then can set a new height property on the container. You'll probably also want to set verticalScrollPolicy="off" on your tag so that Flex doesn't show the scroll bars when the layout engine runs.
I'm not sure I fully understand the question, are you trying to get the aplication to have a size larger than the browser's view port? If so, then as #hasseg commented and #RickDT mentioned, you can set the Application's horizontalScrollPolicy and/or verticalScrollPolicy properties to "off"?
If you're simply trying to make sure your application scales with changes to the browser's shape and size, then make sure you set the following (or values that suit) in your outer most application tag.
percentWidth="100"
percentHeight="100"
Unfortunately no, I think the only way you could do this is to get rid of the html wrapper in the first place. HTH.
There is no need for all that, just change the application from spark to mx. this will show it automaticly because I think spark does not support that at all ( I think it's stupid bug from adobe )
like this:
<mx:Application xmlns:fx="http://ns.adobe.com/mxml/2009" >
</mx:Application>
instead of:
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" >
</s:Application>
leave application tag without height specification "don't use height="100%"

Resources