Tag Archives: SVG

Using SVG to make custom paper (and why it didn’t work)

I’ve been wanting some specific pages of paper for the paper pad I use at work. I’ll plug the specifics features and brand I love below because I think it’s really cool, but let’s stick to the programming for the moment.

Anyway, there are lots of websites out there that will let you download many different configurations of “graph paper” for you to print out on your own printer. That seemed like what I wanted but site after site that I went to had only a big (or small) tub of PDF files from which you could pick. Sometimes they printed out well, most often not, and they really didn’t have the setups I was interested in trying (something like Cornell Notes but with different things in different areas, like dots or a blank area sometimes instead of lines).

So I had the clever idea that I would put together a simple one page website where you could pick from a few simple blocked out versions of a page (for different sizes of paper like US letter and A4 or portrait vs. landscape layout) and then put any of several different patterns in each area. Then I would generate the page using SVG in the browser and you could print out the paper and even bookmark your creation so you could come back and print it as often as you like. Sheer genius!

Except for one thing, even in 2013 when lots of browsers are claiming to have good SVG support, they kind of forgot to support printing and SVG… So you get results that look great in-browser with Chrome or Firefox and you can zoom in four or more times and still see sharp vector drawn shapes. Print out that same thing and you’ll just get a fuzzy mess, even if you choose PDF as the output target where logically the vector shapes should have just been sent straight into the PDF and zoom just as nicely as they did on screen.

Here’s an example of a dot grid that I wanted to print out to the page:

It looks a little aliased on-screen on Chrome but that didn't bother me, I don't have a Retina display on my Mac so I expected it to be a little rough at anything other than print resolution.

It looks a little aliased on-screen on Chrome but that didn’t bother me, I don’t have a Retina display on my Mac so I expected it to be a little rough at anything other than print resolution.

Here’s the same SVG dot paper zoomed in 400% on Chrome. Yup, I did it correctly. All those dots are little circles spaced out just like I wanted.

Zoomed in everything looks good! Let's print it!

Zoomed in everything looks good! Let’s print it!

Then, sadly, in my experience it matters not whether you’re printing to a real printer or to PDF, the following is typical of what actually comes out for this (zoomed in so you can see all the wonderful detail):

Wow! That's exactly nothing like what I drew. Thanks Chrome, thanks Firefox!

Wow! That’s exactly nothing like what I drew. Thanks Chrome, thanks Firefox!

I didn’t have the heart to try it in IE, I figured it would just be straight up blasphemy. And it wouldn’t matter anyway, because even if IE worked perfectly, any solution that wouldn’t work in Chrome and Firefox would be next to useless because those two browsers represent more than half (and by some estimates right around 66%) of all browsers being used today.

Oh, I did promise a plug for the nifty paper pad I use. If you’re in the United States then the Staples chain of office supply stores has a neat line of pads and paper called Arc. It’s almost identical to the Circa notebooks that Levenger carries except much less expensive. In both cases the spine of the notebooks have a set of small plastic disks onto which specially punched paper is pressed. Just the cross-section shape of the rings and the way the paper is punched is sufficient to keep the pages in place, but should you choose you can easily remove pages, add pages, or rearrange pages without the finickiness of ring binders. I love mine and I bought the special punch that Staples sells so I can use whatever paper I like in my notebook. As a result it’s a mix of blank pages, lined pages, pages for laying out iPhone apps, and even notes I printed out from Evernote. Thus my desire to generate all new forms of paper ideally suited to how I take notes and for noodling on new ideas.

Despite my inability to make this work with SVG, I’m not giving up. I’ll just have to think for a while and return to the problem. Necessity is still the mother of invention and I still need pages I can’t get on any of the downloadable paper sites I’ve been to yet.

Advertisements

Changeable vector graphics with SVG and AngularJS

I’ve long been a fan of using SVG (Scalable Vector Graphics) to do images that I can change easily on the fly. When I say “long been a fan” I mean that when I first started doing it I hand wrote some SVG as XML to show a donation bar we needed for GameDev.net and I had a program that would change the amount thus far donated on the bar and run it through an early version of the Java Batik library to spit out a JPEG file we could put on the website. It was crude, but it sure beat making a new graphic two or three times a day.

