Copy link to clipboard
Copied
I have a SWF file containing two symbols which have are "exported for ActionScript". These are both simple squares whose fill is equal in size, but one has a border and the other does not.
I would like to display these graphics side-by-side in my Flash application, and I would like them both to be scaled (enlarged) to the same dimensions. I've written some fairly simple code to load these symbols from the SWF and display them (see below), but the bordered element is not sized as expected:
The border causes the graphic to be reduced in size by more than the border enlarges it.
I used the following code to perform the above test.
<?xml version='1.0'?>
<s:Application
xmlns:fx='http://ns.adobe.com/mxml/2009'
xmlns:s='library://ns.adobe.com/flex/spark'
xmlns:mx="library://ns.adobe.com/flex/mx"
initialize='init(drawArea)'
>
<mx:UIComponent id='drawArea' left='0' top='0' width='250' height='250'></mx:UIComponent>
<fx:Script><![CDATA[
import mx.controls.SWFLoader;
static function init(drawArea:UIComponent):void {
var loader:SWFLoader = new SWFLoader();
loader.addEventListener(Event.COMPLETE, onSwfLoaded);
loader.load('./borderings.swf');
function onSwfLoaded(e:Event):void {
var getDefinition:Function = e.target.loaderContext.applicationDomain.getDefinition;
var Bordered:Class = getDefinition('bordered');
var bordered:MovieClip = new Bordered;
bordered.x = 100;
bordered.y = 100;
bordered.width = 100;
bordered.height = 100;
var borderedContents:DisplayObject = bordered.getChildAt(0);
assert(bordered.numChildren === 1);
assert(borderedContents.x == 0);
assert(borderedContents.y == 0);
assert(borderedContents.width == 14.1);
assert(borderedContents.height == 14.1);
drawArea.addChild(bordered);
var Borderless:Class = getDefinition('borderless');
var borderless:MovieClip = new Borderless;
borderless.x = 250;
borderless.y = 100;
borderless.width = 100;
borderless.height = 100;
var borderlessContents:DisplayObject = borderless.getChildAt(0);
assert(borderless.numChildren === 1);
assert(borderlessContents.x == 0);
assert(borderlessContents.y == 0);
assert(borderlessContents.width == 13.1);
assert(borderlessContents.height == 13.1);
drawArea.addChild(borderless);
drawArea.graphics.lineStyle(1.0, 0xFF0000, 1.0);
drawArea.graphics.moveTo(25, 50);
drawArea.graphics.lineTo(325, 50);
drawArea.graphics.moveTo(25, 150);
drawArea.graphics.lineTo(325, 150);
}
}
static function assert(pass:Boolean, msg:String=null):void {
if (!pass) throw new Error(msg || 'assertion failed');
}
]]></fx:Script>
</s:Application>
The complete IntelliJ test project may be found in this git repository on BitBucket.
The Flash editor claims that the symbols both have the same dimensions: 13.10px by 13.10px, although visually this appears to be excluding the outer half of the border:
However, when I inspect instances of these graphics using ActionScript it reports that the the bordered graphic is larger, at 14.10px by 14.10px.
Why is the sizing of these graphics affected by the border in this odd way? How can I cause the bordered and unbordered versions of this graphic to be scaled to the same dimensions?
Copy link to clipboard
Copied
i'm not familiar with the code you're using but in flash the border is not reported as part of the objects width/height.
so, if you have a 100x100 fill with border thickness 10 and convert it to a symbol, flash will report the object as 100x100.
the object will actually be 110 x 110 with 5 pixels of border extending outside of the 100x100 file. (5 pixels of border will be extending into the fill, too.)
now, if you resize the object, you'll need to know the object's stoke scaling property. i think you can use code for that with flex but not flash (afaik).
Copy link to clipboard
Copied
Thanks for the suggestion. Sadly, I've been looking around in the Flash debugger and the docs, but haven't found any way of determining the stroke size (or any other similar graphics attributes) for loaded graphics.
Copy link to clipboard
Copied
I've programmatically determined the size of the border by comparing the overall dimensions of the graphics with and without the border, and used that to increase the size of the bordered graphic to try to fix things, but the result is still too small as I increase the size of the border.
borderedContents.width += (borderedContents.width - borderlessContents.width) * 2;
borderedContents.height += (borderedContents.height - borderlessContents.height) * 2;
Copy link to clipboard
Copied
Don't use borders. Just use shapes. Even after you figure out the math, you're not going to like how borders look.
Put a larger black square behind your content square (or mask your border and put it on top) and you have a perfect black border.
Always use integers for any x and y, or it will be blurry.
Copy link to clipboard
Copied
A solution to this issue has been provided on Stack Overflow at http://stackoverflow.com/a/20630102/1114. User frankhermes (http://stackoverflow.com/users/224734/frankhermes) helped me figure this out.
For the scaling issue you might take a look at the getRect()
method of DisplayObject
.
From AS3 Reference for getRect()
:
Returns a rectangle that defines the boundary of the display object, based on the coordinate system defined by the
targetCoordinateSpace
parameter, excluding any strokes on shapes. The values that thegetRect()
method returns are the same or smaller than those returned by thegetBounds()
method.
For the example above, this can be used to directly figure out the scale factors required to set an element to specific dimensions while ignoring the strokes, instead of using setting the scale through thewidth
and height
properties. A function like this would work:
static function setDimensionsExcludingStrokes( subject:DisplayObject, width:int=-1, height:int=-1 ):void { var innerDimensions:Rectangle = subject.getRect(subject); if (width >= 0) { subject.scaleX = width / innerDimensions.width; } if (height >= 0) { subject.scaleY = height / innerDimensions.height; } }
Instead of setting bordered.width = 100
and bordered.height = 100
, we would call:
setDimensionsExcludingStrokes(bordered, 100, 100);
This results in the squares being nicely-aligned at the same target size:
Copy link to clipboard
Copied
their fills are the same size but half the stoke is outside the fill's borders.
but, if that works for you, great.
Find more inspiration, events, and resources on the new Adobe Community
Explore Now