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
Files
. 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
page.


<svg version="1.2" baseProfile="tiny" id="FTW"
 xmlns="http://www.w3.org/2000/svg"
 xmlns:xlink="http://www.w3.org/1999/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 {
      margin:1em;
      padding:1em;
    }
    #Logo {
      width:5em;
      height:5em;
      float:left;
    }
    
  
  
    
    
    

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. domStyle.style(node,{'visibility':'hidden'}); // Now we make a new div to take its place on the screen. var extraDiv=document.createElement('div'); domStyle.style(extraDiv,{'position':'absolute','display':'block', 'width':surfaceWidth+'px','height':surfaceHeight+'px', 'top':surfacePos.y+'px','left':surfacePos.x+'px'}); domConstruct.place(extraDiv,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)); } }); } );

Congratulations!

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
happen.

zp8497586rq
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 Saugus.net, Inc.

Recent Features

  • By
    Designing for Simplicity

    Before we get started, it's worth me spending a brief moment introducing myself to you. My name is Mark (or @integralist if Twitter happens to be your communication tool of choice) and I currently work for BBC News in London England as a principal engineer/tech...

  • By
    9 Mind-Blowing WebGL Demos

    As much as developers now loathe Flash, we're still playing a bit of catch up to natively duplicate the animation capabilities that Adobe's old technology provided us.  Of course we have canvas, an awesome technology, one which I highlighted 9 mind-blowing demos.  Another technology available...

Incredible Demos

  • By
    Select Dropdowns, MooTools, and CSS Print

    I know I've harped on this over and over again but it's important to enhance pages for print. You can do some things using simple CSS but today's post features MooTools and jQuery. We'll be taking the options of a SELECT element and generating...

  • By
    Fixing sIFR Printing with CSS and MooTools

    While I'm not a huge sIFR advocate I can understand its allure. A customer recently asked us to implement sIFR on their website but I ran into a problem: the sIFR headings wouldn't print because they were Flash objects. Here's how to fix...