View Full Version : Masking an external swf?

06-13-2007, 09:57 PM
I'm trying to load in external swfs into a flex project via the Image or SWFLoader components, however the elements in the external swfs often travel outside of the boundaries of its stage, so when I load the external swf into flex, I see these elements flowing out of the layout and all over the place.

If I force horizontal/vertical scroll policies on the container that loads the swf, these elements are successfully masked within the boundaries, however I should be able to achieve this effect without having to use scrollbars.

Anyone else deal with this before? This seems like it should be a relatively common issue.

06-13-2007, 10:39 PM
Wow...ok...so I found a solution....and then also something that may be a bug...

The solution is to put the Image component inside a fixed width/height canvas with its clipContent property set to true.

In addition to this, i wanted to be able to scale the canvas to reflect the dimensions of the external swf, using the code below:

private function creationCompleteHandler(evt:FlexEvent):void{
swf.addEventListener("updateComplete", updateCompleteHandler);

private function updateCompleteHandler(evt:Event):void{
this.width = swf.contentWidth > 0 ? swf.contentWidth : 100;
this.height = swf.contentHeight > 0 ? swf.contentHeight : 100;

In this case, swf is the image component. Once the content is loaded, I read the contentWidth/contentHeight values and set the canvas width/height to match it.

This is where the bug comes in.

The width line works fine, but the height line seems to break the mask. Apparently this is because you can't have the canvas's height be exactly the same as the swf's contentHeight. If I add or subtract 1 to the swf.contentHeight value, it will work fine.

Anyone else confused by this?? :confused:

10-11-2007, 09:15 AM
Thanks for bringing this issue to the attention of the public, I am also confused by it.

Well, my current workaround is very similar to yours.

I had wrapped my SWFLoader's instance into container with property "clipContent" set to true.

Then inside event handler for Event.COMPLETE event I am updating the width and height of my container by reading 'swf.content.loaderInfo.width''s and 'swf.content.loaderInfo.height''s values.

My code follows:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical" backgroundColor="white"
horizontalAlign="center" width="100%" height="100%">
private function swfComplete() : void {
box.width = swf.content.loaderInfo.width > 0 ? swf.content.loaderInfo.width : 100;
box.height = swf.content.loaderInfo.height > 0 ? swf.content.loaderInfo.height : 100;
<mx:HBox id="box" borderColor="red" borderStyle="solid" clipContent="true" verticalScrollPolicy="off" horizontalScrollPolicy="off">
<mx:SWFLoader id="swf" source="balls.swf" complete="swfComplete()">

I am currently downloading Flex 3 Beta 2 SDK, if the problem will persist, I am inclined to log a bug at Adobe's public bug database.

10-11-2007, 12:28 PM
Assertnfailure, you say you are using an Image component to load your swf? I think an Image component keeps it' original aspect ratio by default unless you set the maintainAspectRatio property to false.

Best Regards,

10-11-2007, 02:18 PM
I do not think that playing with 'maintainAspectRatio' property will influence the behaviour of SWFLoader in this situation.

IMHO, setting 'maintainAspectRatio' to false is irrelevant to solve the problem with masking of externally loaded SWF content via mx:SWFLoader component.

10-11-2007, 06:49 PM
Thanks for the clarification, I just thought it might help since he is using an Image component and not a SWFLoader, and that this is the exact same "bug" that happens with the Image component when that property is not set to false. I though it was worth a try at least.

Best Regards,

10-12-2007, 11:50 AM
Alex Harui from Adobe had suggested to use masking directly on the instance of SWFLoader in such situation if this helps..

private function swfComplete() : void {
var s:Shape = new Shape();
s.graphics.drawRect(0, 0, swf.content.loaderInfo.width, swf.content.loaderInfo.height);
s.visible = false;
swf.mask = s;

Did not test this solution with using device fonts in loaded SWF should although...