• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Flash Drawing API error?

Community Beginner ,
Mar 03, 2010 Mar 03, 2010

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?):
Flash_Graphic_Error.jpg

Why Flash doesn't draw the inner box (red) in the middle of the outer box?

TOPICS
ActionScript

Views

1.6K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 03, 2010 Mar 03, 2010

Copy link to clipboard

Copied

the "error" is caused by trying to position an object on a fractional pixel.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Mar 03, 2010 Mar 03, 2010

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?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Mar 03, 2010 Mar 03, 2010

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?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 03, 2010 Mar 03, 2010

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Mar 03, 2010 Mar 03, 2010

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?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 03, 2010 Mar 03, 2010

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();

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Mar 04, 2010 Mar 04, 2010

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!.

FlashLines.JPG

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 04, 2010 Mar 04, 2010

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Mar 04, 2010 Mar 04, 2010

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)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jun 07, 2010 Jun 07, 2010

Copy link to clipboard

Copied

LATEST

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines