0
votes

I am forced to consider writing a library to handle the fundamental basics of drawing lines, thick lines, circles, squares etc. of an HTML5 canvas because I can't disable a feature embedded in the browser rendering of the core canvas algorithms.

Am I forced to build the HTML5 Canvas rendering process from the ground up? If I am, who's in with me to do this? Who wants to change the world?

Imagine a simple drawing application written in HTML5... you draw a shape... a closed shape like a rudimentary circle, free hand, more like an onion than a circle (well, that's what mine would look like!)... then imagine selecting a paint bucket icon and clicking inside that shape you drew and expecting it to be filled with a color of your choice.

Imagine your surprise as you selected "Paint Bucket" and clicked in the middle of your shape and it filled your shape with color... BUT, not quite... HANG ON... this isn't right!!! On the inside of the edge of the shape you drew is a blur between the background color and your fill color and the edge color... the fill seems to be flawed.

You wanted a straight forward "Paint Bucket" / "Fill"... you wanted to draw a shape and then fill it with a color... no fuss.... fill the whole damned inside of your shape with the color you choose.

Your web browser has decided that when you draw the lines to define your shape they will be anti-aliased. If you draw a black line for your shape... well, the browser will draw grey pixels along the edges, in places... to make it look like a "better" line.

Yeah, a "better" line that **s up the paint / flood fill process.

How much does is cost to pay off the browser developers to expose a property to disable their anti-aliasing rendering? Disabling would save milliseconds for their rendering engine, surely!

Bah, I really don't want to have to build my own canvas rendering engine using Bresenham line rendering algorithm... WHAT CAN BE DONE... HOW CAN THIS BE CHANGED!!!??? Do I need to start a petition aimed at the WC3???? Will you include your name if you are interested???

UPDATED

function DrawLine(objContext, FromX, FromY, ToX, ToY) {
    var dx = Math.abs(ToX - FromX);
    var dy = Math.abs(ToY - FromY);
    var sx = (FromX < ToX) ? 1 : -1;
    var sy = (FromY < ToY) ? 1 : -1;
    var err = dx - dy;
    var CurX, CurY;
    CurX = FromX;
    CurY = FromY;
    while (true) {
        objContext.fillRect(CurX, CurY, objContext.lineWidth, objContext.lineWidth);
        if ((CurX == ToX) && (CurY == ToY)) break;
        var e2 = 2 * err;
        if (e2 > -dy) { err -= dy; CurX += sx; }
        if (e2 < dx) { err += dx; CurY += sy; }
    }
}
1
Well, I got to the same conclusion and am currently working on RetroJS which do these basic operations (if someone wants to co-op/take over go to my blog in my user info and leave a message there with email). You can't turn off anti-aliasing for path objects, only for image scaling.user1693593
Hi Ken, okay, when I've made some progress with my project I'll see if I have anything to contribute. At this stage I've got a very basic line drawing process based on Bresenham's algorithm... it uses the "fillRect" method to draw either a single pixel, or a thicker line. It's not really ideal, doesn't look great with thicker lines, big chunky square ends! BUT, the main thing is that I'm not getting anti-aliasing, so flood fill / paint works as expected. ...will post code next comment...Tappa Tappa
function DrawLine(objContext, FromX,FromY,ToX,ToY) { var dx = Math.abs(ToX - FromX); var dy = Math.abs(ToY - FromY); var sx = (FromX < ToX) ? 1 : -1; var sy = (FromY < ToY) ? 1 : -1; var err = dx - dy; var CurX, CurY; CurX = FromX; CurY = FromY; while (true) { objContext.fillRect(CurX, CurY, objContext.lineWidth, objContext.lineWidth); if ((CurX == ToX) && (CurY == ToY)) break; var e2 = 2 * err; if (e2 > -dy) { err -= dy; CurX += sx; } if (e2 < dx) { err += dx; CurY += sy; } } }Tappa Tappa
Whoops, sorry... that looks crap... I'll post the code in my question!Tappa Tappa

1 Answers

1
votes

2016/04 - Updated links

You can, as an option, use 8-bit (replaces Retro-Context) for canvas (disclaimer: I'm the author).

If this is a viable alternative to writing the code yourselves you can get lines, circles etc. by doing this:

HTML

<canvas id=c width=960 height=600 data-width=320 data-height=200></canvas>

The data-* are optional and represents the "native" solution. You can also set it as options to getContext().

JavaScript

var canvas = document.getElementById('c'),
    ctx = canvas.getContext('8-bit');         // get retro context

Now you can draw lines, circles etc. without anti-aliasing, pixelated in a pretty old-school retro style using the exact same properties and methods as with regular 2D context.

There are also methods such as ellipse(), drawImage() (with palette reduction and dithering) and other things.

The library is intended for making retro looking games and programs in "low resolution". Don't expect full performance as with native ordinary canvas if that is a goal or if you wish to use full sized canvas as basis.

The project is available on GitHub at this link.

Hope this helps!