2010.04.03

Converting SVG to FIVe3D, Flash Vector Graphics and HTML5 canvas

3d vector tiger

This post is being delayed forever since I was planning to improve my SVG parser but finally I decided to release it since I don’t have plans to work on it anymore.. the basic functionalities are working since July 2009 and I abandoned the project for a while just going back to it a couple months ago when I finally decided to fix a few bugs and add the option to export HTML5 Canvas and Flash AS3 drawing commands… so let’s explain how it all started.

How it started

The whole thing started when I had to import some complex graphics into a Flash project that I was doing using FIVe3d (created by my co-worker Mathieu Badimon). – For those who don’t know FIVe3D is a really cool vector-based 3D engine for Flash, and it doesn’t support regular Sprites or MovieClips, everything needs to be drawn by code using a syntax that mimics the AS3 Graphics class (that is similar to the HTML5 canvas context – if you’re not an AS3 developer), it’s pretty easy to use but it can be very limiting and time consuming if you have to draw a complex shape… so I decided to create a SVG parser from scratch – even knowing that it was done by many people before – I thought it would be a good opportunity to learn a lot of stuff (it was), I couldn’t find any other parser capable to export FIVe3D code and I love to reinvent the wheel… – that way I could just generate all the vector files on Adobe Illustrator (or any other vector drawing software) and export it as an SVG file and then convert it to FIVe3D..

Motifs

FIVe3D uses an internal format that Mathieu decided to call “motifs” that is nothing more than an Array containing drawing commands that he uses to store all the points of each shape. For instance [['M'],[0,50]] means “moveTo(0,50)”, [['L'], [10, 25]] means “lineTo(10, 25)” and so on… – he even created a tool to convert font files into a Class containing all the motifs for each letter that way we can easily use text without having to convert it manually, so my idea was to do the same but instead of converting font files I was going to convert SVG files!

Problems / Limitations

There were many limitations that I had to contour to make it work properly since SVG has hundreds of features (SVG Elements Index, SVG Attributes Index, SVG Property Index) and Flash & FIVe3D doesn’t support some of then natively… – it took me a while just to figure out which features were really required and could be supported by FIVe3D…

Absurd amount of elements, attributes and properties on the SVG spec

I don’t know how they managed to transform something as simple as XML into something so complex… The first big problem was to figure out how to convert the absurd amount of Elements, Attributes and Properties that exist on the SVG specification into the 6 motifs used by FIVe3D (that’s right, just six!!!).

Convert Bézier Curves and Shapes

The next thing was to figure out how to convert a Cubic Bézier Curve into a Quadratic Bézier Curve (Flash and FIVe3D only supports Quadratic Bézier Curves) and than how to convert a circle into Quadratic Bézier Curves (FIVe3D doesn’t have a motif for circle), rounded rectangles and so on.

Groups and Inheritance

Another problem that I had to deal was that sometimes shapes can be grouped and if one property is applied to the group it is inherited by all the group members and some of them are cumulative (like alpha, rotation, etc..) – I wasn’t expecting that since my first tests didn’t had any grouping, so I had to refactor the parser to support groups…

Transformation Matrix

After I had finished almost all the elements I discovered that if you don’t “expand the shape” in Illustrator sometimes it generates the transform attribute (transformation matrix) and that it is cumulative if applied into a group of elements (inheritance), so I had to refactor the whole parser again to support this feature…

The Elliptical Arc

Next big thing that I had to deal was with the insane Elliptical Arc Implementation, since I didn’t had Math during College and also never learned how to read those crazy Mathematical Symbols it took me a while to learn how to implement the stupid elliptical arc path command – I had to first learn how to read the symbols, and believe me, that isn’t easy if you are doing by yourself – after a long time on Wikipedia and getting angry many times it finally worked…

Adding new Features / Stupid Ideas

Since it was raining during the weekend, I was bored and “everything” was working I decided to create new parsers to convert the Motifs into HTML5 Canvas drawing commands and also AS3 Graphics drawing commands – which wasn’t really a smart idea by the way, since the result file should be around 4x bigger than the original file because I’m converting each Cubic Bézier into 4 Quadratic Bézier, each rectangle into 4 lines, etc.. (see problems/limitations above) – also what’s the point of converting SVG into canvas since you are not going to manipulate the coordinates anymore? why don’t you just use a JPG/GIF? it will be way smaller and has the same use… so I only recommend using the HTML5 Canvas and AS3 commands if you’re converting a simple shape… it was created more as a proof-of-concept and because it was easy (I’ve spent just a couple hours implementing both..) – I already knew it wasn’t really useful before building it BUT I WAS BORED :)

