Zdog’s API consists mostly of creating and using instances of its classes.
let illo = new Zdog.Illustration({
element: '.zdog-canvas',
});
let anchor = new Zdog.Anchor({
addTo: illo,
translate: { y: 10 },
});
let rect = new Zdog.Rect({
addTo: anchor,
});
illo.updateRenderGraph();
Set initial properties with an object.
let rect = new Zdog.Rect({
addTo: illo,
width: 80,
height: 60,
rotate: { y: -2 },
color: '#E62',
});
Get and re-set properties on the returned instance.
// get option
console.log( rect.rotate.y );
// => -2
// re-set option
rect.rotate.y = 3;
Some Zdog classes inherit functionality from other classes. For example, Rect inherits from Shape and Shape inherits from Anchor. This means that Rect can use all the properties and methods from Shape and Anchor.
An item that can be added to another item, and have other items added to it.
Anchor is the super class of all item and shape classes — Shape, Group, Illustration, Rect, Ellipse, Box, etc. All items that can be added to a Zdog scene act as Anchors. All item classes can use Anchor properties and methods.
The Anchor class itself is an invisible item. Anchors are useful for collecting related shapes and transforming them together.
let anchor = new Zdog.Anchor({
// options
});
Adds item to parent item.
addTo: illo
// add anchor to illo
let anchor = new Zdog.Anchor({
addTo: illo,
});
// add triangle to anchor
let triangle = new Zdog.Shape({
addTo: anchor,
translate: { z: 40 },
// ..
});
// add circle to anchor
let circle = new Zdog.Ellipse({
addTo: anchor,
translate: { z: -40 },
// ..
});
Shapes can be added as children to other shapes. A child shape is positioned relative to its parent.
let zCircle = new Zdog.Ellipse({
addTo: illo,
translate: { z: 40 }, // z +40 from illo
// ...
});
let xRect = new Zdog.Rect({
addTo: zCircle,
translate: { x: 40 }, // x +40 from zCircle
// ...
});
let yTri = new Zdog.Polygon({
addTo: xRect,
translate: { y: -60 }, // y -60 from xRect
// ...
});
Positions the item. Set to a Vector.
translate: { x: 20, y: -40 }
// move right 20px, up 40px
Rotates the item. Set to a Vector to rotate the item around the corresponding axis.
rotate: { x: Zdog.TAU/8 }
// rotate around horizontal axis
rotate: { y: Zdog.TAU/8 }
// rotate around vertical axis
rotate: { z: Zdog.TAU/8 }
// rotate around z axis
Enlarges or shrinks item geometry. scale does not scale stroke.
Set scale with a number to set x, y, & z scales to the same value.
scale: 2
// scale up all coordinates 200%
Set scale to a Vector to set coordinate-specific scale.
scale: { x: 0.5, y: 1.5 }
// scale x 50%, y 150%
Copy an item. copy() only copies the item, not the item’s graph of descendant items. Use copyGraph() to copy the item and its graph.
// create original
let rect = new Zdog.Rect({
addTo: illo,
width: 64,
height: 64,
translate: { x: -48 },
stroke: 16,
color: '#EA0',
});
// copy
rect.copy({
// overwrite original options
translate: { x: 48 },
color: '#C25',
});
Copies item and its descendent items.
// create original
let rect = new Zdog.Rect({
// ...
});
// add child item
new Zdog.Shape({
addTo: rect,
// ...
});
// copy rect and its children
rect.copyGraph({
// overwrite original rect options
translate: { x: 48 },
color: '#C25',
});
Adds child item. addChild() is useful for moving a child item to a new parent, or creating an item without addTo.
let anchor = new Zdog.Anchor({
// ...
});
let shape = new Zdog.Shape({
// no addTo
});
// add shape to anchor
anchor.addChild( shape );
Removes child item
let shape = new Zdog.Shape({
addTo: anchor,
});
anchor.removeChild( shape );
Removes item from parent.
let shape = new Zdog.Shape({
addTo: anchor,
});
shape.remove();
Updates the items and all its graph of descendant items so they are ready for rendering. Useful for rendering without Illustration.
anchor.updateGraph();
Renders the item and all its descendant items to a <canvas> element. Useful for rendering without Illustration.
anchor.renderGraphCanvas( ctx );
ctx: CanvasRenderingContext2Dlet canvas = document.querySelector('.zdog-canvas');
let ctx = canvas.getContext('2d');
let scene = new Anchor();
// add some shapes...
scene.updateGraph();
// render on canvas
scene.renderGraphCanvas( ctx );
Renders the item and all its descendant items to an SVG element. Useful for rendering without Illustration.
anchor.renderGraphSvg( element );
element: An SVG container element like <svg> or <g>.let svg = document.querySelector('.zdog-svg');
let scene = new Anchor({...});
// add some shapes...
scene.updateGraph();
// render on SVG
scene.renderGraphSvg( svg );
Wraps-around rotate x, y, & z values between 0 and TAU.
A visible shape. Shape is the super-class for all shape classes — Rect, Ellipse, Cone, etc. All shape classes can use Shape options and methods.
Sets shape stroke and fill color. Set to any color string — hex code, rgb(), hsla(), etc. Default color: '#333'.
color: '#E62'
Renders the shape line and sets line width. Default stroke: 1.
stroke: 30
Set stroke to 0 or false to disable.
// render only fill
stroke: false,
fill: true,
Renders the inner shape area. Disabled by default fill: false.
fill: true
Closes the path from the last point back to the first. Enabled by default closed: true.
closed: false
Shows or hides shape. Does not affect child items. Enabled by default visible: true.
Shows or hides the shape when its backface is visible. Enabled by default backface: true.
Set backface: false to hide the shape when its backface is showing.
backface: false
Set backface to a color to change the shape’s color when its backface is showing.
backface: "#636"
A Vector used to determine where the front of the shape is. Useful for changing how backface works for custom Shapes. Default front: { z: 1 }.
Updates the shape path. Trigger updatePath() after you change a point on a Shape’s path, a Rect’s width or height, etc.
let triangle = new Zdog.Shape({...});
// get first path point
let trianglePoint = triangle.path[0];
let dragStartX, dragStartY;
// drag to change path point
new Zdog.Dragger({
onDragStart: function() {
dragStartX = trianglePoint.x;
dragStartY = trianglePoint.y;
},
onDragMove: function( pointer, moveX, moveY ) {
trianglePoint.x = dragStartX + moveX;
trianglePoint.y = dragStartY + moveY;
// path point changed, updatePath() to apply change
triangle.updatePath();
},
});
An item with a separated rendering order. Inherits Anchor.
Use a Group to control rendering order. Shapes will be rendered in the order they are added to the Group. Groups are useful for positioning shapes within other shapes, like windows in walls or pupils in eyes.
// render shapes in order added
var eyeGroup = new Zdog.Group({
addTo: illo,
translate: { z: 20 },
});
// eye white first
new Zdog.Ellipse({
addTo: eyeGroup,
width: 160,
height: 80,
// ...
});
// then iris
let iris = new Zdog.Ellipse({
addTo: eyeGroup,
diameter: 70,
// ...
});
// then pupil
iris.copy({
diameter: 30,
color: '#636',
});
// highlight last in front
iris.copy({
diameter: 30,
translate: { x: 15, y: -15 },
color: 'white',
});
Shows or hides group, including all child items in the group. Shape.visible only shows or hides the item. Enabled by default visible: true.
Updates the rendering order of the group’s child items.
Disabled by default updateSort: false. Group child items are rendered in the order they are added to the Group.
Tracks dragging interaction with pointer events. Illustration inherits Dragger which enables dragRotate and use of the onDrag callback functions.
The Dragger class by itself is useful for dragging interactions outside of Illustration.dragRotate or rendering without Illustration. See updatePath for another Dragger demo.
// use Dragger to rotate shapes separately
let circle = new Zdog.Ellipse({...});
let triangle = new Zdog.Shape({...});
// variables for rotation dragging
let viewRotation = new Zdog.Vector();
let dragStartRX, dragStartRY;
new Zdog.Dragger({
startElement: illo.element,
onDragStart: function() {
// highlight on drag start
circle.color = '#C25';
triangle.color = '#EA0';
// keep track of rotation
dragStartRX = viewRotation.x;
dragStartRY = viewRotation.y;
},
onDragMove: function( pointer, moveX, moveY ) {
// move rotation
let moveRX = moveY / illo.width * Zdog.TAU * -1;
let moveRY = moveX / illo.width * Zdog.TAU * -1;
viewRotation.x = dragStartRX + moveRX;
viewRotation.y = dragStartRY + moveRY;
},
onDragEnd: function() {
// remove highlight colors on drag end
circle.color = '#636';
triangle.color = '#E62';
},
});
function animate() {
// rotate shapes
circle.rotate.set( viewRotation );
triangle.rotate.set( viewRotation );
illo.updateRenderGraph();
requestAnimationFrame( animate );
}
animate();
The element to start dragging on the initial mousedown, pointerdown, or touchstart event.
// set with a selector string
startElement: '.zdog-canvas'
// set with an Element
startElement: document.querySelector('.zdog-canvas')
Callback function triggered when dragging starts with the initial mousedown, pointerdown, or touchstart event.
onDragStart: function( pointer ) {
console.log(`Drag started at ${pointer.pageX}, ${pointer.pageY});
}
pointer - the Event or Touch object with .pageX and .pageY.Callback function triggered when dragging moves with mousemove, pointermove, or touchmove event.
onDragMove: function( pointer, moveX, moveY ) {
console.log(`Drag moved ${moveX}, ${moveY}`);
}
pointer - the Event or Touch object with .pageX and .pageY.moveX - horizontal distance moved from the dragStart position.moveY - vertical distance moved from the dragStart position.Callback function triggered when dragging ends on the mouseup, pointerup, or touchend event.
onDragEnd: function() {
console.log('Drag ended');
}
Handles displaying and rotating a scene on an HTML element. Inherits both Anchor and Dragger. Illustration does several things.
Anchor, it acts as a top level item for all other items in the scene to be added to.<canvas> or an <svg>.let illo = new Zdog.Illustration({
element: '.zdog-canvas',
dragRotate: true,
});
// add shapes to Illustration
// triangle
new Zdog.Shape({
addTo: illo,
// ...
});
// circle
new Zdog.Ellipse({
addTo: illo,
// ...
});
// animate
function animate() {
illo.updateRenderGraph();
requestAnimationFrame( animate );
}
animate();
The HTML element to render on, either a <canvas> or an <svg>.
// set with a selector string
element: '.zdog-canvas'
// set with an Element
element: document.querySelector('.zdog-canvas')
Illustration requires the initial size of the element be set in its element width and height attributes.
<canvas class="zdog-canvas" width="240" height="240"></canvas>
With a <canvas> element, Illustration will increase resolution of the <canvas> for high pixel density displays.
<canvas class="zdog-canvas" width="240" height="240"></canvas>
element: '.zdog-canvas'
<svg class="zdog-svg" width="240" height="240"></svg>
element: '.zdog-svg'
As an Anchor, you can sets translate, rotate, & scale transforms on the Illustration.
Set rotate to set the initial view rotation of the scene.
rotate: { y: Zdog.TAU/8 }
// rotate 45°
Enlarges or shrinks the displayed size of the rendering. Whereas scale will change the size of item geometry, zoom changes item geometry and stroke size.
zoom: 1.5
// enlarge 150%
zoom: 0.5
// shrink to 50% size
Centers the scene in the element. Enabled by default centered: true.
centered: false
// position scene at 0,0 in top left corner
Enables dragging to rotate on an item.
With dragRotate enabled, you can then use Dragger onDrag functions: onDragStart, onDragMove, onDragEnd
Set dragRotate: true to drag-rotate the Illustration’s item graph.
let illo = new Zdog.Illustration({
dragRotate: true,
// ...
});
let circle = new Zdog.Ellipse({
addTo: illo,
// ...
});
let triangle = new Zdog.Shape({
addTo: illo,
// ...
});
Set dragRotate to an item to drag-rotate that item’s graph.
let triangle = new Zdog.Shape({...});
let illo = new Zdog.Illustration({
dragRotate: triangle,
// ...
});
illo.addChild( triangle );
let circle = new Zdog.Ellipse({
addTo: illo,
// ...
});
Enables fluid resizing of element.
With an <canvas> element, Illustration will re-set the width and height attributes to match the display size of the element for crisp pixel-perfect display.
Enable resize: true for fluid element resizing.
<!-- set initial size and aspect ratio -->
<canvas class="zdog-canvas" width="480" height="240"></canvas>
.zdog-canvas {
display: block;
width: 100%;
}
resize: true
With an <svg> element, Illustration will remove width and height attributes, so the <svg> will scale up its size proportionally, filling up the width of its parent element — similar behavior to an <img> with width: 100%.
<svg class="zdog-svg" width="480" height="240"></svg>
resize: true
Set resize: 'fullscreen' to resize the element to the size of the browser window. View fullscreen demo on CodePen.
resize: 'fullscreen'
.zdog-canvas {
width: 100%;
height: 100%;
}
For <canvas>, set 100% width and height CSS on the canvas. Zdog will scale up the canvas to match device pixel ratio. 100% width and height then scales the element back down, thus providing higher pixel density.
A function triggered when the element is resized. Required resize to be enabled.
onResize: function( width, height ) {
console.log(`Illo element is ${width} x ${height}`);
}
Use onResize to proportionally scale zoom.
resize: true,
onResize: function( width ) {
// scale zoom
this.zoom = width / 400;
},
Function triggered before rendering.
onPrerender: function( context ) {
// ...
}
context - the rendering context. For <canvas>, the CanvasRenderingContext2D. For <svg>, the <svg> element.// with <canvas>
onPrerender: function( ctx ) {
// render axis lines
ctx.fillStyle = '#EA0';
// with centered enabled, 0,0 is center of canvas
ctx.fillRect( -1, -120, 2, 240 );
ctx.fillRect( -120, -1, 240, 2 );
},
Renders an item and its graph to the Illustration’s element.
Call .renderGraph() to render the Illustration item graph.
illo.renderGraph()
Pass in an item to render that item.
illo.renderGraph( scene )
Combines updateGraph() and renderGraph() methods — to save you a line of code. Updates and renders an item and its graph to the Illustration’s element.
Call .updateRenderGraph() to render the Illustration’s item graph.
illo.updateRenderGraph()
Pass in an item to render that item.
illo.updateRenderGraph( scene )
Sets element size.
illo.setSize( width, height )
A 3D vector with x, y, and z coordinates.
Create a Vector by passing in a vector Object or another Vector.
let position = new Zdog.Vector({ x: 1, y: 0, z: 2 });
Zdog uses Vectors for position in 3D space and for rotation.
// position
let position = new Zdog.Vector({ x: 1, y: -2, z: 3 });
// => 1 right, 2 up, 3 closer
With rotation, the coordinate values are used for the angle around the respective axis.
let rotation = new Zdog.Vector({ y: Zdog.TAU/4 });
// => quarter-turn around vertical y-axis
A vector Object is a plain ol' JavaScript Object with x, y, z coordinate properties. The coordinate properties are optional. They default to 0 if undefined. So you only need to set non-zero values.
new Zdog.Vector({ x: 1, z: 2 }) // => { x: 1, y: 0, z: 2 }
new Zdog.Vector({ y: 3 }) // => { x: 0, y: 3, z: 0 }
new Zdog.Vector({}) // => { x: 0, y: 0, z: 0 }
let position = new Zdog.Vector({ x: 4 });
// => { x: 4, y: 0, z: 0 }
position.add({ y: 5 });
// => { x: 4, y: 5, z: 0 }
A vector Object is different from an instance of a Vector class.
// won't work, just an Object
{ x: 1 }.add({ y: 2 });
// will work, is a Vector
new Zdog.Vector({ x: 1 }).add({ y: 2 });
Sets x, y, z coordinates.
vec.set({ x: 1, z: 2 })
// => { x: 1, y: 0, z: 2 }
Returns a new Vector with copied x, y, and z coordinates. Most Vector methods are mutable — they change the Vector’s coordinates. Use .copy() to work with a vector while still preserving the original.
let positionA = new Zdog.Vector({ x: 1, z: 2 });
let positionB = positionA.copy();
positionB.add({ x: 3 });
// => { x: 4, y: 0, z: 2 }
positionA
// => { x: 1, y: 0, z: 2 }
Adds x, y, z coordinate values.
let position = new Zdog.Vector({ x: 1, z: 2 });
position.add({ x: 3, y: 4 });
// => { x: 4, y: 5, z: 2 }
Subtracts x, y, z coordinate values.
let position = new Zdog.Vector({ x: 1, z: 2 });
position.subtract({ x: 3, y: 4 });
// => { x: -2, y: -4, z: 2 }
Multiplies x, y, z coordinate values.
let position = new Zdog.Vector({ x: 2, z: 3 });
position.multiply({ x: 3, y: 4 z: 5 });
// => { x: 6, y: 0, z: 15 }
.multiply() can be passed a Number to multiply all coordinates by the same value.
let position = new Zdog.Vector({ x: 2, z: 3 });
position.multiply( 4 );
// => { x: 8, y: 0, z: 12 }
vector.rotate( rotation );
Rotates a position vector given a rotation vector Object.
let position = new Zdog.Vector({ x: 1, y: 2 });
// rotate 45° clockwise
position.rotate({ z: Zdog.TAU/4 });
// => { x: -2, y: 1, z: 0 }
Returns the total length of the vector.
let position = new Zdog.Vector({ x: 6, y: 8 });
let mag = position.magnitude();
// => 10
vector.lerp( point, alpha );
Linear interporlate the vector towards point, given alpha a percent between the vector and point.
let position = new Zdog.Vector({ x: 2, y: 4 });
// interpolate 75% to 6,8,0
position.lerp( { x: 6, y: 8 }, 0.75 );
// => { x: 5, y: 7, z: 0 }
Zdog includes a couple constants and methods to help with math & animation.
Zdog.TAU // => 6.28318
A full rotation in radians. Math.PI * 2. TAU is more user-friendly than PI as TAU maps directly to a full rotation.
const TAU = Zdog.TAU; // easier to read constant
rotate: { y: TAU/4 } // /4 = quarter turn
rotate: { y: TAU/2 } // /2 = half turn
rotate: { y: TAU*3 } // *3 = 3 full turns
Apply an in-out easing. Useful for animation.
let easeAlpha = Zdog.easeInOut( alpha, power );
alpha - a Number 0 to 1.power - the exponential power of the easing curve. Default 2.let ticker = 0;
let cycleCount = 150;
function animate() {
let progress = ticker / cycleCount;
// apply easing to rotation
let tween = Zdog.easeInOut( progress % 1, 3 );
illo.rotate.y = tween * Zdog.TAU;
ticker++;
illo.updateRenderGraph();
requestAnimationFrame( animate );
}
animate();
Zdog.extend( a, b )
Sets the properties of Object b on to Object a.
let optionsA = { stroke: 4, fill: true };
let optionsB = { color: '#EA0', fill: false };
Zdog.extend( optionsA, optionsB );
// optionsA = { stroke: 4, color: '#EA0', fill: false }
Zdog.lerp( a, b, alpha )
Linear interpolation between values a and b given a percent decimal alpha.
// 75% of the way between 20 and 40
Zdog.lerp( 20, 40, 0.75 );
// => 35
Zdog.modulo( a, b )
Returns modulo or "wrap around" value of a given b.
// It's 8AM now. What time will it be 18 hours from now?
let later = Zdog.modulo( 8 + 18, 24 )
// => 2, 2AM
// It's 8AM now. What time was it 15 hours ago?
let earlier = Zdog.modulo( 8 - 15, 24 )
// => 17, uh, I'm American
earlier = Zdog.modulo( earlier, 12 )
// => 5PM
// Why can't I use % operator?
earlier = ( 8 - 15 ) % 24;
// => -7, oh no. % returns remainders, which can be negative