mike chambers | about

Saving an SVG File from Paper.js

Tuesday, July 1, 2014

Recently I have been spending some time playing around with Paper.js, an open source vector graphics scripting framework that runs on top of the HTML5 Canvas, similar to CreateJS.

One of the cool features of Paper.js (and the reason I am using it) is that it has support for exporting its content via SVG. Among other things, this allows me to bring anything I create into Illustrator, and gives me the option to do resolution independent prints.

In order to export SVG from Paper.js, you use the project.exportSVG() API. Depending on the options you pass in, this will return an SVG Node, or a String of SVG. You can then trace this to the console, or a TextArea element and copy the SVG into a file to save.

However, I found this pretty tedious, and put together some simple code that will automatically download the generated SVG as an SVG file.

First, an example. Click the circle below to give the canvas focus, and then hit SHIFT-p. This will then download an SVG file of the content.

This works by creating a data URI containing the SVG, using it in a dynamically created Anchor element and then programmatically triggering its click event. (If it doesn’t work for you, read on).

paper.install(window);
    
//currently name doesn't seem to work in some browsers.
//Save SVG from paper.js as a file.
var downloadAsSVG = function (fileName) {
   
   if(!fileName) {
       fileName = "paperjs_example.svg"
   }

   var url = "data:image/svg+xml;utf8," + encodeURIComponent(paper.project.exportSVG({asString:true}));
   
   var link = document.createElement("a");
   link.download = fileName;
   link.href = url;
   link.click();
}
    
var t;
window.onload = function() {
   // Setup directly from canvas id:
   paper.setup('myCanvas');      
   
   //Draw a circle
   var radius = 30;
   var circle = new Shape.Circle(new Point(50,50), radius);
   circle.strokeColor = "#333333";
   circle.fillColor = "#0084B0";
   
   paper.view.update();
   
   t = new Tool();
   
   //Listen for SHIFT-P to save content as SVG file.
   t.onKeyUp = function(event) {
       if(event.character == "P") {
           downloadAsSVG();
       }
   }
}

The HTML5 download attribute on the Anchor element is supposed to specify that the link should be downloaded, and not viewed, as well as the name of the file. However, this doesn’t seem to currently be working in Chrome or IE (at least not in the manner I am using it).

I have tested this in IE 11 on Windows, and Chrome on Mac and Windows. It doesn’t work at all in Firefox, and in Safari, you need to manually save the file once it loads. So, this isn’t usable in a production site, but is perfect if you want to quickly grab vector files of your personal PaperJS projects.

Of course, the best solution would be to prompt the user for a file name and location, something that was possible under the W3C File API specification (and implemented in Chrome). Unfortunately, it appears that that specification is no longer being worked on. This probably still works in Chrome, but my guess is that it may be removed sometime in the future.

To see the complete example code, just right click the example above and select View Source.

twitter github flickr behance