Here's the situation - I've got a shell that loads an external .swf. Now, that .swf is 800x600, but it's an animation piece, and there are elements that extends off the stage. When I load the .swf into the shell and call its width attribute, it returns 1200 - because it's including the elements that break out of the stage.
This isn't what I want - ideally, there would be two properties, one to return the 'calculated width' and one to return the 'default width'. Do these properties exist, and if not, what's the best workaround?
The width and height of the loaded SWF as defined by the FLA it was created with can be found in the Loader object in which you've loaded the SWF into.
swfLoader.contentLoaderInfo.width
swfLoader.contentLoaderInfo.height
This will always show you the dimensions as defined in the FLA properties. It makes no difference if any images, MovieClips, or what have you extend off the stage.
The stage.stageWidth and stage.stageHeight properties will always return the width of the stage, the stage is always the top most SWF. In other words, it will always represent the dimensions of the shell's stage. There is only ever one stage in a Flash application.
Mark is very likely right that the content loader info object will contain the correct width and height. I've never checked myself so I can't guarantee it. The docs say 'nominal' and contrast it with 'actual' so it seems reasonable.
There are a couple of other options. You can mask the external swf. Create a mask that is the size of the stage and put all content underneath it. Another idea is to create a movieclip based on a rectangular shape set it's alpha to 0 place it at x:0, y:0 and match it's width and height to stage. Give it an instance name and then when it is loaded use that value for the size.
Related
I have a flash object that is comprised of three layers...
the top layer 'Layer1' is a layer where a bunch of stuff happens for the program to run (drawing shapes, movie clips, etc) using as3... the next two layers just sit underneath and serve as a background image to the main program that is happening on 'Layer 1'. I want to programmatically add shapes and sprites and things to the 'masklayer' so that I can update the mask layer programmatically as well...however I can't seem to figure out how to do this...anytime i try to access the object it defaults to the top layer...anybody know?
The layers on your timeline only exist in the editor. There are no "layers" in a compiled swf.
To manipulate the ordering of a display object at runtime, you can use addChildAt(). This works even if the display object is already a child of that container.
However, it's generally better to avoid that by creating parent display objects at design time. For example, you could create movie clips called maskContainer and imgContainer and whatever you want to have on the bottom you could add using imgContainer.addChild().
I have an object manipulation function that(right now) manipulates the scale of the objects inside of an array to give real-time size changes in relation with each other.
What I would like to know is if there's a way to change an object's width/height(to fit the screen size since it's a mobile app) and then reset the scale so that the new width/height has a scaleX/scaleY value of 1.
The width/height are properties that directly influence the scale of a DisplayObject. You cannot resize it without affecting the scale.
You can however:
Draw the image as bitmap
Redraw it if it's a primitive
Put it in a holder
A little about every solution:
Drawing a DisplayObject (or any IBitmapDrawable) is done through creating a BitmapData and using a draw() call. The up-side is that it will be a bitmap and thus save some rendering time. The downside is that if it's a large image it will take memory (can be critical for mobile) and it won't have interactivity/animation unless you make a script that would read the animation.
If you're drawing the element though the Graphics class's API, you might just make something like a resize() method that you would call on window resize/flip-orientation. Just utilise the clear() method of the Graphics object and redraw the whole thing.
Lastly, probably your best pick. Resize your object. Make a new Sprite (I choose Sprite because it's interactive and you probably want that) and add the resized object to that newly made sprite while the Sprite is just added to the display list like you added the resized object before. If it's hard to understand, here's some code:
myResizeableObject.width = newWidth;
myResizeableObject.scaleY = newScaleY;
var holderSprite:Sprite = new Sprite();
myResizeableObject.parent.addChild(holderSprite); // if you don't have a specific place to add the myResizeableObject, don't use myResizeableObject.parent - it's ugly
holderSprite.addChild(myResizeableObject);
Hope that helps you!
I'm currently doing the following when applying a mask to a MovieClip:
mc1.cacheAsBitmap = true;
_mask.cacheAsBitmap = true;
mc1.mask = _mask;
Which works great, however...
mc1 is a complex vector animation, and cacheing it as a bitmap in order to mask it has pretty big memory implications from what I can see, and have read.
Is their another way to implement masks? Or a way to optimise the usual solution?
Thanks
edit
Both the mask and mc1 are MovieClips, and they have been added to the stage, the mask is a gradient.
I am using Flash CS6, both movieclip and mask are added to the timeline, where they are being animated
You can use http://www.greensock.com/blitmask/
Quote from the documentation:
Can’t I just set the target DisplayObject’s cacheAsBitmap property to true and get the same result? Why use BlitMask?
If you set a DisplayObject’s cacheAsBitmap property to true, Flash takes a bitmap capture of that object so that when you move it (only
altering the x and/or y properties), the text and vectors don’t need
to be re-rasterized again before being rendered to the screen.
However, Flash would still need to concern itself with extra pixels on
every frame if you’re masking them to only show a small portion of the
area. BlitMask, however, only cares about that smaller masked area
(after the initial capture of course) which alleviates Flash from
having to even think about the extra pixels.
The issue I'm having is that I have a main "wrapper" 100x100 (but it could be any size) - it's just there to hold and display whatever content, swf, gif, etc we may want to throw into it. As long as the loaded content doesn't have 3D animation like rotationY going on, it displays fine. But when it does, the 3D "anchor" properties (like projectionCenter) of the loaded swf inherit those of the main timeline (i.e. 100x100 (main) vs 728x90 (loaded)). If I change the dimension of the main "wrapper" in Flash IDE to match what's coming in - the 3D behaves fine, but I won't know what the dimensions of the content will be until it comes, so I need a way (if there is one) to dynamically alter the main "wrapper" or root display object through AS. Stuff like "this.width = loader.width" or "stage.width = loader.width" or "root.width = loader.width" etc doesn't work. Flex has the hBox and vBox - does AS have anything?
Use ExternalInterface to call a javascript function in the wrapper html, this will change the dimensions of the height/width of the enclosing div that wraps your .swf embd (Embed at width="100%" and height="100%") alternatively use swfobject to get a handle on the embedded object and change the height/width properties to match.
Then you can attach a Event.RESIZE listener and reposition your elements when the swf has been resized to fit the contents.
This is an example (Though just the height of the swf is changing) http://www.markgriffo.com/scrollTest/
I'm having an issue with Movieclips inside my Swf resizing to the wrong dimensions. I'm currently tracing the width of the offending clip every half second, and I can see the value change to an incorrect size at some interval in the logged output. I really want to see what code is changing the width. My plan was to extend Movieclip, override the set width property, and dump a stack trace when the value set is too low. This isn't so simple however. Flash is complaining about undefined reference to UI components that are on the Movieclip fla.
Is there a simple way to find out when/why this value changes? I cannot use a debugger.
edit:
The reason I cannot just extend MovieClip is because I am getting my Movieclip object from Event.currentTarget.content after using a Loader. I cannot point my Test (extends MovieClip) object at this return value because it is illegal to do so.
I'll explain the problem a little more and maybe someone will have another idea. I have an app with lots of different windows. They all open to a size of around 750x570. One of these windows contains a FusionChart. when I load this, according to my trace, the background Swf I am using changes to a dimension of about 2712x1930. This doesn't make sense to me because it looks the same size as before and at those dimensions it wouldn't even come close to fitting on my screen. If I then close the window and open another, the new window is tiny, but says it has the same dimensions as the original windows (750x570).
It is almost as if the window is scaling to the huge 2712x1930 without showing a change in size, and then showing the next window (750x570) as a size relative to what the huge window would look like. If that makes sense...
Maybe using a Proxy?
The Proxy class lets you override the default behavior of ActionScript operations (such as retrieving and modifying properties) on an object.
If you can see the trace you are doing and use a debug version of the flash player, try to override the property you want to check and trace the calling stack stack within the Error object:
public class Test extends Sprite() {
// property to watch
override public function set x(value:Number):void{
super.x=value;
// trace the calling stack work only in the flash debug player
trace((new Error()).getStackTrace());
}
}
what do you mean by "Flash is complaining about undefined reference to UI components that are on the Movieclip fla."?
your idea is absolutely the right solution in general... assuming the property doesn't change from within the runtime (which is rare, unless those properties are calculated) ...
when it comes to width and height, they are the two worst properties in the flash player API ... for reading, they are calculated by the space needed by a DisplayObject in parent coordinate space (if you rotate a DisplayObject, than these properties change). for writing, they actually forward to scaleX and scaleY ...