Two.js
A two-dimensional drawing api meant for modern browsers. It is renderer agnostic enabling the same api to render in multiple contexts: webgl, canvas2d, and svg.
Home • Examples • Documentation • Help
Usage
Download the latest minified library and include it in your html.
<script src="js/two.min.js"></script>
It can also be installed via npm, Node Package Manager:
npm install --save two.js
Alternatively see how to build the library yourself.
Here is boilerplate html in order to draw a spinning rectangle in two.js:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="js/two.min.js"></script>
</head>
<body>
<script>
var two = new Two({
fullscreen: true,
autostart: true
}).appendTo(document.body);
var rect = two.makeRectangle(two.width / 2, two.height / 2, 50 ,50);
two.bind('update', function() {
rect.rotation += 0.001;
});
</script>
</body>
</html>
Custom Build
Two.js uses nodejs in order to build source files. You'll first want to install that. Once installed open up a terminal and head to the repository folder:
cd ~/path-to-repo/two.js
npm install
This will give you a number of libraries that the development of Two.js relies on. If for instance you only use the SvgRenderer then you can really cut down on the file size by excluding the other renderers. To do this, modify /utils/build.js to only add the files you'd like. Then run:
node ./utils/build
And the resulting /build/two.js and /build/two.min.js will be updated to your specification.
Running in Headless Environments
As of version v0.7.x Two.js can also run in a headless environment, namely running on the server with the help of a library called Node Canvas. We don't add Node Canvas to dependencies of Two.js because it's not necessary to run it in the browser. However, it has all the hooks setup to run in a cloud environment. To get started follow the installation instructions on Automattic's readme. After you've done that run:
npm install canvas
npm install two.js
Now in a JavaScript file setup your Two.js scenegraph and save out frames whenever you need to:
var { createCanvas, Image } = require('canvas');
var Two = require('two.js')
var fs = require('fs');
var path = require('path');
var width = 800;
var height = 600;
var canvas = createCanvas(width, height);
Two.Utils.shim(canvas, Image);
var time = Date.now();
var two = new Two({
width: width,
height: height,
domElement: canvas
});
var rect = two.makeRectangle(width / 2, height / 2, 50, 50);
rect.fill = 'rgb(255, 100, 100)';
rect.noStroke();
two.render();
var settings = { compressionLevel: 3, filters: canvas.PNG_FILTER_NONE };
fs.writeFileSync(path.resolve(__dirname, './images/rectangle.png'), canvas.toBuffer('image/png', settings));
console.log('Finished rendering. Time took: ', Date.now() - time);
process.exit();
Change Log
Nightly
- Removed extraneous underscore calls from
Two.Utils@adroitwhiz
January, 2020 v0.7.0
- Exposed
resolutionparameter inTwo.makeCircleandTwo.makeEllipseas the final parameter - Made
Two.CircleandTwo.Ellipserecalculate controls points on_updateand made vertex amounts cyclical @adroitwhiz - Added ESLint scripts to development environment @adroitwhiz
- Improve performance of WebGLRenderer by leveraging uniform to construct plane and removing duplicate render calls @adroitwhiz
- Unpacked
scaleobjects in WebGLRenderer @adroitwhiz - Removed unnecessary
gl.colorMaskcalls @adroitwhiz - Removed
Two.Utils.toFixedcalls on Canvas and WebGLRenderers @adroitwhiz Two.Shape.cloneclonesTwo.Shape.matrixwhenTwo.Shape.matrix.manualis set totrue- Improved
Two.Group.maskrendering inTwo.WebGLREnderer - Fixed
Two.WebGLRenderer.setSizerecursive loop error - Connected
Two.Shape.classNametoTwo.Shape.classListfor searching and class assignment in SVG elements - Performance improvements on canvas HTML5 styles @brandonheyer
- Added trickle down styling to
Two.Group.closed,Two.Group.curved, andTwo.Group.automatic - Check for Duplicity on
Two.Group.add - Accounted for offset positions in
Two.Path.centerandTwo.Group.centermethods - Exposed
Two.Shape.matrixas a publicly accessible property - Removed
Two.Utils.deltaTransformPointand patchedTwo.Utils.decomposeMatrixto more accurately parse matrices - Added support for various position inclusion of gradients and other effects in
Two.interpret - Improved
Two.Utils.applySvgAttributesrotation from SVG interpretation - Added
Two.makeArrowfor Simple Triangular Tipped Arrows @mike168m - Improved
Two.Matrixefficiency of calculations - Added
Two.Path.dashes.offsetandTwo.Text.dashes.offsetproperties for animating dashed strokes in all renderers - Fixed
Two.Path.cornermethod to not be additive on successive invocations - Split
Two.Matrix.toArrayinto two different functions. One for 2D transforms and one for a plain object (JSON) representation - Added
Two.Matrix.toTransformArrayintended for 2D transformation use internally WebGLRenderermore robustly supports displaying bitmap content- Added
<g />attributes to be inherited by children in SVG interpretation - Added
offscreenElementas an option when constructing WebGL Renderers for WebWorker compatibility - Added
Two.Shape.positionaccessor toTwo.Shape.translationfor ease of use with matter.js - Added
Two.Path.dashesandTwo.Text.dashessupport to WebGL and Canvas Renderers
December 8, 2018 v0.7.0-beta.3
- Canvas Renderer supports dashed and non dashed paths
- Enforce
Two.Rectanglehas fourvertices - Fixed
Two.Path.closedon latestendingcalculations
November 18, 2018 v0.7.0-beta.2
- Updated Two.js compatibility with webpack and node-canvas 2.0.0+
November 3, 2018 v0.7.0-beta.1
- Altered
Two.Path.cloneandTwo.Text.cloneto use references where possible and to_update()on return - Improved multi-decimal and arc SVG interpretation
- Added
Two.Commands.arcfor better arc rendering across all renderers Two.PathandTwo.Textnow havedashesproperty to define stroke dashing behavior @danvanordenTwo.Vectorarithmetic methods made more consistent — still need to improve performanceTwo.Path.verticeswill not clone vectors, improving developer clarity- Two.js clone methods do not force adding to a parent
Two.ImageSequence,Two.Sprite, andTwo.Rectanglehaveoriginproperties for offset renderingTwo.Group.getBoundingClientRectwill pass-through on effects instead of breakTwo.interpretapply SVG nodestyleattributes to paths. Inherits from groupsand infers SVGviewBoxattribute against Two.js instanceTwo.interpretimproves multi-decimal formatteddattributesTwo.ZUIadded through the new/extrasfolderTwo.Text.getBoundingClientRectnow returns an estimated bounding box objectTwo.interpretproperly assigns back calculatedZcoordinatesTwo.loadnow immediately returns aTwo.Groupfor use without callbacks if desired- Added
Two.Group.lengthto return the calculated length of all child paths Two.Group.beginningandTwo.Group.endingcalculate based on childTwo.Paths for intuitive grouped animating- Added
Two.Utils.shimto properly handlecanvasandimageelement spoofing in headless environments - Improved conformance between primitive shapes
Two.Path.getBoundingClientRectconsiders control points from bezier curvesTwo.Path.beginningandTwo.Path.endingcalculate based on distance increasing accuracy for animation, but also performance load- Moved
Two.Path._verticesunderlying to list of rendered points toTwo.Path._renderer.vertices - Improved accuracy of
Two.Path.endingandTwo.Path.beginningon open paths - Added specific
clonemethod toTwo.ArcSegment,Two.Circle,Two.Ellipse,Two.Polygon,Two.Rectangle,Two.RoundedRectangle, andTwo.Starprimitives - Added ability to read
viewBoxproperty from root SVG node inTwo.interpret - Added more reliable transform getter in
Two.interpret - Added
rxandryproperty reading onTwo.Utils.read.rect - Added
Two.Utils.read['rounded-rect']to interpret Rounded Rectangles - Added ability for
Two.RoundedRectangle.radiusto be aTwo.Vectorfor x, y component styling - Added ES6 compatible
./build/two.module.jsfor importing library - Improved
QSVG interpretation Two.Texture,Two.Sprite, andTwo.ImageSequenceimplemented inWebGLRenderer- Added
classNameproperty toTwo.Shapes for easier CSS styling inSVGRenderer@fr0 Two.Events.resizeis now bound to a renderer'ssetSizefunction giving a more generic solution to change scenegraph items based on dimensions changing
December 1, 2017 v0.7.0-alpha.1
- Fixed closed
Two.Path.getPointAtmethod to clamp properly - Added
Two.Texture.repeatfor describing pattern invocations - Added
Two.Texture,Two.Sprite, andTwo.ImageSequence - Removed
Two.Shapeinheritance forTwo.Gradients - Added
Two.Vector.rotatemethod @ferm10n - Objects clone to parent only if parent exists @ferm10n
- Vendor agnostic
requestAnimationFrame@ferm10n Two.Utils.Events.listenToandTwo.Utils.Events.stopListening@ferm10nTwo.Utils.Eventsadded toTwo.Path.prototypefor event inheritance @ferm10n- Enhanced
Two.Shape.scaleto allow both numbers andTwo.Vectoras property value - Made
Two.interpretuse latest primitives - Added
Two.Circleprimitive Two.Shape.translationis now a getter/setter and can be replaced- Fixed translation interpretation to strip out
'px'strings - Removed
Two.SineRing— makeTwo.Star.curved = trueand it's the same effect - Enhanced
Two.ArcSegment,Two.Ellipse,Two.Polygon,Two.Rectangle,Two.RoundedRectangle,Two.Star - Fixed
Two.Anchor.relativeinterpretation insvg,canvas, andwebglrenderers - Made Getters / Setters enumerable for iteration compatibility
- Fixed Two.Utils.Collection.splice method and added additional test
- Added compatibility with node.js, browserify, and node-canvas
- Removed third party dependencies
- Added
removemethod toTwo.Text - Fixed ordering on same parent additions for
Two.Group
February 9, 2016 v0.6.0
- Updated
Two.CanvasRenderer.ctx.imageSmoothingEnabledto not use deprecated invocation, issue 178 - Fixed
Two.Group.maskinSVGRendererto append to DOM correctly - Updated
requireimports to be compatible with require.js - Added
Two.Textfor programmatically writing text in Two.js
October 1, 2015 v0.5.0
- Added support for
two.interpretto importsvg's gradients - Added
Two.Utils.xhrandtwo.loadmethods to asynchronously load SVG files - Added
Two.Gradient,Two.LinearGradient, andTwo.RadialGradient - Added dependency check to ensure ASM loading in environments like NPM as well as in the browser
- Properly deleted
webgltextures on removal ofTwo.Path - Added support for
two.interpretto importsvg's Elliptical Arcs - Added
Two.ArcSegmentandTwo.SineRingas new shapes invoked likeTwo.Path@chrisdelbuck - Added
Two.Line,Two.Rectangle,Two.RoundedRectangle,Two.Ellipse,Two.Polygon, andTwo.Staras new shapes invoked likeTwo.Path - Breaking: renamed
Two.PolygontoTwo.Path - Performance enhancements to
webglrenderer - Performance enhancements to
canvasrenderer Leo Koppelkamm - Enabled render ordering in
Two.Group.childrenbased on previous augmentation - Augmented
Two.Group.childrento inherit fromTwo.Collectioneffectively making it an array instead of a map Leo Koppelkamm- The map can still be accessed at
Two.Group.children.ids
- The map can still be accessed at
July 22, 2014 v0.4.0
- Updated
Two.interpretto handle polybezier path data - Added
Two.Group.maskandTwo.Polygon.clipin order to create clipping masks Two.Grouphas ownopacityproperty Leo Koppelkamm- Rendering optimizations Leo Koppelkamm
Two.noConflictnon-destructive command internally to the libraryTwo.interpretdecomposestransformattribute of source tagTwo.interprethandles item irregularities from Inkscape- Changed
Two.Identifierto use underscores instead of hyphens for dot-notation access Leo Koppelkamm - Added
Two.Group.getByIdandTwo.Group.getByClassNamemethods for convenient selection Leo Koppelkamm - Added
classListto allTwo.Shapes Leo Koppelkamm - Enabled inference of applied styles on imported svgs Leo Koppelkamm
- Added
Two.Polygon.getPointAtmethod to get coordinates on a curve/line - Added
Two.Polygon.lengthproperty andTwo.Polygon._updateLengthmethod to calculate length of curve/line - Updated
Two.Group.prototypeobservable properties onTwo.Polygon.Propertiesto ensure each property is considered unique Two.Polygon.verticesfirst and last vertex create automated control points whenTwo.Polygon.curved = true- Updated
Two.Polygon.subdividemethod to accommodateTwo.makeEllipse - Enabled
idto be properly interpreted from SVG elements @chrisdelbuck - Updated
webglrenderergetBoundingClientRectto accommodaterelativeanchors - Updated
beginningandendingto clamp to each other - Reorganized
Two.Polygon._updateandTwo.Polygon.plotin order to handlebeginningandendingproperties - Updated
Two.getComputedMatrixandTwo.Polygon.getBoundingClientRectto adhere to nested transformations - Updated
Two.Anchorto changecontrolpoints relatively by default throughanchor.relativeproperty - Updated
Two.Polygon.subdividemethod to accommodatecurved = falsecircumstances - Updated
svg,canvas, andwebglrenderers to properly reflect holes in curvedTwo.Polygons - Updated
Two.Groupclonemethod - Added
toObjectmethod toTwo.Group,Two.Polygon,Two.Anchor Two.Polygoninitializespolygon.cap = 'butt'andpolygon.join = 'miter'based on Adobe Illustrator defaultsTwo.Polygon.subdividemethod now works withTwo.Commands.movefor noncontiguous polygons- Internally update matrices on
getBoundingClientRectin order to remove the need to defer or wait for internal variables to be up-to-date - Refactor of renderers and scenegraph for performance optimization and lower memory footprint
- Relinquished internal events for flags
- Prototypical declaration of
Object.defineProperty - Added
_updateandflagResetmethods toTwo.Shape,Two.Group, andTwo.Polygon - Decoupled
canvasandwebglrenderers and are now independent - Added
_matrix.manualto override the default behavior of aTwo.Polygontransformation - Localized variables per file as much as possible to reduce Garbage Collection on runtime
October 25, 2013 v0.3.0
- Can properly pass
domElementon construction of new instance of two - Added
overdrawboolean towebglrenderer @arodic - Added support for ie9 svg interpretation @tomconroy
- Added
subdividemethod forTwo.PolygonandTwo.Group - Ensure sure that
manualproperly is set on construction ofTwo.Polygonthat it bindsTwo.Anchor.controlschange events - Added automatic High DPI support for
webglrenderer - Updated
two.interpret(svg)to handle compound paths - Added
Two.Anchorwhich represents all anchor points drawn in two.js - Modified source to not have any instances of
windowfor node use - Updated to underscore.js 1.5.1
- Added
Two.Utils.getReflectionmethod to properly get reflection's in svg interpretation - Made
Two.Vectorinherently not broadcast events and now needs to be explicity bound to in order to broadcast events, which two.js does internally for you - Created
Two.Utils.Collectionan observable array-like class thatpolygon.verticesinherit @fchasen - Added
Two.Events.insertandTwo.Events.removefor use withTwo.Utils.Collection - Properly recurses
getBoundingClientRectfor bothTwo.GroupandTwo.Polygon - Added
Two.Versionto clarify forthcoming builds - Updated hierarchy ordering of
group.childrenincanvasandwebglrenderers - Updated shallow and bidirectional
removemethod forTwo.GroupandTwo.Polygon - Added
cornermethod toTwo.GroupandTwo.Polygonallowing anchoring along the upper lefthand corner of the form - Modified
centermethod ofTwo.GroupandTwo.Polygonto not affect thetranslationproperty to stay inline withcornermethod and any future orientation and anchoring logic - Added automatic High DPI support for
canvasrenderer - Added
overdrawboolean tocanvasrenderer - Added AMD loader compatibility @thomasrudin
- Deferred
two.update();to account for canvas and webgl - Added
removeandclearmethods totwoinstance - Updated svg interpretation for
webglcontext Added matrix property to allTwo.Shape's for advanced transformations- Added
inversemethod toTwo.Matrix - Remove execution path dependency on utils/build.js @masonblier
- Added
timeDeltaproperty to everytwoinstance - Added gruntfile, package.json for more integration with
npm, and dependency free build (build/two.clean.js) @iros - Crossbrowser compatibility with
noStrokeandnoFillcommands
May 3, 2013 v0.2.0
- First alpha release
Jan 29, 2013 v0.1.0-alpha
- Proof of Concept built from Three.js