API

Classes

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();

Properties

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;

Inheritance

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.

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
});

addTo

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
  // ...
});

translate

Positions the item. Set to a Vector.

translate: { x: 20, y: -40 }
// move right 20px, up 40px

rotate

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

scale

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()

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',
});

copyGraph()

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',
});

addChild()

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 );

removeChild()

Removes child item

let shape = new Zdog.Shape({
  addTo: anchor,
});

anchor.removeChild( shape );

remove()

Removes item from parent.

let shape = new Zdog.Shape({
  addTo: anchor,
});

shape.remove();

updateGraph()

Updates the items and all its graph of descendant items so they are ready for rendering. Useful for rendering without Illustration.

anchor.updateGraph();

renderGraphCanvas()

Renders the item and all its descendant items to a <canvas> element. Useful for rendering without Illustration.

anchor.renderGraphCanvas( ctx );
let 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 );

renderGraphSvg()

Renders the item and all its descendant items to an SVG element. Useful for rendering without Illustration.

anchor.renderGraphSvg( element );
let svg = document.querySelector('.zdog-svg');

let scene = new Anchor({...});
// add some shapes...

scene.updateGraph();
// render on SVG
scene.renderGraphSvg( svg );

normalizeRotate()

Wraps-around rotate x, y, & z values between 0 and TAU.

Shape

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.

color

Sets shape stroke and fill color. Set to any color string — hex code, rgb(), hsla(), etc. Default color: '#333'.

stroke

Renders the shape line and sets line width. Default stroke: 1.

Set stroke to 0 or false to disable.

// render only fill
stroke: false,
fill: true,

fill

Renders the inner shape area. Disabled by default fill: false.

closed

Closes the path from the last point back to the first. Enabled by default closed: true.

visible

Shows or hides shape. Does not affect child items. Enabled by default visible: true.

backface

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.

Set backface to a color to change the shape’s color when its backface is showing.

front

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 }.

updatePath()

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();
  },
});

Group

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',
});

visible

Shows or hides group, including all child items in the group. Shape.visible only shows or hides the item. Enabled by default visible: true.

updateSort

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.

Dragger

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();

startElement

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')

onDragStart

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});
}

onDragMove

Callback function triggered when dragging moves with mousemove, pointermove, or touchmove event.

onDragMove: function( pointer, moveX, moveY ) {
  console.log(`Drag moved ${moveX}, ${moveY}`);
}

onDragEnd

Callback function triggered when dragging ends on the mouseup, pointerup, or touchend event.

onDragEnd: function() {
  console.log('Drag ended');
}

Illustration

Handles displaying and rotating a scene on an HTML element. Inherits both Anchor and Dragger. Illustration does several things.

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();

element

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'

translate, rotate, & scale

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°

zoom

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

centered

Centers the scene in the element. Enabled by default centered: true.

centered: false
// position scene at 0,0 in top left corner

dragRotate

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,
  // ...
});

resize

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.

onResize

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;
},

onPrerender

Function triggered before rendering.

onPrerender: function( context ) {
  // ...
}
// 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 );
},

renderGraph()

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 )

updateRenderGraph()

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 )

setSize()

Sets element size.

illo.setSize( width, height )

Vector

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

Vector Objects

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 });

set()

Sets x, y, z coordinates.

vec.set({ x: 1, z: 2 })
// => { x: 1, y: 0, z: 2 }

copy()

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 }

add()

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 }

subtract()

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 }

multiply()

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 }

rotate()

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 }

magnitude()

Returns the total length of the vector.

let position = new Zdog.Vector({ x: 6, y: 8 });
let mag = position.magnitude();
// => 10

lerp()

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 }

Utilities

Zdog includes a couple constants and methods to help with math & animation.

TAU

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

easeInOut()

Apply an in-out easing. Useful for animation.

let easeAlpha = Zdog.easeInOut( alpha, power );
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();

extend()

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 }

lerp()

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

modulo()

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