SVG & Javascript


generative, interactive images on the web

Inspired by Processing and openFrameworks, built on SVG just like D3.js

SVG on Github

svg.js (13kb) current version

This is a small library - just one level higher than writing W3C DOM level 1. It’s meant to clean up the annoying bits and provide event handlers, otherwise keeps it simple.

Introduction

This is the SVG-Javascript object.

sketch = SVG.image()

I’ve named this instance sketch. Think of it as the SVG image itself, but with methods and event handlers.

sketch.w  // get/set the width of the SVG

This initializer creates and attaches one SVG image to the web page, by default, at the bottom. If you provide the id name of an HTML element the image will be appended as a child to that element.

sketch = SVG.image("my-container-id")

Simple Example

Draw with the mouse in a few lines of code:

let prev, sketch = SVG.image();

sketch.onMouseMove = function(mouse) {
   if (prev == null) { prev = mouse; }
   sketch.line(prev.x, prev.y, mouse.x, mouse.y);
   prev = mouse;
}

Everything is under the SVG namespace. There is a growing list of geometry primitives,

line (x1, y1, x2, y2)
circle (x, y, radius)
rect (x, y, width, height)
polygon (pointsArray)
polyline (pointsArray)
bezier (fromX, fromY, c1X, c1Y, c2X, c2, toX, toY)
arc (x, y, radius, startAngle, endAngle)
wedge (x, y, radius, startAngle, endAngle)
text (textString, x, y)
regularPolygon (cX, cY, radius, sides)

as well as group, a container which can sort things like layers in Photoshop.

group()

These methods create the element, you still need to append it for it to appear on screen; a sequence that follows the W3C convention of createElement() and appendChild().

myGroup = SVG.group()
myLine = SVG.line(0, 0, 100, 100)

sketch.appendChild(myGroup)  // append the group to the image
myGroup.appendChild(myLine)  // append the line to the group

Or notice how in the first example sketch preceded the line call. This will automatically attach the line to the sketch. both svgs and groups can call draw methods on themselves, allowing you to skip the call to appendChild.

let g = SVG.group()
g.line(1,2,3,4)

will create:

<g><line x1=​"1" y1=​"2" x2=​"3" y2=​"4"></line></g>

Events

onMouseMove is just one of many event handlers.

sketch.onMouseMove = function(mouse) {}
sketch.onMouseDown = function(mouse) {}
sketch.onMouseUp = function(mouse) {}
sketch.onMouseLeave = function(mouse) {}
sketch.onMouseEnter = function(mouse) {}
sketch.animate = function(event) {}

The last on this list is an animation loop; if you implement animate the function body will repeat 60 times every second.

The energy impact of this library is very low until you active the animate method.

and since everything on the page is an honest SVG, saving-to and loading-from is really simple.

save (svg, filename)
load (input, callback)

Styling

All style commands are CSS and should be easy to search on the internet. Styling can be applied in 1 of 3 ways.

attributes (1):

shape = SVG.rect(3, 3, 500, 500)
shape.setAttribute("fill", "none")
shape.setAttribute("stroke", "#39F")
shape.setAttribute("stroke-width", 4)

or inline style (2):

shape = SVG.rect(3, 3, 500, 500)
shape.setAttribute("style", "fill: none; stroke: #39F; stroke-width: 4")

or, create a class definition for .my-shape in a separate CSS style sheet (3):

shape = SVG.rect(3, 3, 500, 500)
shape.setAttribute("class", "my-shape")

// or, equivalently
shape = SVG.rect(3, 3, 500, 500, "my-shape")

Appendix

additional methods I use often:

SVG methods

// update the geometry of a polygon/polyline or arc/wedge
setPoints(node, pointsArray)
setArc(node, x, y, radius, startAngle, endAngle, includeCenter = false)

// add and remove classes
addClass(node, newClass)
removeClass(node, newClass)

// clear the contents of a group or an svg
removeChildren(node)

SVG.image() methods

// get/set the visible dimensions
w
h

// get/set the units inside the canvas. not the visible dimensions
setViewBox(x, y, width, height)
getViewBox()

// clear an image
removeChildren()

// event handlers like onMouseMove provide this event object
{
  isPressed: false, // is the mouse button pressed (y/n)
  position: [0,0],  // the current position of the mouse [x,y]
  pressed: [0,0],   // the last location the mouse was pressed
  drag: [0,0],      // vector, displacement from start to now
  prev: [0,0],      // on mouseMoved, the previous location
  x: 0,             //
  y: 0              // -- x and y, these are the same as position
}