Years later things have gotten a lot easier. Modern browsers have advanced to the point where you can include an SVG image in the page as easily as referring to them in an img tag like so, <img src=”something.svg”/>, or just dumping some SVG code straight into the middle of the HTML for your page like this <svg>…lots of vector graphics…</svg>. And editing? Why would you edit by hand anymore when Adobe Illustrator can generate SVG files of your drawings for you, or if you have no budget for such nice tools, Inkscape does a pretty good job and costs nothing.

So it occurred to me the other day that it would be interesting to see if I could use AngularJS and its ability to rewrite HTML on the fly and combine that with SVG in the browser to rewrite SVG on the fly. The answer is, it not only works, it’s downright easy to do so. I’ve provided a couple of different examples to show just how easy it is to so.

Example 1: Have a SVG graphic where I change text within the graphic automatically because it’s tied to a value in an AngularJS model.

Getting an image to start with was pretty easy. I went to The Noun Project and grabbed an icon of the sun I liked. It was provided by an unknown author in this case. The icon came in SVG format so all I did with it in Inkscape was add a little color and some text that showed the temperature. Then I saved that as a “Plain SVG” file rather than an “Inkscape SVG” file. It might have worked as well with the latter but I didn’t want any surprises.

Inkscape editing SVG icon

I then popped over to an HTML file I had generated and imported it with an image link like this:

<img alt="" src="images/sunshine_plus_temp.svg" />

I then hand edited the SVG file and found where the text for the temperature and replaced it with an AngularJS model variable reference. So:

<tspan sodipodi:role="line" id="tspan4542" x="97.124313" y="52.063747">87°</tspan>

became:

<tspan sodipodi:role="line" id="tspan4542" x="97.124313" y="52.063747">{{temp}}°</tspan>

The <img> way of loading the SVG had to change because AngularJS wasn’t going to replace a variable inside an image for me. So I simply pasted the contents of the sunshine_plus_temp.svg right into the middle of a page already setup for AngularJS and put the temp variable into my $scope. It worked like a charm. With an input field tied to the model variable, as I typed, the SVG graphic was automatically updated with the new value.

My final touch was to externalize the SVG file. Nobody wants to edit an HTML file with half a dozen or more embedded lumps of SVG in there. It could quickly turn into an unreadable mess. And, as I already observed, <img> won’t work either. Ah, but AngularJS jumps to the fore again because it has it’s ng-include directive. All I had to do was this:

<span ng-include="'images/sunshine_plus_temp.svg'"></span>

and AngularJS was including the image where I needed it and binding the variable to the model for real-time update. Here’s the final version of the code I came up with for my first example, note the second set of quotes inside the ng-include to tell it not to interpret the string inside there, it’s just a string to use directly:

  <div>
    <p>Example 1: Text updated on the fly in an SVG graphic via AngularJS.</p>
    <span ng-include="'images/sunshine_plus_temp.svg'"></span>
  </div>
  <label>Temperature</label> <input type="text" ng-model="temp"/>

It’s worth noting that Inkscape is still perfectly capable of editing the SVG file even after the change I made and I guess I could have just made the change within Inkscape in the first place and never bothered opening up the file to manually change it with a text editor.

Inkscape editing modified SVG icon

Example 2: Have an SVG graphic that incorporates an image (just because it’s vector doesn’t mean it has to be all vector, SVG is great with images too) and use AngularJS to swap out the images on the fly.

We don’t really need a second example here, the first one showed pretty much everything but I wanted to show how easily images incorporate into SVG and help you achieve results that would be much much harder to do with other techniques. In this example I took a slides icon by Diego Naive, from The Noun Project, overlaid an image on top of it, and then overlaid a glossy reflection on top of half the slide, just to show that the image is fully incorporated by the graphic and can easily be rotated, have graphics on top of it, underneath it, etc. Stuff that would require a lot of work to do with many other techniques.

Again, I tested it out and edited the final SVG file to add a variable reference, in this case to {{slide_image}} instead of the specific file reference that I had added with Inkscape. This time, I will say that it does not edit nearly as well in Inkscape after the edit because it doesn’t know where to find an image named “{{slide_image}}”. Within the Inkscape editor you just see an error box where the image should be. Not perfect, but not debilitating either.

Here’s a page with links to both examples and to the Github repository with all the code for both: http://johnmunsch.github.io/AngularJSExamples/