Copy link to clipboard
Copied
Hi!
I think Flash drawing API is not working like it should...
Test this:
var W:Number = 12;
var H:Number = 12;
function drawRectExt():void
{
this.graphics.clear();
this.graphics.lineStyle(1,0xFF0000);
this.graphics.beginFill(0xFFFFFF, 1);
this.graphics.drawRect(0,0,W,H);
this.graphics.endFill();
}
function drawRectInt():void
{
this.graphics.lineStyle();
this.graphics.beginFill(0xFF0000, 1);
this.graphics.drawRect(W*0.2,H*0.2,W-W*0.4,H-H*0.4);
this.graphics.endFill();
}
drawRectExt();
drawRectInt();
This is the result (and the error?):
Why Flash doesn't draw the inner box (red) in the middle of the outer box?
Copy link to clipboard
Copied
the "error" is caused by trying to position an object on a fractional pixel.
Copy link to clipboard
Copied
Thanks kqlad!
I changed the line:
this.graphics.drawRect(W*0.2,H*0.2,W-W*0.4,H-H*0.4);
by this:
this.graphics.drawRect(2,2,8,8);
Now I don't have fractional pixels, but the "error" remains...
Any ideas?
Copy link to clipboard
Copied
I think I found the problem:
if we use:
this.graphics.drawRect(3,3,7,7);
it works!, but it's illogical (remember, the outer square is 12 px), and now if we zoom it... then we can see the red box is not in the middle ! (but without zoom it looks like if it was...)
I've tried then drawing the outer box with 2 rectangles (without lines...)
function drawRectExt():void
{
this.graphics.clear();
//this.graphics.lineStyle(1,0xFF0000);
this.graphics.beginFill(0xFF0000, 1);
this.graphics.drawRect(-1,-1,W+2,H+2);
this.graphics.endFill();
this.graphics.beginFill(0xFFFFFF, 1);
this.graphics.drawRect(0,0,W,H);
this.graphics.endFill();
}
and put again inside drawRectInt:
this.graphics.drawRect(2,2,8,8);
and that's works great! with and without zoom...
So, the problem was the line... I think I know why, the line it's 1px width, but it has the registration point in the middle, therefore if we draw a line in this way:
this.graphics.lineStyle(1,0xFF0000);
this.graphics.drawRect(0,0,W,H);
the line (1px width) is drawn from -0.5 to 0.5.
We can correct it in this way too:
function drawRectExt2():void {
this.graphics.clear();
this.graphics.lineStyle(1,0xFF0000);
this.graphics.beginFill(0xFFFFFF, 1);
this.graphics.drawRect(-0.5,-0.5,W+0.5,H+0.5);
this.graphics.endFill();
}
But I think that's a bad solution (and only works without zoom )
so... our lesson is... never use lines to draw a stroke? what do you think?
Copy link to clipboard
Copied
you just need to understand the drawing api.
when you use a 1 pixel line to draw a 12 pixel square, the left side of the square will be at pixel n and the right side will be 12 pixels to the right at pixel n+12. your square's interior (ie, the fill) will be 11x11 pixels.
you can therefore exactly center a 9x9, a 7x7, a 5x5, a 3x3 and a 1x1 square inside. no other interior square will look perfectly centered.
Copy link to clipboard
Copied
Please kglad, can you show me how to do it? I'm really confussed right now
These are my functions:
function drawRectExt2():void
{
this.graphics.clear();
this.graphics.lineStyle(1,0xFF0000);
this.graphics.beginFill(0xFFFFFF, 1);
this.graphics.drawRect(0,0,12,12);
this.graphics.endFill();
}
function drawRectInt2():void
{
this.graphics.lineStyle();
this.graphics.beginFill(0xFF0000, 1);
this.graphics.drawRect(3,3,7,7);
this.graphics.endFill();
}
it looks good at 100% but if you zoom it you will see that it's not centered.
This works:
function drawRectExt2():void
{
this.graphics.clear();
this.graphics.lineStyle(1,0xFF0000);
this.graphics.beginFill(0xFFFFFF, 1);
this.graphics.drawRect(-0.5,-0.5,12,12);
this.graphics.endFill();
}
function drawRectInt2():void
{
this.graphics.lineStyle();
this.graphics.beginFill(0xFF0000, 1);
this.graphics.drawRect(2,2,7,7);
this.graphics.endFill();
}
Is that the right way to do it?
Copy link to clipboard
Copied
use:
var W:Number = 12;
var H:Number = 12;
var intSqSide:Number = 9; // or 7,5,3,1 - you can use other numbers like 8 or 6.342 etc but you'll see antialiasing. the antialiasing will be symmetric but still detract from the effect when small sizes are used.
function drawRectExt():void {
this.graphics.clear();
this.graphics.lineStyle(1,0xFF0000);
this.graphics.beginFill(0xFFFFFF, 1);
this.graphics.drawRect(0,0,W,H);
this.graphics.endFill();
}
function drawRectInt():void {
delete this.graphics.lineStyle();
this.graphics.beginFill(0xFF0000, 1);
this.graphics.drawRect(1+(W-1-intSqSide)/2,1+(H-1-intSqSide)/2,intSqSide,intSqSide);
this.graphics.endFill();
}
drawRectExt();
drawRectInt();
Copy link to clipboard
Copied
Hi again kglad!
first I want to thank you for your help with this..
now, I have tested your code with "intSqSide = 7;"
and it looks good at 100%, but if you zoom it you will see that it's not centered.
In numbers, with intSqSide = 7, the code looks like this:
function drawRectExt():void {
this.graphics.clear();
this.graphics.lineStyle(1,0xFF0000);
this.graphics.beginFill(0xFFFFFF, 1);
this.graphics.drawRect(0,0,12,12);
this.graphics.endFill();
}
function drawRectInt():void {
delete this.graphics.lineStyle();
this.graphics.beginFill(0xFF0000, 1);
this.graphics.drawRect(3,3,7,7);
this.graphics.endFill();
}
My last version was:
function drawRectExt2():void
{
this.graphics.clear();
this.graphics.lineStyle(1,0xFF0000);
this.graphics.beginFill(0xFFFFFF, 1);
this.graphics.drawRect(-0.5,-0.5,12,12);
this.graphics.endFill();
}
function drawRectInt2():void
{
this.graphics.lineStyle();
this.graphics.beginFill(0xFF0000, 1);
this.graphics.drawRect(2,2,7,7);
this.graphics.endFill();
}
I think it's logic to offset in X and Y direction the width/2 of the line. Because Flash draws the line centered, there should be an option to change that, like in Illustrator, where you can draw the stroke centered, aligned to inside or aligned to outside.
I don't know why Flash does not support this feature!
It's really frustrating to draw lines in this way. If I draw a box with 12px side and 1px contour, I want that box with those values! not 11px inside, and not with an offset of half pixel in each side!.
Copy link to clipboard
Copied
that's a problem with zoom you're using (either in the test environment or browser). but if you zoom using a screen utility, it stays centered.
Copy link to clipboard
Copied
So you are saying there's an error in the Zoom of Flash Player?
I'm not so sure... because if you use:
this.graphics.drawRect(-0.5,-0.5,12,12);
and then:
this.graphics.drawRect(2,2,7,7);
it works even with zoom.
and if you use:
this.graphics.drawRect(0,0,12,12);
this.graphics.drawRect(3,3,7,7);
Then we are assuming that Flash starts the line at 0, and finish it at 1px, we put our inner box at 3px (2px from the end of the line) then move 7px, we are at 10px, and if the content is 11px we only have 1px to the line on the right.
I think Flash doesn't draw lines in that way. Flash starts the line in -WIDTH_LINE*0.5 and ends it at +WIDTH_LNE*0.5
That may be usefull in some situations, but it will more useful if we could control that, like in Illustrator, where you can define where to align the stroke.
(the image in myy previous post was created in Illustrator to show the differents line alignment)
Copy link to clipboard
Copied
Flash uses "twips" internally. Where 1 twip = 1/20 pixel.
Maybe you could try this by using a multitude of 20 and see what happens.
Just a hunch, don't know if this is related to the problem.