Illustrator to HTML5's Canvas
January 14I've spent a bit of time playing around with HTML5's canvas element lately. It's a fun new toy and has a lot of potential to be useful. But the biggest headache I'm finding so far is the lack of authoring tools.
SVG has been around for ages, whereas Canvas is still relatively new. (Mozilla's Vladimir Vukićević has a good overview presentation of the differences between the two, and when and where to use each.) SVG support is built into plenty of graphic editing tools; Canvas support is so far sadly lacking, although Matt May pointed me to this YouTube video that shows off the upcoming Canvas support Adobe's CS5 suite will have, whenever it becomes available.
In the meantime, most of the Canvas demos we've seen thus far have mostly featured simple primitive shapes like lines and ellipses for good reason: it's too hard to build up a reasonably complex vector image by manually plotting bezier curves.
Over the past few days I've tried out various ways to get around this problem. I came up with two methods of taking vector shapes out of Illustrator and rendering them with Canvas, both involving an intermediate step as SVG first.
So to start, from Illustrator (or any other vector editing application capable of doing so) export your artwork to SVG. You'll find the SVG option in the Save As / Save a Copy dialog, and I've found the SVG profile you choose doesn't really make much of a difference (though for the sake of argument I've been using 1.1).
We'll use this happy little cloud image as our reference file:
1) Manually
This method is only theoretical so if you're looking for the actual how-to, skip ahead to #2. I figure it might be worth writing this up anyway because, even though I couldn't get it working, perhaps it'll provide enough of a starting point for someone else to pick up where I left off and build a proper converter.
SVG and Canvas are both essentially vector drawing tools; Canvas is more pixel-oriented, but you are certainly able to plot lines and curves mathematically. Canvas is also limited to fewer primitive shapes, but there are obvious parallels between the two.
I spent a bit of time looking into the bezier commands in particular. In SVG, to plot a bezier curve, you do something like this:
<path d="C x1,y1 x2,y2 x,y" />
In Canvas, it's this instead:
ctx.bezierCurveTo(x1,y1, x2,y2, x,y);
Different syntax, but the same basic components: you're drawing a line from the current pen position to the x, y value, and before that you have two additional points (x1, y1 and x2, y2) that set your handles. (More SVG path commands, Canvas path methods.) It's worth noting that SVG is more forgiving about commas; each coordinate must be separated by a comma for the Canvas method, but they're strictly optional in the SVG example. This is relevant because Illustrator's SVG export seems to be wildly inconsistent about when and how many commas each command uses.
Given the similarities, I thought it might be fairly straightforward to manually tweak the SVG output into Canvas drawing functions. M becomes moveTo, C becomes bezierCurveTo, and so forth.
<path d="
M 62.58, 31.96
c -0.711,0 -1.811,0.062 -3.181,0.165
c -0.566 -6.309 -5.862 -11.255 -12.318 -11.255
c -2.363,0 -4.564,0.675 -6.442,1.824 "/>
Becomes:
ctx.moveTo(62.58, 31.96);
ctx.bezierCurveTo(-0.711,0,-1.811,0.062,-3.181,0.165);
ctx.bezierCurveTo(-0.566,-6.309,-5.862,-11.255,-12.318,-11.255);
ctx.bezierCurveTo(-2.363,0,-4.564,0.675,-6.442,1.824);
This did not work. I suspect the absolute vs. relative coordinate difference between SVG's c and C commands tripped me up, but after a half hour or so of poking around this was all I had to show for it:
Still, even if I'd have managed to get it right, I'd rather not have to manually massage my SVG output every time I want a new Canvas drawing. Which leads me to method #2.
2) Automatically
One of the main reasons I bothered to attempt a manual conversion in the first place was because after an extensive search it appeared that people are mostly interested in converting Canvas to SVG. There are very few articles and tools that cover going the other way, which is what we're after. Maybe I didn't come up with exactly the right search term, but I was finding so little I almost gave up entirely.
Then after one last shot in the dark, I managed to stumble across SVGToCanvas, a Java library that promised to do exactly what it sounds like, with a few disclaimers and a major caveat:
- You need Java 6. Otherwise known as 1.6, this comes installed with Mac OS X Snow Leopard but previous versions will need to upgrade. I believe this is the download necessary for Leopard, if you're on an even older version you're on your own. No idea what the Windows situation is, but this might be a good place to start.
- You need to run it on the command line. I know this will freak out some designers, but really, it's not terribly difficult.
- You mainly get outlines for now. This would be the big ugly caveat. Sometimes you get colour and gradients, sometimes you get mixed-up colour and gradients, mostly you don't. Plan to re-add them manually. Hopefully this will work better in a future version of the library, but still, having outlines is a solid start.
Still with me? Great, go grab the JAR file and drop it on your hard drive somewhere easy to find. For now, probably best to drop it in the same folder with the SVG files you're going to convert.
Now, load up the terminal, and find your way to the same directory. Here's a quick command line primer that ought to get you going. The cd, ls, and pwd commands in particular are the ones you need.
(If you need a bit more help than that: put the SVG and JAR files in a folder on your Desktop called 'canvas'. When you open up the terminal, type this minus quotes: 'cd ~/Desktop/canvas'. Hit return. You're good, keep reading.)
Run the converter with the following command:
java -jar svg2canvas.jar -o cloud.html cloud.svg
From left to right: we're invoking Java with the SVGToCanvas library, then by -o cloud.html we're specifying the output will be written to cloud.html, otherwise it just displays the output in the terminal (which can be handy if you'd like to just copy and paste without managing temporary files). Then finally at the end, cloud.svg is the input SVG file that we had previously generated from Illustrator.
That generates an HTML file which contains a canvas element and the Javascript necessary to render the cloud:
In this case it worked, though it added a stroke. When it's just the outline, you can restore the colour by manually tweaking the code. Add a fillStyle method before the draw, and a fill after:
ctx.fillStyle(#4a6481);
... (drawing commands here) ..
ctx.fill();
Not too difficult for simple shapes. I'd hate to have to manually re-add the subtle gradients for more complicated illustrations, but it's nice to know the outline conversion is fairly robust:
Figure: SVG original on the left, the converted Canvas version on the right.
One more thing: I'd recommend flattening the vector art as much as possible. Join shapes that can be joined, expand effects and compound paths and masks, and generally clean up the artwork to as few points as possible. Smaller file sizes, more chance of success upon conversion.
So there you go. It's still a fairly painful way to get your vector work into a canvas, but until we get some better tools or built-in support for our existing tools, it's one way to fill the gap.
Older Than...
January 12For no particular reason, I present to you a list of things that were true on August 27, 2001:
- The iPod, XBox, YouTube, Facebook, Flickr, Ubuntu, and Blu-Ray did not exist.
- IBM was still in the PC business, Handspring was still around, and Blackberries were data-only devices with no telephone capabilities.
- The Euro had not yet entered circulation, currencies like the Franc, Mark and Lira were still legal tender.
- George Harrison, The Queen Mother, Gregory Peck, Barry White, Johnny Cash, Ronald Reagan, Ray Charles, Julia Child, Pope John Paul II, Johnny Carson, Steve Irwin, Gerald Ford and Michael Jackson were still alive.
- SARS, Avian Flu, H1N1 were not in the common vernacular.
- Enron and WorldCom were still in business.
- Oil was $24/barrel, gold was $276/ounce, NASDAQ was at 1912.41, and the DOW was at 10,382.35.
- The Concorde still flew.
- The Petronas Towers were the tallest skyscrapers in the world. (They've been surpassed twice since.)
- Lost and 24 had never aired, there were only four books in the Harry Potter series, and Arnold Schwarzenegger was still making movies.
- Lance Armstrong had only won the Tour de France 3 times. (He went on to win 4 more.)
- The most recent Boston Red Sox World Series win had been 1918 (which remained true until 2004).
- The Netherlands was the only country in the world that legally recognized same sex marriages. (That stands at 7 now).
- Charley, Ivan, Jeanne, Katrina, Dean, and Ike were not names associated with weather.
- 61 Extrasolar planets had been discovered. (Currently that's up to 424).
- Pioneer 10 signals were still being received on Earth.
Dear Adobe
January 8In the spirit of Dear Adobe, I submit the following two minute Photoshop gripe:
As a sanity-check before posting I put this video out on Twitter, and received the following tidbits:
- The lack of ability to paste a hex value appears to be a Mac-only bug, in Windows it works. (Thanks @cloudislands, @friskdesign)
- Within the Save for Web & Devices dialog, if you use the eyedropper tool on the left to select a colour within the canvas, and then hit the Matte colour dropdown menu arrows and select Eyedropper Color, that works. (Thanks @kyleridolfo, @Yardboy, @bradleysepos