Generating Dojo GFX Drawings from SVG Files ||

By  on  

Eric Brown was my first boss at SitePen and was one of my go-to vector graphic creation men. Eric created an awesome tool for converting SVG images to JSON, useful for creating vector graphics of all rendering engines (Canvas, SVG, VML, etc.) that Dojo's GFX library supports. The original script had a few issues, so Eric's here to clear those up.

This article builds on the earlier article
Generate Dojo GFX Drawings from SVG
. If you've not yet read that article, go and do it now.
I'm not going to repeat what's already in it, and this article won't make
a lick of sense without reading that one first. Really, go ahead, don't
worry, go read it now. I'm a patient sort of guy and will still be here
when you get back.

So you've read it now? Good. You understand that the technique being
discussed here is a way of making images that'll handle resizing gracefully
without quality loss, regardless of whether they're being shown on giant
desktop monitors or minuscule phone displays. With this technique you get
full retina quality without the full retina download. Now you've got got
the basics down and are ready to learn a handful of new tricks.

Tip #1

The first is a work-around for a gotcha that may have bitten you on
some of the SVG images you tried to convert. Oftentimes when you do a
conversion there will be errors in the resulting JSON file that will cause
IE grief. Don't fret! This is a known limitation that has always been in
svg2gfx.xsl, but it's trivially corrected post-conversion. All
that one needs to do is remove occurrences of ,] and
,} from the JSON and the problem is solved. This can be pretty
easily done with your favorite text editor, but it's also easily done with
a one-liner that works on all Linux systems, Macs, and other UNIX-like
machines. Starting with the file you converted per the earlier article,
type the following at the command line:

sed -e 's/,}/}/g' -e 's/,]/]/g' output.json > correctedoutput.json

This will make your JSON play nice with IE. (Yeah experts, I know this
can be done more succinctly with more complicated regular expressions, but
this version works with pretty much any SED.)

Tip #2

[FTW Logo]

This second trick is really easy but will get you better results. Say
for instance you're making a logo for your new company, "FTW",
and you want a few letters incorporated into the logo. Use whatever
graphics tool you're using to generate outlines for the letters prior to
conversion, and your logo will display properly on every machine regardless
of what fonts they've got installed. See? I told you this one was simple.

Tip #3

This third trick is nearly as simple as the second one. If you put
id values on objects within your source SVG, they'll get
carried through as name values within the resulting JSON. This
can make debugging much easier should something go wrong. It also enables
easier manual tweaking after the conversion should it be desirable. Setting
id values can sometimes be done directly within your drawing
application, but can also be done directly to the resulting SVG with a
text editor.

Tip #4

If you're using your image in just one page, there's a performance
advantage to embedding it within the JavaScript for your page. This is
easily done, and best shown by example. I'll walk through the entire
process of using the FTW image above into an embedded resizable logo on a

<svg version="1.2" baseProfile="tiny" id="FTW"
 xmlns:xlink="" x="0px" y="0px"
 width="400px" height="400px" viewBox="0 0 400 400" xml:space="preserve">


Notice that per Tip #2 this SVG has had its FTW replaced with outlines.
In lieu of three letters, it has three paths. This effectively embeds the
font so it'll render the same everywhere. Also, per Tip #3 portions of
the drawing have been given id attributes.

Now we do the full conversion in just one command line by first converting
it as covered in the earlier article, and then piping it directly into the
postprocessing step we discussed above in Tip #1:

xsltproc svg2gfx.xslt ftw.svg | sed -e 's/,}/}/g' -e 's/,]/]/g' > 
 if (1==1) {document.getElementById("link17").style.display="none";} ftw.json

This will give us the GFX JSON we need. It'll all be in one line. We

custom essay writing service

can now copy and paste this line into a page. We'll show it copied into a
page as part of the next trick.

Tip #5

