ActionScript drawRoundRect rendering blurry corners - actionscript-3

I'm using the AS3 drawRoundRect function as in the following snippet:
g.lineStyle(1, 0x808080, 1, true);
g.drawRoundRect(0, 0, 100, 24, 12, 12);
As you can see, pixel hinting is on.
The problem I'm having is corners being anti-aliased way too much, they are way too blurry and not even symmetrical on the above snippet. Frankly, the drawRoundRect function draws the ugliest rounded rectangles that I've ever seen.
Is there a way to make AS3 draw more crisp rectangles?
Thanks!
:)

fills are rendered much better than lines. as you can see here:
const thickness:Number = 1;
g.beginFill(0x080808);
g.drawRoundRect(0, 0, 100, 24, 12);
g.drawRoundRect(thickness, thickness, 100 - 2 * thickness, 24 - 2 * thickness, 12 - thickness);
g.endFill();
g.lineStyle(thickness, 0x080808, 1, true);
g.drawRoundRect(0, 50, 100, 24, 12);
well, it is not SOOOOOOOOOOO unincredibly better ... :-S ... but at least its symetric ... and the smudges on the corners are more like little beads ... :-D
greetz
back2dos

I've had similar problems in the past. It usually came down to one of the movieclips along the display path not being on an even pixel. Flash then tries to render fractional pixels, which it can't do, which caused distortion and blurriness.
So, make sure all your movieclips/sprites are on an even pixel (I know you're drawing the rect on even pixels, but if the displayobject it belongs to, or any of its parents aren't on an even pixel, it would be causing the problem).

I've had the same deal, as well. One hacky trick you could try is to apply a minor blur filter to the parenting object.
It looks like you're using the drawRoundRect method of the Graphics class.
If the object you're working with is a UIComponent, you could try using the drawRoundRect method of UIComponent. It takes an Object for the cornerRadius value, rather than setting ellipse width and height values. I'm not 100% sure that the cornerRadius value isn't converted into ellipse width and height, but it seems like it'd be something to try.
Also, you could try the GraphicsUtil class's drawRoundRectComplex. It takes a Number for each corner's radius. Again, not completely sure that it doesn't eventually use the same underlying mechanics as drawRoundRect.

When you using drawRoundRect set X to be half of thickness, and then thickness will be on rounded pixel. In this your case try:
g.lineStyle(1, 0x808080, 1, true);
g.drawRoundRect(0.5, 0.5, 99, 23, 12, 12);

Related

Flash, AS3: Drawn objects are not the same

I'm playing with Open Flash Chart. Take a look at this chart:
http://teethgrinder.co.uk/open-flash-chart-2/line-solid-dot.php
As you can see, the rounded dot points look ugly. Some of them are more rounded, some of them less, they don't look the same, as they should. I don't know AS3 and have no idea what is the case. I checked the source code:
this.graphics.lineStyle( 0, 0, 0 );
this.graphics.beginFill( colour, 1 );
this.graphics.drawCircle( 0, 0, style.get('dot-size') );
this.graphics.endFill();
I tried to change the size or draw rectangles instead, but they still don't look the same. I guess the problem is somewhere else...
EDIT: I also noticed, that other elements also looks a little bit different (and they shouldn't) - for example axis ticks. My guess is that it is the quality problem. But when I right-click on the flash object, there is an option "quality" and the "high" is set (there is also a "medium" and a "low" to choose). Can I increase the quality level somewhere else?
From hollow dots, I came to realize there is something around each dot which separated each dot from the connecting lines & also produced blurry hollow dots.
Setting the attribute "halo_size" to 0 helped in this case.
I noticed the same gap in your sold dots examples as well. Maybe that's the problem.
To set stage quality, simply use:
stage.quality = "low";
stage.quality = "medium";
stage.quality = "high";
You may set it in the main class itself which happens to be the document class for this project.
I noticed that if the chart size is 400 x 400 these inconsistencies cease to exist. So the problem we see is a scaling problem & not at the place we think.
Besides, Setting line style allows a proper border around the circle. This will at least appear better.
this.graphics.lineStyle(1, colour, 1);
this.graphics.beginFill( colour, 1 );
this.graphics.drawCircle( 0, 0, style.get('dot-size') );
this.graphics.endFill();

HTML5 / Canvas "Glass" Circle

I need to render a simple chart and I want the points to be glassy looking circles/orbs in the chart area. I can find tons of examples of drawing these with Photoshop, but I don't want to use stock images; I'd prefer to draw them in my HTML5 canvas. I am no artist, though!
There are many HTML5 canvas questions, but I don't see anything that leads me to this solution.
A point in the right direction would be most appreciated.
All you have to do is create one or more radial gradients to fit the properties of the glassy object that you want. It's easy to do!
Just one gradient:
// Create some gradient
var gradient = ctx.createRadialGradient(105, 105, 20, 120, 120, 50);
gradient.addColorStop(0, 'rgba(250,250,255,0)');
gradient.addColorStop(0.75, 'rgba(230,250,255,1.0)');
gradient.addColorStop(1, 'rgba(0,0,255,0)');
// draw the gradient (note that we dont bother drawing a circle, this is more efficient and less work!)
// but make sure it covers the entire gradient
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 300, 300);​
Can make this:
Live example:
http://jsfiddle.net/GTbjk/
Maybe you want to reign in that fuzzy edge:
gradient.addColorStop(0.8, 'rgba(0,0,255,0)');
gradient.addColorStop(1, 'rgba(0,0,255,0)');
http://jsfiddle.net/GTbjk/1/
I'm not going to make one to your specification, since you didn't provide one and thats not what we're here for anyway. Making these will almost exclusively be the work of well-placed radial gradients, so go experiment!
As j08691 points out this is a really inefficent way of making these unless you want them to be dynamic or scalable, you are better off just making images and use ctx.drawImage

