Two.js is a two-dimensional drawing api geared towards modern web browsers. It is renderer agnostic enabling the same api to draw in multiple contexts: svg, canvas, and webgl.
Download
Development Version
Uncompressed with comments about 128kb
Production Version
Minified using Closure Compiler about 50kb
Two.js requires Underscore.js and Backbone.js Events. If you're already loading these files elsewhere then you can build the project yourself and get the file size even smaller. For more information on custom builds check out the source on github.
Overview
-
Focus on Vector Shapes
Two.js is deeply inspired by flat motion graphics. As a result, two.js aims to make the creation and animation of flat shapes easier and more concise. At the time of this writing two.js unfortunately does not support text or images.
-
Scenegraph
At its core two.js relies on a scenegraph. This means that when you draw or create an object (a
Two.PolygonorTwo.Group), two actually stores and remembers that. After you make the object you can apply any number of operations to it — e.g:rotation,translation,scale, etc.. -
Animation Loop
Two.js has a built in animation loop. It is simple in nature and can be automated or paired with another animation library. For more information check out the examples.
-
SVG Interpreter
Two.js features a
Scalable Vector Graphics Interpreter. This means developers and designers alike can create SVG elements in commercial applications like Adobe Illustrator and bring them into your two.js scene. For more information check out the examples.
Basic Usage
In order to start any of these demos you'll want to download two.js and add it to your <html> document. Once downloaded add this tag to the <head> of your document: <script src="./path-to-two/two.js"></script>. When you visit the page, you should be able to open up the console and type Two. If this returns a function then you're ready to begin!
Drawing Your First Shapes
Before we get into all the fancy animating it's good to get a feel for how to make shapes in two.js. In order to do this we need to have an instance of two. This sets up a dom element that contains either an svg or canvas element to add to the webpage. The two object has a scene which holds all shapes as well as methods for creating shapes.
For a list of all properties and construction parameters check out the documentation.
Shapes and Groups
Adding shapes to groups makes managing multiple shapes easier and more sane. Group's provide an easy way to move your content through translation, rotation, and scale. These operations emit from the coordinate space (0, 0). In the example below we can see that the initial orientation of the circle and rectangle changed from the first example. These shapes are oriented around (0, 0), which allows us to transform the group around the centeroid of the shapes. In addition Group's styling operations trickle down and apply to each shape.
All rendered objects in two.js are a child of a group. Every two instance has a property scene. This property is a root-level Two.Group and can act as a camera through the same transformations described above.
Adding Motion
Finally, let's add some motion to our shapes. So far the examples use two.update(); to draw content to the screen. The instance of two.js has two particular methods for animation. The first is two.play(); which calls two.update(); at 60fps. This rate, however, will slowdown if there's too much content to render per frame.
The second method is two.bind(); This method takes a string as its first parameter indicating what event to listen to and a function as its second argument delineating what to do when the event described in the first parameter happens. To sync a function with the animation loop simply invoke two.bind('update', referenceToFunction); as outlined below:
For a complete list of events that can be bound to an instance of two check out the documentation.
Examples
For even more examples check out the example page here.
Projects
For even more projects and information to submit your projects built with two.js check out the project page here.
Documentation
Two
-
When you import the library Two is a
windowlevel class that serves as the main interaction point for the project. It exposes a number of methods and properties. These make it possible to draw, but also afford other capabilities such as augmenting the drawing space. Below are the documented properties and features of theTwoclass. Unless specified methods return their instance ofTwofor the purpose of chaining. -
construction
var two = new Two(params);Create a new instance of
Twowhereparamsis a JavaScript object with several optional parameters listed below:-
type
params.typeSet the type of renderer for the instance: svg, webgl, canvas, etc.. Applicable types are carried within
Two.Types. Default type isTwo.Types.svg. -
width
params.widthSet the width of the drawing space. Disregarded if
params.fullscreenis set totrue. Default width is640pixels. -
height
params.heightSet the height of the drawing space. Disregarded if
params.fullscreenis set totrue. Default height is480pixels. -
autostart
params.autostartA boolean to automatically add the instance to draw on
requestAnimationFrame. This is a convenient substitute so you don't have to calltwo.play(). -
fullscreen
params.fullscreenA boolean to set the drawing space of the instance to be fullscreen or not. If set to
truethenwidthandheightparameters will not be respected. -
ratio
params.ratioSet the resolution ratio for
canvasandwebglrenderers. If left blank two.js automatically infers the ratio based on thedevicePixelRatioapi.
-
-
type
two.typeA string representing which type of renderer the instance has implored.
-
frameCount
two.frameCountA number representing how many frames have elapsed.
-
timeDelta
two.timeDeltaA number representing how much time has elapsed since the last frame in milliseconds.
-
width
two.widthThe width of the instance's dom element.
-
height
two.heightThe height of the instance's dom element.
-
playing
two.playingA boolean representing whether or not the instance is being updated through the automatic
requestAnimationFrame. -
renderer
two.rendererThe instantiated rendering class for the instance. For a list of possible rendering types check out
Two.Types. -
scene
two.sceneThe base level
Two.Groupwhich houses all objects for the instance. Because it is aTwo.Grouptransformations can be applied to it that will affect all objects in the instance. This is handy as a makeshift camera. -
appendTo
two.appendTo(domElement);A convenient method to append the instance's dom element to the page. It's required to add the instance's dom element to the page in order to see anything drawn.
-
play
two.play();This method adds the instance to the
requestAnimationFrameloop. In affect enabling animation for this instance. -
pause
two.pause();This method removes the instance from the
requestAnimationFrameloop. In affect halting animation for this instance. -
update
two.update();This method updates the dimensions of the drawing space, increments the
tickfor animation, and finally callstwo.render(). When using the built-inrequestAnimationFramehook,two.play(), this method is invoked for you automatically. -
render
two.render();This method makes the instance's renderer draw. It should be unnecessary to invoke this yourself at anytime.
-
add
two.add(objects);Add one or many shapes / groups to the instance. Objects can be added as arguments,
two.add(o1, o2, oN), or as an array depicted above. -
remove
two.remove(objects);Remove one or many shapes / groups from the instance. Objects can be removed as arguments,
two.remove(o1, o2, oN), or as an array depicted above. -
clear
two.clear();Removes all objects from the instance's scene. If you intend to have the browser garbage collect this, don't forget to delete the references in your application as well.
-
makeLine
two.makeLine(x1, y1, x2, y2);Draws a line between two coordinates to the instance's drawing space where
x1,y1are the x, y values for the first coordinate andx2,y2are the x, y values for the second coordinate. It returns aTwo.Polygonobject. -
makeRectangle
two.makeRectangle(x, y, width, height);Draws a rectangle to the instance's drawing space where
x,yare the x, y values for the center point of the rectangle andwidth,heightrepresents the width and height of the rectangle. It returns aTwo.Polygonobject. -
makeCircle
two.makeCircle(x, y, radius);Draws a circle to the instance's drawing space where
x,yare the x, y values for the center point of the circle andradiusis the radius of the circle. It returns aTwo.Polygonobject. -
makeEllipse
two.makeEllipse(x, y, width, height);Draws an ellipse to the instance's drawing space where
x,yare the x, y values for the center point of the ellipse andwidth,heightare the dimensions of the ellipse. It returns aTwo.Polygonobject. -
makeCurve
two.makeCurve(x1, y1, x2, y2, xN, yN, open);Draws a curved polygon to the instance's drawing space. The arguments are a little tricky. It returns a
Two.Polygonobject.The method accepts any amount of paired x, y values as denoted by the series above. It then checks to see if there is a final argument, a boolean
open, which marks whether or not the shape should be open. Iftruethe curve will have two clear endpoints, otherwise it will be closed.This method also recognizes the format
two.makeCurve(points, open)where points is an array ofTwo.Anchor's and open is an optional boolean describing whether or not to expose endpoints. It is imperative if you generate curves this way to make the list of pointsTwo.Anchor's. -
makePolygon
two.makePolygon(x1, y1, x2, y2, xN, yN, open);Draws a polygon to the instance's drawing space. The arguments are a little tricky. It returns a
Two.Polygonobject.The method accepts any amount of paired x, y values as denoted by the series above. It then checks to see if there is a final argument, a boolean
open, which marks whether or not the shape should be open. Iftruethe polygon will have two clear endpoints, otherwise it will be closed.This method also recognizes the format
two.makePolygon(points, open)where points is an array ofTwo.Anchor's and open is an optional boolean describing whether or not to expose endpoints. It is imperative if you generate curves this way to make the list of pointsTwo.Anchor's.The
Two.Polygonthat this method creates is the base shape for all of the make functions. -
makeGroup
two.makeGroup(objects);Adds a group to the instance's drawing space. While a group does not have any visible features when rendered it allows for nested transformations on shapes. See
Two.Groupfor more information. It accepts an array of objects,Two.Polygons orTwo.Groups. As well as a list of objects as the arguments,two.makeGroup(o1, o2, oN). It returns aTwo.Groupobject. -
interpret
two.interpret(svgNode);Reads an svg node and draws the svg object by creating
Two.Polygons andTwo.Groups from the reference. It then adds it to the instance's drawing space. It returns anTwo.Groupobject. -
bind
two.bind(event, callback);Bind an event, string, to a callback function. Passing
"all"will bind the callback to all events. Inherited from Backbone.js. -
unbind
two.unbind(event, callback);Remove one or many callback functions. If callback is
nullit removes all callbacks for an event. If the event name is null, all callback functions for the instance are removed. This is highly discouraged. Inherited from Backbone.js. -
Array
Two.ArrayA JavaScript
Float32Arraywith graceful fallback to JavaScriptArray. -
Collection
Two.CollectionA databound instance of an array, used for
verticesattribute of aTwo.Polygon. -
Types
Two.TypesA list of applicable types of rendering contexts. This is used to standardize the addresses of the various renderers. The types include
svg,canvas, andwebgl. e.g:Two.Types.svg -
Properties
Two.PropertiesA list of renderer specific application properties.
-
Events
Two.EventsA list of actionable events triggered by a given instance. For the most part these are internal events in order to enable two-way databinding. Exceptions include
updateevent on animation loop andresizewhen the dimensions of the drawing space change. Related totwo.bindandtwo.trigger. -
Commands
Two.CommandsA list of commands that dictate how the various renderers draw
Two.Anchors. -
Resolution
Two.ResolutionA number representing how many subdivisions should be present during curve calculations.
-
Instances
Two.InstancesA running list of all instances created on the page.
-
noConflict
Two.noConflict();Run two.js in
noConflictmode, returning thetwovariable to its previous owner. Returns a reference to theTwoclass. -
Utils
Two.UtilsA collection of utility functions and variables used throughout the project. This is where much of the algorithmic computation lies: computing curve handles, subdividing cubic bezier curves, interpretting svg nodes. Because of its complexity it's encouraged to look at the source code for further information.
-
Error
Two.Error(message);A two.js specific custom error handler. Takes a message, string, to display in the console to developers.
Two.Polygon
-
This is the base class for creating all drawable shapes in two.js. Unless specified methods return their instance of
Two.Polygonfor the purpose of chaining. -
construction
var polygon = new Two.Polygon(vertices, closed, curved, manual);A polygon takes an array of
verticeswhich are made up ofTwo.Anchors. This is essential for the two-way databinding. It then takes two booleans,closedandcurvedwhich delineate whether the shape should be closed (lacking endpoints) and whether the shape should calculate curves or straight lines between the vertices. Finally, manual is an optional argument if you'd like to override the default behavior of two.js and handle anchor positions yourself. Generally speaking, this isn't something you need to deal with, although some great usecases arise from this customability, e.g: advanced curve manipulation.If you are constructing groups this way instead of
two.makePolygon(), then don't forget to add the group to the instance's scene,two.add(group). -
id
polygon.idThe id of the polygon. In the svg renderer this is the same number as the
idattribute given to the corresponding node. i.e: ifpolygon.id = 4thendocument.querySelector('#two-' + group.id)will return the corresponding svg node. -
stroke
polygon.strokeA string representing the color for the stroke of the polygon. All valid css representations of color are accepted.
-
fill
polygon.fillA string representing the color for the area of the vertices. All valid css representations of color are accepted.
-
linewidth
polygon.linewidthA number representing the thickness the polygon's strokes. Must be a positive number.
-
opacity
polygon.opacityA number representing the opacity of the polygon. Use strictly for setting. Must be a number 0-1.
-
cap
polygon.capA string representing the type of stroke cap to render. All applicable values can be found on the w3c spec. Defaults to
"round". -
join
polygon.joinA string representing the type of stroke join to render. All applicable values can be found on the w3c spec. Defaults to
"round". -
miter
polygon.miterA number representing the miter limit for the stroke. Defaults to 1.
-
rotation
polygon.rotationA number that represents the rotation of the polygon in the drawing space, in radians.
-
scale
polygon.scaleA number that represents the uniform scale of the polygon in the drawing space.
-
translation
polygon.translationA
Two.Vectorthat represents x, y translation of the polygon in the drawing space. -
parent
polygon.parentA reference to the
Two.Groupthat contains this instance. -
vertices
polygon.verticesAn
Two.CollectionofTwo.Anchors that is two-way databound. Individual vertices may be manipulated, however it is imperative that the array itself does not get manipulated. -
closed
polygon.closedBoolean that describes whether the polygon is closed or not.
-
curved
polygon.curvedBoolean that describes whether the polygon is curved or not.
-
automatic
polygon.automaticBoolean that describes whether the polygon should automatically dictate how
Two.Anchors behave. This defaults totrue. -
beginning
polygon.beginningA number, 0-1, that is mapped to the layout and order of vertices. It represents which of the vertices from beginning to end should start the shape. Exceedingly helpful for animating strokes. Defaults to 0.
-
ending
polygon.endingA number, 0-1, that is mapped to the layout and order of vertices. It represents which of the vertices from beginning to end should end the shape. Exceedingly helpful for animating strokes. Defaults to 1.
-
clip
polygon.clipA boolean describing whether to render this shape as a clipping mask. This property is set automatically in correspondence with
Two.Group.mask. Defaults tofalse. -
clone
polygon.clone();Returns a new instance of a
Two.Polygonwith the same settings. -
center
polygon.center();Anchors all vertices around the centroid of the group.
-
addTo
polygon.addTo(group);Adds the instance to a
Two.Group. -
remove
polygon.remove();If added to a
two.scenethis method removes itself from it. -
getBoundingClientRect
polygon.getBoundingClientRect(shallow);Returns an object with top, left, right, bottom, width, and height parameters representing the bounding box of the polygon. Pass
trueif you're interested in the shallow positioning, i.e in the space directly affecting the object and not where it is nested. -
noFill
polygon.noFill();Removes the fill.
-
noStroke
polygon.noStroke();Removes the stroke.
-
plot
polygon.plot();If curved goes through the vertices and calculates the curve. If not, then goes through the vertices and calculates the lines.
-
subdivide
polygon.subdivide();Creates a new set of vertices that are
lineToanchors. For previously straight lines the anchors remain the same. For curved lines, however,Two.Utils.subdivideis used to generate a new set of straight lines that are perceived as a curve. -
MakeObservable
Two.Polygon.MakeObservable();Convenience method to make getter / setter properties specific to
Two.Polygon. Two.Group
-
This is a container object for two.js — it can hold shapes as well as other groups. At a technical level it can be considered an empty transformation matrix. It is recommended to use
two.makeGroup()in order to add groups to your instance oftwo, but it's not necessary. Unless specified methods return their instance ofTwo.Groupfor the purpose of chaining. -
construction
var group = new Two.Group();If you are constructing groups this way instead of
two.makeGroup(), then don't forget to add the group to the instance's scene,two.add(group). -
id
group.idThe id of the group. In the svg renderer this is the same number as the
idattribute given to the corresponding node. i.e: ifgroup.id = 5thendocument.querySelector('#two-' + group.id)will return the corresponding node. -
stroke
group.strokeA string representing the color for the stroke of all child shapes. Use strictly for setting. All valid css representations of color are accepted.
-
fill
group.fillA string representing the color for the area of all child shapes. Use strictly for setting. All valid css representations of color are accepted.
-
linewidth
group.linewidthA number representing the thickness of all child shapes' strokes. Use strictly for setting. Must be a positive number.
-
opacity
group.opacityA number representing the opacity of all child shapes. Use strictly for setting. Must be a number 0-1.
-
cap
group.capA string representing the type of stroke cap to render for all child shapes. Use strictly for setting. All applicable values can be found on the w3c spec. Defaults to
"round". -
join
group.joinA string representing the type of stroke join to render for all child shapes. Use strictly for setting. All applicable values can be found on the w3c spec. Defaults to
"round". -
miter
group.miterA number representing the miter limit for the stroke of all child objects. Use strictly for setting. Defaults to 1.
-
rotation
group.rotationA number that represents the rotation of the group in the drawing space, in radians.
-
scale
group.scaleA number that represents the uniform scale of the group in the drawing space.
-
translation
group.translationA
Two.Vectorthat represents x, y translation of the group in the drawing space. -
children
group.childrenA map of all the children of the group.
-
parent
group.parentA reference to the
Two.Groupthat contains this instance. -
mask
group.maskA reference to the
Two.Polygonthat masks the content within the group. Automatically sets the referencedTwo.Polygon.cliptotrue. -
clone
group.clone();Returns a new instance of a
Two.Groupwith the same settings.This will copy the children as well, which can be computationally expensive.
-
center
group.center();Anchors all children around the centroid of the group.
-
addTo
group.addTo(group);Adds the instance to a
Two.Group. In many ways the inverse oftwo.add(object). -
add
group.add(objects);Add one or many shapes / groups to the instance. Objects can be added as arguments,
two.add(o1, o2, oN), or as an array depicted above. -
remove
group.remove(objects);Remove one or many shapes / groups to the instance. Objects can be removed as arguments,
two.remove(o1, o2, oN), or as an array depicted above. -
getBoundingClientRect
group.getBoundingClientRect(shallow);Returns an object with top, left, right, bottom, width, and height parameters representing the bounding box of the polygon. Pass
trueif you're interested in the shallow positioning, i.e in the space directly affecting the object and not where it is nested. -
noFill
group.noFill();Remove the fill from all children of the group.
-
noStroke
group.noStroke();Remove the stroke from all children of the group.
-
MakeObservable
Two.Group.MakeObservable();Convenience method to make getter / setter properties specific to
Two.Group. Two.Anchor
-
Taken from the Adobe Illustrator nomenclature a
Two.Anchorrepresents an anchor point in two.js. This class delineates to the renderer what action to take when plotting points. It inherits all properties and methods fromTwo.Vector. As a result,Two.Anchorcan be used as such. Depending on its command, anchor points may or may not have corresponding control points to describe how their bezier curves should be rendered. -
construction
var anchor = new Two.Anchor(x, y, lx, ly, rx, ry, command);A
Two.Anchorcan take initial positions ofxandyto orient the point.lxandlydescribe where the left control point will reside. Likewiserxandrydescribe where the right control point will reside. Finally, thecommanddescribes what action the renderer will take once rendering. A more detailed description of commands can be found on the w3c and the available commands in two.js can be found underTwo.Commands.Two.Anchoris introduced to two.js as of v0.3.0 -
x
anchor.xThe x value of the anchor's position.
-
y
anchor.yThe y value of the anchor's position.
-
command
anchor.commandThe command for the given anchor.
-
controls
anchor.controlsAn object that exists only when
anchor.commandisTwo.Commands.curve. It holds the anchor's control pointTwo.Vectors and describes what the make up of the curve will be.-
right
anchor.controls.rightA
Two.Vectorthat represents the position of the control point to the “right” of the anchor's position. To further clarify, if you were to orient the anchor so that it was normalized and facing up, this control point would be to the right of it. -
left
anchor.controls.leftA
Two.Vectorthat represents the position of the control point to the “left” of the anchor's position. To further clarify, if you were to orient the anchor so that it was normalized and facing up, this control point would be to the left of it.
-
-
clone
anchor.clone();Returns a new instance of a
Two.Anchorwith the samex,y,controls, andcommandvalues as the instance. -
listen
anchor.listen();Convenience method to add event bubbling to an attached polygon.
-
ignore
anchor.ignore();Convenience method to remove event bubbling to an attached polygon.
-
AppendCurveProperties
Anchor.AppendCurveProperties();Convenience method to add the
controlsobject. Two.Vector
-
This is the atomic coordinate representation for two.js. A
Two.Vectoris different and specific to two.js because its main properties,xandy, trigger events which allow the renderers to efficiently change only when they need to. Unless specified methods return their instance ofTwo.Vectorfor the purpose of chaining. -
construction
var vector = new Two.Vector(x, y); -
x
vector.xThe x value of the vector.
-
y
vector.yThe y value of the vector.
-
set
vector.set(x, y);Set the
x,yproperties of the vector to the argumentsx,y. -
copy
vector.copy(v);Set the
x,yproperties of the vector from another vector,v. -
clear
vector.clear();Set the
x,yproperties of the vector to 0. -
clone
vector.clone();Returns a new instance of a
Two.Vectorwith the samex,yvalues as the instance. -
add
vector.add(v1, v2);Add to vectors together. The sum of the
x,yvalues will be set to the instance. -
addSelf
vector.addSelf(v);Add the
x,yvalues of the instance to the values of another vector. Set the sum to the instance's values. -
sub
vector.sub(v1, v2);Subtract two vectors. Set the difference to the instance.
-
subSelf
vector.subSelf(v);Subtract a vector,
v, from the instance. -
multiplySelf
vector.multiplySelf(v);Multiply the
x,yvalues of the instance by another vector's,v,x,yvalues. -
multiplyScalar
vector.multiplyScalar(value);Multiply the
x,yvalues of the instance by another number,value. -
divideScalar
vector.divideScalar(value);Divide the
x,yvalues of the instance by another number,value. -
negate
vector.negate();Toggle the sign of the instance's
x,yvalues. -
dot
vector.dot(v);Return the dot product of the instance and a vector,
v. -
lengthSquared
vector.lengthSquared();Return the length of the vector squared.
-
length
vector.length();Return the length of the vector.
-
normalize
vector.normalize();Reduce the length of the vector to the unit circle.
-
distanceTo
vector.distanceTo(v);Return the distance from the instance to another vector,
v. -
distanceToSquared
vector.distanceToSquared(v);Return the distance squared from the instance to another vector,
v. -
setLength
vector.setLength(length);Set the length of a vector to a specified distance,
length. -
equals
vector.equals(v);Return a boolean representing whether or not the vectors are within 0.0001 of each other. This fuzzy equality helps with Physics libraries.
-
lerp
vector.lerp(v, t);Linear interpolation of the instance's current
x,yvalues to the destination vector,v, by an amount,t. Where t is a value 0-1. -
isZero
vector.isZero();Returns a boolean describing the length of the vector less than 0.0001.
These are the five main classes that a typical developer will come across with when using two.js, however the project is built with a few more classes behind the scene. If you're interested in the nitty-gritty then it's recommended to check out the source.
Credits
Two.js is not possible without these great contributions to JavaScript:
-
Underscore.js
Utility functions and the magical
debouncemethod which makes much of the morphing efficient. -
Backbone.js
Event binding, bubbling, and communication.
-
Request Animation Frame
Polyfill version by Paul Irish.
-
Three.js
The initial proof-of-concept was made in Three.js — much of the style and tone of the API mimics Three.
-
Qunit + Resemble + Canvas2Blob
Testing framework with image differencing functions for cross rendering comparisons.
-
Code Mirror + jQuery
Simple in-browser editor for tweaking values in Basic Usage.
-
Tween.js
Awesome tween library in JavaScript.
-
Bourbon
Simple SCSS framework for writing better css.
-
Google Data Arts Team
Inspiring JavaScript developers everywhere.