Using SVG Sprites in a Canvas Game

There are a num­ber of tech­niques or cre­at­ing inter­est­ing and var­ied sprites. Today we’re going to explore using SVG to pro­gram­mat­ic­lly cre­ate sev­eral vari­ations of the one image.

Creating Sprite Variations

SVG is a vec­tor image format that uses lines and shapes to cre­ate images. It’s XML based format, which means we can edit the prop­er­ties of the image using an XML parser, or even using basic string manip­u­la­tion to change the image on the fly.

What this means is that we can eas­ily cus­tom­ise the col­ours or gradi­ents in a game sprite by using as little as a basic search and replace oper­a­tion. This might be used in a num­ber of cir­cum­stances, be it cus­tom­ising your char­ac­ter or just inject­ing some vari­ation into your game scenery.

Today’s work­flow will look like this:

  1. Load SVG file as a string.
  2. Replace all men­tion of a par­tic­u­lar col­our with a new colour.
  3. Render the SVG image to a Canvas context.
  4. Use the rendered con­text as you would any other image.

Editing SVG in Javascript

A suitable SVG image might have lots of solid colours. Here’s a SVG ver­sion of one of our game char­ac­ters, but let’s say we wanted to allow the player to cus­tom­ise their colour.

If you open your SVG image in your text editor, you’ll quickly notice that the format is very sim­ilar in concept to nor­mal HTML and CSS. A nor­mal SVG is gen­er­ally con­struc­ted with paths, shapes, and reg­u­lar text ele­ments (see the MDN site for a full list of SVG ele­ments). You should be able to right click on the image of the ninja to view the source of it an get a feel for what’s going on.

Here’s an example path from our ninja pic. The d attrib­ute spe­cifies the coordin­ates the path fol­lows, and the style attrib­ute allows css-like styles to be applied to the ele­ment. Here we have set a red back­ground col­our (#ff000) in hexa­decimal notation:

<path
d='m 204.146,150.31198 c 0,41.73 0.5,88.463 -8.5,127.998 -66,-28.553 -63,-28.553 -63,-94.447'
id='path51'
style='fill:#ff0000' />

You might real­ise straight away that we can do all kinds of things with this image format, not­ably here we could replace all the instances of the col­our red with any col­our of our choosing.

The fol­low­ing code will search for any ref­er­ence to the col­our red, and replace it with the col­our blue through­out the entire document.

var svgNinjaRed = '<svg […]>'; // This variable contains our SVG file. 
var svgNinjaBlue = svgNinjaRed.replace(/#ff0000/g, '#0000ff');

The ninja is blue after replacing all the red hex codes. Once we’ve run a quick search and replace through the SVG file, all instances of the col­our red have been replaced with blue.

It really is as simple as that for basic oper­a­tions, although we could cre­ate much more advanced tem­plates to add accessor­ies, change fea­tures of the char­ac­ter or update tex­tual values.

Once we’re done, we can render the final SVG to a can­vas con­text and use it in our game.

SVG to Canvas Rendering

Most mod­ern browsers have nat­ive sup­port for load­ing SVG images in the DOM, but instead we’re going to use a third party lib­rary called canvg to render the SVG image to a Canvas buf­fer instead.

Fortunately the syn­tax for canvg is quite simple, and it can take our SVG string as a parameter:

// Create our Canvas element
var canvasNinja = new document.createElement('canvas');
canvasNinja.width = 240;
canvasNinja.height = 320;

// Get drawing context
var canvasNinjaContext = canvasNinja.getContext('2d');

// Render Ninja to canvas
canvasNinjaContext.drawSvg(svgNinjaBlue,0,0);

The SVG image has now been ras­ter­ised for use in our can­vas game.

There are a num­ber of inter­faces to canvg, but the drawSvg method is the most famil­iar because it uses the same syn­tax as the nat­ive can­vas drawImage. It’s also worth not­ing that you should render your SVG to a sep­ar­ate Canvas instance before dis­play­ing it on the screen as the canvg lib­rary isn’t very fast. As com­plex images can take sev­eral seconds to render, keep­ing a pre-rendered copy to use with drawImage is a necessity.

Putting it all together

Once we’ve put all this together, we end up with a pretty sweet script that can change col­ours of SVG sprites on the fly.

I’ve cre­ated a demo show­cas­ing this tech­nique, which lets you see the tech­nique in action. You are free to use it for your own purposes.

If you need to find any SVG resources, the Open Clip Art lib­rary is a good place to start, and if you’re look­ing for a good SVG editor you can get Inkscape for free.

One thought on “Using SVG Sprites in a Canvas Game”

Leave a Reply