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
}