ActionScript drawRoundRect rendering inconsistent corner radii

I'm trying to draw a shape with quite precise rounded corners, I'd settle for anything around 3px. Unfortunately Flash has other ideas, and is creating a rounded rectangle with four seemingly different radii. My code is below:
var sq:Shape = new Shape();
sq.graphics.beginFill(0x000000,1);
sq.graphics.drawRoundRect(20,20,20,20,4,4);
sq.graphics.endFill();
addChild(drop);
I removed the line as apparently fills render better, and changed to an even number radius as apparently that helps, but it's still the same. The code above gives me a square like so:
The corners are noticeably different. If I were using a bigger radius it might not be so much of a problem, but because of the small radius of the corners the square just looks odd.
Have I missed the drawRoundRectEvenly function or am I asking too much here? Any help is appreciated! Thanks!
Darren
Try setting pixelHinting to true.
sq.graphics.lineStyle(1, 0x000000, 1.0, true);
Even if you're not using strokes, try it with an alpha 0 and see if it helps smooth things a bit. It will most likely still not be perfect, but it should snap to pixels a bit better and clean up dramatically.

AS3 Render Shape to Bitmap with Antialias

I have a drawn a Circle Shape in AS3. I want to render the Circle into a Bitmap with nice/antialiased Edges. Because I want it to work on Mobile Devices (Air Apps are limited to stagequality = low) I need a workaround. Any custom shape to bitmap renderer available?
Not sure this solution would work for Air Mobile Apps, but worth looking into.
Didier Brun # ByteArray.org posted an API used to draw primitive shapes (as BitmapData, not from Vector draw calls either), which might help you get your circles to draw the way you want.
http://www.bytearray.org/?p=67
Code Snippet (from that URL):
// create the BitmapData to work on
var pixels:Raster = new Raster(320, 240, true);
// draw stuff
pixels.drawRoundRect( new Rectangle ( 20, 20, 200, 100), 18, 0xFF00FFFF );
pixels.drawRect( new Rectangle ( 70, 70, 100, 100 ), 0xFF009900 );
pixels.filledTri( 40, 40, 80, 110, 50, 30, 0xFF998811 );
pixels.aaCircle(100, 100, 40, 0x77AA88 );
pixels.circle(40, 40, 30, 0xFF000000);
pixels.line(10, 10, 60, 80, 0xFF000000 );
// show it
addChild ( new Bitmap ( pixels ) );
Hopefully the library / source code is compatible for your project! :)
Have you consider using the drawWithQuality method?
The drawWithQuality() method works exactly like the draw() method, but instead of using the Stage.quality property to determine the quality of vector rendering, you specify the quality parameter to the drawWithQuality() method.
StageQuality.LOW is going to make your bitmap quality low if you're using draw() because the source will be of low quality whether it's on the DisplayList or not.
I don't think there's a way around this.. You'll have to load in circle graphics or import images to use.
If it is only something simple as circle, you can synthesize smooth image pixel by pixel. Create BitmapData of sufficient size and loop on pixels. On every pixel, compute distance from center - if it less than circle radius - half of pixel diagonal, set pixel to circle color. If it greater than circle radius + half of pixel diagonal, call setPixel32(x, y, 0).
Pixels that won't pass both conditions are near the edge - to do exact antialiasing, you must compute how much of pixel is covered by circle. Maybe you can find some convincing simple approximation. Good luck!
Update:
OK, I think I can remember simpler approach... You can draw your circle or any shapes two times bigger than they should be, then draw that bitmap into another with scale 0.5 (set through matrix) and smoothing on. That would be supersampling 4x. If stage quality doesn't affect bitmap smoothing, it should work.
In ActionScript 3 bitmap is created from BitmapData, so you need to create if first with
_bitmapData = new BitmapData(..
BitmapData has method draw, passing DisplayObject instance (Sprite, MovieClip or other) to it as parameter, will draw it's content into BitmapData.
Example:
var c:Sprite = new Sprite();
c.graphics.clear();
c.graphics.beginFill(0x00FF00, 0.5);
c.graphics.lineStyle(2.0);
c.graphics.drawRectangle(0, 0, 100, 100);
c.graphics.endFill();
var bd:BitmapData = new BitmapData(100, 100);
bd.draw(c);
var bitmap:Bitmap = new Bitmap(bd);

Custom Line stroke in HTML5 canvas

When drawing lines with the HTML5 canvas element, is it possible to define the stroke style of the lines? Basically in Photoshop and other similar programs, you can define a stroke style for lines that looks like it is "hand drawn". Is is possible to do anything like that in HTML5 canvas or am I shooting for the moon here?
Thanks
-Jesse
It is possible but not by default. See ShadowCloud's post for what you can do by default (very little).
Depending on what you want, it shouldn't be too hard.
If by "hand drawn" you mean you want jitter, you'd have to break up every drawn line/curve into smaller parts and add some noise to each of the points.
If you want a brush you'd have to break up every drawn line/curve into smaller parts and call drawImage every few pixels to emulate a photoshop brush.
Almost all of them rely on breaking up your lines and curves into smaller bits, so you should figure that out foremost.
If you decide to implement these and are having trouble breaking up bezier curves and want help, let me know and I'll give you my code for that.
There is no standard API in HTML5 Canvas to manage such thing.
You can just set the color or the width of the stroke, for example:
context.strokeStyle = '#f00'; // red color
context.lineWidth = 4; // 4px wide
// Draw some rectangles.
context.fillRect (0, 0, 100, 100);
context.strokeRect(0, 0, 100, 100);
You can try to get more control using a library (Processing.js or Fabric.js)