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 Anchor
s. 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 Shape
s. 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
. Group
s 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 Vector
s 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