RSS | Comments RSS | Atom


CanvasPaint blog


Chronicling the development of CanvasPaint from a proof-of-concept tech demo into a useful, social online tool.

December 2006


drawings30 Dec 2006 05:33 am

In the absence of real updates (which can currently be blamed on this), let’s see some more drawings:

See you in 2007.

technology28 Dec 2006 02:59 pm

This is just simple mathematics/geometry, but I remember googling for this for hours back when I first implemented the ellipse tool. Courtesy of Gavin Doughtie and Jon Stewart’s excellent presentation No Flash Required: Interactive Browser Graphics, this is how to draw an ellipse with bezier curves where x1/x2–y1/y2 is its bounding box.

var KAPPA = 4 * ((Math.sqrt(2) -1) / 3);

var rx = (x2-x1)/2;
var ry = (y2-y1)/2;

var cx = x1+rx;
var cy = y1+ry;

trg.beginPath();
trg.moveTo(cx, cy - ry);
trg.bezierCurveTo(cx + (KAPPA * rx), cy - ry,  cx + rx, cy - (KAPPA * ry), cx + rx, cy);
trg.bezierCurveTo(cx + rx, cy + (KAPPA * ry), cx + (KAPPA * rx), cy + ry, cx, cy + ry);
trg.bezierCurveTo(cx - (KAPPA * rx), cy + ry, cx - rx, cy + (KAPPA * ry), cx - rx, cy);
trg.bezierCurveTo(cx - rx, cy - (KAPPA * ry), cx - (KAPPA * rx), cy - ry, cx, cy - ry);
drawings13 Dec 2006 10:22 pm

features12 Dec 2006 02:42 am

This is only available in Opera 9 for now, and it’s pretty damn slow. Performance on Firefox 3/Gran Paradiso was even worse by a couple of magnitudes, so I haven’t enabled it there yet — I guess I’ll be benchmarking some different flood fill algorithms later this week.

technology10 Dec 2006 05:46 am

 hand-drawn text on canvasOne of the features most glaringly missing from CanvasPaint is text support. Quite a lot of the images saved online contain scrawly, hand-drawn text. Proper font support would obviously greatly improve the efficiency of spamming some website’s url and/or the word “dick” 50 times in a row. Unfortunately, the canvas spec does not address writing text to a canvas apart from the following comment:

// drawing text is not supported in this version of the API
// (there is no way to predict what metrics the fonts will have,
// which makes fonts very hard to use for painting)

On the Mozilla wiki, there has been some inconclusive discussion about adding text rendering functionality, but it appears to have stalled.

So let’s explore some other options. The first thought is to somehow make use of the browser’s built-in perfect font handling capabilities (kerning/hinting, right-to-left, etc.), letting it render the font by itself and then somehow importing it into the canvas:

1. Overlaying HTML

One obvious technique that does this is simply layering divs with “real” text on top of a canvas. The nicest implementation of this principle is Oliver Steele’s TextCanvas library. This approach works well enough, but of course the text is not actually rendered to the canvas and thus can’t be transformed, drawn over (unless you layer another canvas on top) or saved when you call toDataURL(), so it’s not a suitable solution for CanvasPaint.

2. Rendering HTML with drawWindow()

Mozilla supports a proprietary drawWindow() method, which would enable one to render some HTML text from a (potentially hidden) iframe to the canvas. However, that method is only accessible from chrome – ie. for extensions, where it is used to great effect for creating/displaying screenshots of web pages (TabPreview, etc). There’s a bug advocating allowing websites to access it as well, but that too appears to be in hibernation.

So using the browser’s font rendering doesn’t seem to be working well enough. “No problem,” I hear you say, “then let’s reimplement it all from scratch!”. Alright, if you insist…

3. Bitmap fonts with drawImage()

Bitmap font on canvas

A bitmap font is simply an image containing all characters of a font, which is then selectively drawn to the canvas. → Try it out.
This works fairly well, but to make it look really nice, we’d need to create one such image per font size we’re intending to use.
Benjamin Joffe has written a helpful bitmap font generator to facilitate this task. For most canvas projects this is probably the way to go, even though it feels rather tedious and inflexible.

4. Vector fonts

Postscript Type3 font on canvas

That finally leaves us with parsing actual vector font files. The two most commonly used formats are TrueType and PostScript Type1 – both complex binary file formats, which we’ll hardly be able to parse in JavaScript.
Thankfully a little tool called TTF2PT1 allows us to convert a TrueType file into an ASCII Type1 (T1A) font. Suddenly, everthing becomes readable. Now the instructions for drawing Arial’s capital I look like so:

/I {
[...]
93 hmoveto
95 hlineto
716 vlineto
-95 hlineto
-716 vlineto
closepath
endchar }

It turns out to be quite easy to convert those lines for use with canvas with some simple hackish search/replace/turn-PS-stack-operators-into-JS-function-calls. We’ll just load the T1A file using AJAX and parse it in real time: → Try it out.

Some issues remain: At 150-200KB, those T1A files are pretty huge. To save on filesize and processing time, one could possibly pre-parse those into some made-up canvas font format, or at least remove all the lines the simple parser skips anyway.
Most quality fonts include very specific and complex hinting information to optimize their display at small font sizes where simple antialiasing causes pixels to tend to smudge and run together. A reference implementation of how to handle hints might be FreeType’s Autohinter (or possibly Ghostscript or T1Lib?) Replicating all that in JavaScript would be quite a task… any volunteers?

Additionally, there are most likely licensing issues with putting font data online like that, if you’re not just planning on using open source fonts. I suspect this is one of the reasons the efforts to enable embedding fonts in regular HTML (the DRM’ed EOT and PFR, as well as CSS2’s liberal @font-face) never caught on.

So what to implement in CanvasPaint? I’m leaning towards a pre-parsed “canvasfont” version of Vera Sans… another entry for the todo list. Soon, important messages like these should be easier to create:

[One final idea would be rendering the text server side with ImageMagick or the like, and loading that into the canvas... but that'd be, like, totally lame, right?]

Update: The RhinoCanvas project has an in-depth suggestion for a drawString() method.

features09 Dec 2006 10:24 am

You can now use File>Open to load images from the web – including, but not limited to, ones created with CanvasPaint.

Image upload is next.

reactions07 Dec 2006 05:50 pm

Some of my favorite reactions to CanvasPaint from the blogosphere so far:

»As proof of concept, it’s impressive and shows how close we are to migrating to a web OS.« —digital alchemy

»Might actually be faster to open it from your browser than to load it from your accessories menu.« —Straydog scraps

»Maybe we don’t need Flash so much after all.« —Adam Rossi-Kessel

»wow this person must have not left the house for months« —Justin Chelf

»HOLY CRAP MSPAINT IN A BROWSER. The Internet, by creating this work of Shakespeare, has proven that it is in fact comprised of an infinite number of monkeys with an infinite number of typewriters.« —del.icio.us user mav.rc

and then of course:

»CanvasPaint is everything Web 2.0 should not be« —Rafe Needleman

drawings06 Dec 2006 09:30 pm

Most of the drawings saved online are random scribbles by people just experimenting with the app, a couple are insults or haphazard paintings of genitals, but some people actually take the time to create really cool art. I’ll be posting some prime examples in batches over the next few days — here’s for starters:

Pure awesomeness. Robot on fire! Merry Christmas Pure awesomeness. Beach

(Note: A few of the thumbnails have black backgrounds when the full versions don’t, due to the thumbnail generation process.)

experiences06 Dec 2006 09:20 pm

The origins of CanvasPaint

The CanvasPaint project was originally started over a year ago, in late 2005 when I first heard of the <canvas> tag. I showed my prototype to a few friends and presented it at BarCamp Vienna, but there were — and are — still a few features I wanted to add and bugs I meant to fix before “officially releasing” it. However, I never seemed to get around to doing some more work on it and kept delaying completion.

Lesson learned

If you don’t release yourself, the blogosphere will take care of that for you: Sunday night a colleague blogged about it as a footnote to the current MS Paint pro video that’s making the rounds. A friend read it and reddit. Next was del.icio.us/popular, and then it got dugg.

As soon as I noticed, I hastily put together image saving functionality that has only just become possible for a sizable portion of users since Firefox 2 was released, moved it to its own domain, and spent the next 48 hours watching the hits pour in. Yesterday, 70,000 people tried it out, and over 2,000 images were saved online.

Step 3: Profit?

The public interest in this little tool has motivated me to continue work on CanvasPaint. How much fun it has been watching the drawings come in makes me believe the app might be useful beyond the “somewhat insane tech demo” level.
Thus the current plan is: bugfix, improve usability, redesign and add features: (re-)opening drawings, importing external images, and possibly all the cliche Web 2.0 stuff: tagging, comments, rating and whatnot. This blog (my first!) will serve as a scratchpad for ideas and progress reports.

Regardless of whether you’ll hang around to follow what becomes of this or are already bored to tears by these ramblings of some dude high on a little interweb linkage, I’d like to say: Thanks for checking out CanvasPaint!