With just a little bit of clever hackery it's easy to work vector
graphics magic into a site that features unobtrusive JavaScript. While
virtually every modern environment both mobile and stationary will use
the vector graphic version, folks without JavaScript will still see at
least an appropriate bitmap image. The code below makes it happen; it's
pretty heavily commented and thus speaks for itself. You can use it as a
template for your own pages. Normally one would use a bitmap image that
approximates the vector image, but here we're using two distinctly different
images to make the workings of the trick more obvious.

    h1 {
    #Logo {

This Company Is FTW!

Blah blah blah, blah blah.

require(["dojo/dom", "dojo/dom-construct", "dojo/dom-style", "dojo/behavior", "dojox/gfx", "dojox/gfx/utils", "dojo/domReady!"], // This code works on desktop browsers including recent versions of // Chrome, Safari, Firefox, Opera, and IE. It works on iOS. It works // on Android. It even works on some more exotic systems like the // OLPC XO. function(dom, domConstruct, domStyle, behavior, gfx, utils) { behavior.add({ '#Logo':function(node) { var logoNode=dom.byId('Logo'); var surfacePos=dojo.position(logoNode); var surfaceWidth=surfacePos.w; var surfaceHeight=surfacePos.h; // The following 400 comes from the size of our original SVG image. var scale=surfaceWidth/400; // We're going to make the bitmap placeholder image hidden.,{'visibility':'hidden'}); // Now we make a new div to take its place on the screen. var extraDiv=document.createElement('div');,{'position':'absolute','display':'block', 'width':surfaceWidth+'px','height':surfaceHeight+'px', 'top':surfacePos.y+'px','left':surfacePos.x+'px'});,node.parentNode,'first'); // We put a GFX surface into this new div. var surface=gfx.createSurface(extraDiv,surfaceWidth,surfaceHeight); var logo=surface.createGroup(); // This next line has your JSON copied into it between the two ' var logoShape='[{name:"FTWLogo",children:[{name:"Pentagon",shape:{type:"polyline",points:[{x:105.232,y:340.097},{x:41.442,y:151.479},{x:201.116,y:32.524},{x:363.591,y:147.625},{x:304.331,y:337.715},{x:105.232,y:340.097}]},fill:"#1B1464",stroke:{color:"#000000",width:"5",style:"Solid"}},{name:"Star1",shape:{type:"polyline",points:[{x:212.992,y:48.754},{x:200.967,y:42.751},{x:189.205,y:49.255},{x:191.198,y:35.963},{x:181.377,y:26.787},{x:194.635,y:24.574},{x:200.328,y:12.399},{x:206.528,y:24.324},{x:219.867,y:25.976},{x:210.441,y:35.558},{x:212.992,y:48.754}]},fill:"#FFFF00",stroke:{color:"#FBB03B",width:"2",style:"Solid"}},{name:"Star2",shape:{type:"polyline",points:[{x:53.874,y:168.643},{x:41.849,y:162.64},{x:30.087,y:169.144},{x:32.08,y:155.853},{x:22.259,y:146.676},{x:35.517,y:144.463},{x:41.209,y:132.289},{x:47.41,y:144.213},{x:60.749,y:145.865},{x:51.323,y:155.447},{x:53.874,y:168.643}]},fill:"#FFFF00",stroke:{color:"#FBB03B",width:"2",style:"Solid"}},{name:"Star3",shape:{type:"polyline",points:[{x:377.663,y:163.829},{x:365.638,y:157.826},{x:353.876,y:164.33},{x:355.869,y:151.039},{x:346.049,y:141.862},{x:359.306,y:139.649},{x:364.998,y:127.475},{x:371.199,y:139.399},{x:384.538,y:141.051},{x:375.112,y:150.633},{x:377.663,y:163.829}]},fill:"#FFFF00",stroke:{color:"#FBB03B",width:"2",style:"Solid"}},{name:"Star4",shape:{type:"polyline",points:[{x:117.066,y:356.964},{x:105.041,y:350.961},{x:93.279,y:357.465},{x:95.272,y:344.174},{x:85.452,y:334.997},{x:98.709,y:332.784},{x:104.402,y:320.609},{x:110.603,y:332.533},{x:123.941,y:334.186},{x:114.516,y:343.768},{x:117.066,y:356.964}]},fill:"#FFFF00",stroke:{color:"#FBB03B",width:"2",style:"Solid"}},{name:"Star5",shape:{type:"polyline",points:[{x:317.365,y:353.679},{x:305.34,y:347.676},{x:293.578,y:354.18},{x:295.57,y:340.889},{x:285.75,y:331.712},{x:299.008,y:329.499},{x:304.701,y:317.324},{x:310.901,y:329.248},{x:324.24,y:330.9},{x:314.814,y:340.482},{x:317.365,y:353.679}]},fill:"#FFFF00",stroke:{color:"#FBB03B",width:"2",style:"Solid"}},{name:"FTW",children:[{name:"F",shape:{type:"path",path:"M137.14,198.674h-28.076v27.392h-20.41v-67.675h48.486v13.574h-28.076v13.086h28.076V198.674z"},fill:"#FFFFFF"},{name:"T",shape:{type:"path",path:"M215.754,174.846h-24.805v51.22h-20.361v-51.22h-24.805v-16.455h69.971V174.846z"},fill:"#FFFFFF"},{name:"W",shape:{type:"path",path:"M337.287,158.391l-29.297,68.554h-11.816l-17.578-39.892l-18.018,39.892h-11.914l-28.711-68.554h21.143 l14.062,37.5l16.113-37.5h14.6l15.82,37.5l14.697-37.5H337.287z"},fill:"#FFFFFF"}]}]}]'; // Now we can load the shape onto the surface. utils.fromJson(logo,logoShape); // This transform converts from our original SVG image size to // the size we need for our display. It's a vector transformation, // so there's no loss of quality. logo.setTransform(gfx.matrix.scale(scale)); } }); } );


Now you're ready to go out and incorporate vector graphics for all your
sites. You no longer have to just dream of having logos that render on any
size display in crystal clear quality. You now have the power to make it

Eric Brown

About Eric Brown

Although his single biggest contribution to the Dojo Toolkit is the svg2gfx.xsl script written in XSLT, Eric spends most of his programming time developing in JavaScript and Python. He's contributed off and on to lots of miscellaneous open source projects with Dojo, Persevere, and ZOPE being just a few of note, and he's one of the Repoze committers. He enjoys writing computer games, and he's in the process of working on a couple right now in JavaScript and Python. He wrote the Dojo Pong demo game and the Antichrist Watch amusement. He has served as a Director of Software at SitePen and RNK Communications, and founded the local Web presence / consulting firm, Inc.

Recent Features

  • By
    Being a Dev Dad

    I get asked loads of questions every day but I'm always surprised that they're rarely questions about code or even tech -- many of the questions I get are more about non-dev stuff like what my office is like, what software I use, and oftentimes...

  • By
    JavaScript Promise API

    While synchronous code is easier to follow and debug, async is generally better for performance and flexibility. Why "hold up the show" when you can trigger numerous requests at once and then handle them when each is ready?  Promises are becoming a big part of the JavaScript world...

Incredible Demos

  • By
    Create Custom Events in MooTools 1.2

    Javascript has a number of native events like "mouseover," "mouseout", "click", and so on. What if you want to create your own events though? Creating events using MooTools is as easy as it gets. The MooTools JavaScript What's great about creating custom events in MooTools is...

  • By
    HTML5&#8217;s placeholder Attribute

    HTML5 has introduced many features to the browser;  some HTML-based, some in the form of JavaScript APIs, but all of them useful.  One of my favorites if the introduction of the placeholder attribute to INPUT elements.  The placeholder attribute shows text in a field until the...