PS: the file size can be easily reduced if the Canvas and Graphics parsers didn’t used Motifs as the input – right now I’m converting everything to motifs and than converting it to Canvas/AS3 graphics, a lot of information is lost during this conversion – but It shouldn’t be hard to create a new parser based on SVGToMotifs Class to output direct Canvas/AS3 commands. (maybe I will do it if I get bored again)

What is missing

A lot of stuff is missing, some of then I wouldn’t even try to implement since it would take forever (i.e. masking, animation) or aren’t that useful for me right now.. the <style> tag support is one of them, since Illustrator don’t use it I decided to not implement it in the end (but I’ve implemented in-line style) – all the path drawing commands and shapes are currently supported, gradient fill isn’t supported since FIVe3D doesn’t support it, fonts and bitmaps aren’t supported either.

If something isn’t supported the tool will display a message on the “Warnings Panel”.

Important

Make the vector file as simple as possible removing all the masks, avoiding groups and flattening the file as much as possible..

The parser is actually really fast (it can parse a +1000 lines SVG in less than 1s) but since it outputs an insane amount of text it can even crash your browser if the SVG file is too big since Flash takes a long time to update the text into the output panel, use at your own risk.

Examples

Here are some simple examples of SVG files converted using the tool:

The Tool

I’ve created this simple tool to make it easier to use the parser:

You need flash player 10 to view this content. Good luck if you are using an iPad :)

I’ve just published the source code of the parser on GitHub in case you want to check it out and maybe contribute with the project: http://github.com/millermedeiros/SVGParser – the source code is just of the parser API since the tool is really stupid right now.. – I hope it’s useful for someone!

Update 2011/01/18: integrated some improvements made by Wesley Luyten and fixed some bugs, now it should handle Inkscape files way better. But remember, always flatten images and remove masks for better results!


Comments

[...] Converting SVG to FIVE3D, Flash Vector Graphics and Html5 Canvas 2. Shape Export to [...]

One word: AWESOME!!! Just want I've been looking for. Thank you so much for this!

I get an error 1009 when trying to convert an svg to HTML5 canvas. Do you know what that means? Thanks.

This is a flash error on the XML parser, I think that some properties and tag names (specially the ones with namespaces) makes the flash XML parser to stop working..

I was testing the parser using only SVG files generated by Illustrator (since that was what I use to create vector files) but I've noticed that SVG files created by Inkscape throws this error and I'm almost sure that it's because of the metadata tags that Inkscape uses (I didn't tried to fix it and/or isolate the problem) my goal was to make Illustrator SVGs to work.. (since I've never used Inkscape)

I don't think it should be too hard to find out why it's happening and how to fix this problem.. (just a few regular expressions) - maybe I go back to this project after finishing some other stuff that I'm currently working on or maybe someone fork it and fix it before I do :)

I have a plan to create a new parser to convert SVG into canvas but this time using XSLT instead of AS3. Maybe someday I will have free time (and patience) to do it..

cheers!

Nice work!

I just had a go this evening at parsing SVG to HTML5 canvas on the fly using PHP, you can see my results here:

http://appsynergy.net/projects/converting-svg-path-to-html5-canvas/

A bit more basic than yours (which I didn't find until after I completed the example.. :S), but nice to see multiple solutions!

Thank you for making this SVG parser open source! I bet it's useful to a lot of people. I created a fork on GitHub and made some little changes so it also supports files from Inkscape.

I implemented the parser in my web game, etchNride. Here's an example of a house generated by your parser: www.etchnride.com/jaFyQA

Awesome tool!!

David S. Corchuelo

Awesome tool!! thanks a lot, this is excellent post. I will try this tool and I hope to make contributions.

Nice Tips about for converting SVG into five3d. You have mentioned this information in an attractive manner, which is useful for us. Thank you so much for sharing such kind of posting.

Fonts Converter

Leave a Comment

Please post only comments that will add value to the content of this page. Please read the about page to understand the objective of this blog and the way I think about it. Thanks.

Comments are parsed as Markdown and you can use basic HTML tags (a, blockquote, cite, code, del, em, strong) but some code may be striped if not escaped (specially PHP and HTML tags that aren't on the list). Line and paragraph breaks automatic. Code blocks should be indented with 4 spaces.