ZIM Wrap :: JavaScript wrapper functions for fun efficiency!

CDN Links  |  Live Example  |  Docs

Examples of JavaScript Drag and Drop, Hit Tests with CreateJS and EaselJS

ZIM Wrap provides global shortcuts to common and often lengthy JavaScript commands. The file is bootstrapped by all the modules.
WRAP Examples:

// LOGGING               
// console.log() is a pain to type out
// when other languages have trace(), echo(), print(), etc.
// zog(); binds to console.log to give accurate file and line numbers
// to show the console look in Developer Tools or CTRL SHIFT I or K
zog("hello Z world"); // will display "hello world" in the console
zog(7, 80, "good"); // will display all these

// document.getElementByID() is absolutely ridiculous
// most other languages just let us use the ID
// JavaScript sort of does but for some reason it's half baked
// zid is shorter and if you want a style then use zss()

zid("tagID"); // will access the tag by ID

zss("tagID").display="none"; // will access the style property

// window.location.href() is easily forgetable
// window.open() has a mixed up format for parameters
// perhaps you will prefer zgo() for an easy link to a page

zgo("myURL"); // will open in the same window
zgo("myURL", "whatever"); // will open in a blank window

// zum() converts a pesky style string to a number
// in other languages we can animate by saying obj.x += 5;
// at least this gets us a little closer

zss("obj").left = (zum(zss("obj").left)+5)+"px"; // whatever!

// handling parameter defaults is a pain in JavaScript
// most langages let you do: function setColor(c="blue") {}
// in JavaScript we are left evaluating the parameter like so:
// if (typeof c === "undefined") c="blue";
// this is a pain for every parameter!  so check out zot();
// zot() returns true if the parameter has no value or it's value is null

if (zot(c)) c="blue"; // just a little easier to remember is it not?

// sometimes we need to stop an event from propagating
// for instance, a click on the backing opens the popup
// a click on the popup closes the popup
// we would not want the closing click to go through to the backing
// because that would close and then open the popup in one click!
// zop(e); stops the event from passing through by
// wrapping a couple lines of cross-browser code

popup.addEventListener("click", closePopup);
backing.addEventListener("click", openPopup);
function closePopup(e) {
    if (!e) e = window.event; // handle IE
    zop(e); // will stop event from going to backing
function openPopup(e) {		

// arrows, pgup, pgdown, home, end, 
// and scrollwheel default to move the page
// when in full screen, this is unwanted
// zil() will preventDefault() on these
// returns an array of three events it uses
// [keydown, mousewheel and DOMMouseScroll]

zil(); // put somewhere on your page

// after a few days, these wrappers become quite memorable
// they have fun, short names 
// we generally just stuck a z in front of the name:

// z + log   == zog
// z + id    == zid
// z + css   == zss
// z + go    == zgo
// z + num   == zum
// z + not   == zot
// z + stop  == zop
// z + still == zil

// Z + IM   == ZIM // IM == Interactive Media                    

ZIM Code :: rand code between easy and useful!

CDN Links  |  Live Example  |  Docs

ZIM Code provides a growing set of JavaScript functions that we use over and over.
CODE Examples:

// often you want to pick something randomly from a list
// one way is to make an Array and choose a random index
// a[Math.floor(Math.random()*a.length)];
// this is a little cumbersome to write
// and does not help if you want to get sequential unique values
// a better way, is to just shuffle the array
// then to get a unique value, access the first element
// if you need more then access subsequent elements
// zim.shuffle() actually changes the original array 
// it also returns the array 

var a = ["Lemur", "Leopard", "Lynx"];
zog( zim.shuffle(a)[0] ); // gets a random element
zog( a[1] ); // would get the next random element
zog( a[2] ); // would get the next random element

// Math.random() is cool but often you want a range
// it is easy enough to do some quick math
// it is easier to use zim.rand(a,b);

zog( zim.rand(10,20) ); // an integer between (and including) 10 to 20
zog( zim.rand(5) ); // an integer between (and including) 0 to 5 
zog( zim.rand() ); // a decimal between 0 and 1 (not including 1)

// Copies an array or object
// from Trindaz / gist:2234277

var a = ["moon", "sun", ["dark", "light"], {craft:"hover", price:12}];
var b = zim.copy(a);

// modified Evan Steinkerchnerv & Tomas Zato
// finds out if arrays are same (including nested arrays)
// works for arrays with strings and numbers (not necessarily other objects)
// pass in two arrays with an optional strict (default true) mode
// in not strict (strict == false) it does not matter the order

var a = [1,2,3];
var b = [1,2,3];
var c = [2,2,3];
zog("zim.arraysEqual [1,2,3], [1,2,3] : " + zim.arraysEqual(a,b) ); // true
zog("zim.arraysEqual [1,2,3], [2,2,3] : " + zim.arraysEqual(a,c) ); // false

// sometimes you want to round a decimal off to a nearest decimal place
// use zim.decimals(number, decimalPlaces);

zog( zim.decimals(1.78394, 2) ); // 1.78
zog( zim.decimals(5.99150, 1) ); // 6.0
zog( zim.decimals(5.99150, 3) ); // 5.992

// DAMPING (see ZIM Build Live Examples)
// use the zim.Damp() class to handle damping 
// damping looks more natural - things slow down and ease to a stop
// rather than make something follow the cursor directly, apply damping
// the equation is not long but can be tricky to remember
// Damp works in two steps:
// 1. set up a Damp object with a start value and damping value
// 2. convert a desired number to the dampened number in a Ticker or Interval
// damping works by continuously going part of the way to a desired value
// because of the continuous manner, you can't use it with a pressmove event
// if you want to damp in x and y you need two Damp objects
// note: Damp just works with values - you then apply the values to your objects

var damp = new zim.Damp(circle.x, .1);

var ticker = createjs.Ticker.on("tick", function() {
	circle.x = damp.convert(stage.mouseX);

// PROPORTION (see ZIM Build Live Examples)
// use the zim.Proportion() class to convert an input value (base)
// to a proportional value on another scale (target)
// for instance convert the position of a slider to a volume or a scale
// proportion requires a straight forward but lengthy equation 
// so the Proportion class makes it a little easier on us!
// Proportion has a two step process:
// 1. set up a Proportion object with its parameters
// 2. convert a base amount to a target amount 
// (usually in a Ticker or pressmove event)

// the parameters are: 
// baseMin, baseMax, targetMin, targetMax, factor, targetRound
// for a horizontal slider, baseMin is the left of the bar
// baseMax would be the right of the bar
// to handle scale, targetMin would be the minimum scale
// targetMax would be the maximum scale
// factor is 1 (default) for direct proportion (both increasing)
// factor is -1 for indirect proportion (one increasing the other decreasing)
// if you want to round the target amount
// then set the last parameter to true (default is false)
// then you adjust the slider knob (base amount) in a pressmove event 
// and use the convert() method to find the new scale (target amount)

var proportion = new zim.Proportion(0,100,1,5);

knob.on("pressmove", function() {
	zim.scale( circle, proportion.convert(knob.x) );

// PROPORTION DAMP (see ZIM Build Live Examples)
// use the zim.ProportionDamp() class to convert an input value (base)
// to a proportional value on another scale (target) with damping!
// for instance convert the position of a slider to a scale
// but as you slide the slider, the scale eases to the right scale
// this is very fluid and the height of interface elegance
// combining the two techniques gets fairly complex
// but ProportionDamp makes it easy!

// ProportionDamp has a two step process:
// 1. set up a ProportionDamp object with its parameters
// 2. convert a base amount to an eased target amount 
// use a Ticker or Interval - NOT a pressmove event (because of easing) 

// the parameters are: 
// baseMin, baseMax, targetMin, targetMax, damp, factor, targetRound
// for a horizontal slider, baseMin is the left of the bar
// baseMax would be the right of the bar
// to handle scale, targetMin would be the minimum scale
// targetMax would be the maximum scale
// damp is the easing with a default of .1
// factor is 1 (default) for direct proportion (both increasing)
// factor is -1 for indirect proportion (one increasing the other decreasing)
// if you want to round the target amount
// then set the last parameter to true (default is false)
// then you adjust the slider knob (base amount) in a Ticker event 
// and use the convert() method to find the new scale (target amount)
// this process will include damping and look very smooth

var pd = new zim.ProportionDamp(0,100,1,5,.05);

var ticker = createjs.Ticker.on("tick", function() {
	zim.scale( circle, pd.convert(knob.x) );

// amazing!    

DOM Examples:

// calculating the scroll position of a window is sometimes necessary
// zim.scrollX() and zim.scrollY() solve cross browswer issues
// just setting a timeout so we have time to scroll and test!

setTimeout(function() {zog( zim.scrollY() );}, 1000);
zim.scrollY(500,1000); // will scroll to 500 in 1 second (time optional)

// window width and height is also a touch complex for cross browser
// use zim.windowWidth() and zim.windowHeight();

zog( zim.windowWidth() );
zog( zim.windowHeight() );

// PHP and JavaScript have slightly different URL encoding/decoding
// this is important if you are not wanting single quotes for database data
// so these two zim functions match the PHP urlencode and urldecode

var string = "href = 'http://danzen.com'";

var encoded = zim.urlEncode(string); 
zog(encoded); // href+%3D+%27http%3A%2F%2Fdanzen.com%27

var decoded = zim.urlDecode(encoded);
zog(decoded); // href = 'http://danzen.com'

// here is PHP:
	echo urlencode("href = 'http://danzen.com'");
	// href+%3D+%27http%3A%2F%2Fdanzen.com%27	
	echo urldecode("href+%3D+%27http%3A%2F%2Fdanzen.com%27");
	// href = 'http://danzen.com'

// here is the JavaScript version - note, it is different:
zog( encodeURI(string) ); // href%20=%20'http://danzen.com'

// I have been using this setCookie/getCookie function for years

zim.setCookie("score", 100, 1); // sets cookie for one day
zog( zim.getCookie("score") ); // 100
// zim.deleteCookie("score"); // would remove the cookie

zim.setCookie("name", "Dan Zen"); // stores the cookie for browser session
// below will show "Dan Zen" until all browsers closed
// to test, remove the zim.setCookie() functions after you run the code once
// test the file again - the score will be there, the name will be undefined
zog( zim.getCookie("name") ); 


ZIM Create :: for an added boost to the fab CreateJS EaselJS code!

CDN Links  |  Live Example  |  Docs

ZIM Create works with the CreateJS JavaScript Library to simplify and extend complex Interactive Media tasks.
CREATE Examples:
// assuming that we have a createjs stage
// and two createjs shapes (or bitmaps, etc) called circle and square
// these could be nested inside various containers (or not)
// the code behind the zim.drag() function is quite complicated

// to set up dragging and dropping the circle we simply use:


// the circle now can be picked up and dropped repeatedly
// it will have a pointer cursor on rollover and a move cursor when moving
// you can specify a bounds rectangle as the second parameter
// this is relative to the stage.  Assuming we have stageW and stageH

var bounds = new createjs.Rectangle(0,0,stageW,stageH);
zim.drag(circle, bounds);

// this will keep the registration point of the circle inside the stage
// you could make a slider behavior like so:

var slideBounds = new createjs.Rectangle(100,100,200,0); // no y movement
zim.drag(circle, slideBounds, "pointer", "ew-resize");

// note, here we specified the cursors too
// to turn off the ability to drag we use:


// NOTE: dragging uses the event object's target property
// if you press on an object within the specified object,
// it may drag the inner object 
// (allowing you to use one drag call on a collection of objects)
// to stop you can pass in true for the currentTarget parameter
// then it will drag the whole object you put the drag() on

// there are five hit tests available in ZIM

// 1. zim.hitTestPoint(a, x, y)
// tests to see if a shape (a) is hitting a point (x, y)
// this is similar to the native hitTest() in createjs
// but it tests to see if a point on the global stage
// is hitting the shape even if the shape is
// nested, rotated, moved or has had a registration change
// makes use of globalToLocal - always tricky...

if ( zim.hitTestPoint(circle, stageW/2, stageH/2) ) {
	zog("hitting stage center");

// 2. zim.hitTestReg(a, b)
// checks to see if a shape (a) is hitting the registration point of an object (b)
// good for shapes hitting small objects.  Works even if objects are
// nested, rotated, moved or have had registration changes
// also handy for snapping (set registration point to middle)
// makes use of localToLocal - always tricky

if ( zim.hitTestReg(circle, square) ) {
	zog("hitting registration point of square");

// 3. zim.hitTestRect(a, b, num)
// checks to see if a shape (a) is hitting a number of points on a rectangle
// the second parameter (b) is an object with a getBounds() available 
// this bounds is used as the rectangle
// the third parameter (num) is how many points along each side of the rectangle
// get tested - default is 0 which tests only the corners of the rectangle
// num = 2 would test the corners and two extra points distributed on each side
// so this would be 4 + 2*4 = 12 points total
// this technique gives a good way to test a shape and rectangle
// but watch out for performance at larger numbers - usually 2 or 3 is fine
// makes use of localToLocal - always tricky

if ( zim.hitTestRect(circle, square, 2) ) {
	zog("hitting along the edge of square");

// 4. zim.hitTestCircle(a, b, num)
// checks to see if a shape (a) is hitting a number of points on a circle
// the second parameter (b) is an object with a getBounds() available 
// this bounds is used to determine the circle
// the circle diameter is set to the average of the width and height of the bounds
// the third parameter (num) is how many points around the circle
// get tested - default is 8 which tests from 0 every 45 degrees
// this technique gives a good way to test a shape and circle
// watch out for performance at larger numbers - usually 12 or so should be fine
// makes use of localToLocal - always tricky
// imagine we have a second circle, circle2:

if ( zim.hitTestCircle(circle, circle2, 12) ) {
	zog("hitting along the edge of circle");

// 5. zim.hitTestBounds(a, b, demo)
// checks if the bounds of two objects (a,b) are hitting
// so the objects must have bounds set (setBounds)
// works even if the shapes are nested, etc.
// the last parameter (demo) shows the bounds of the objects (optional)
// (demo should be an empty shape object on the stage)
// if an object is rotated, the bounds expand 
// to encompass the original bounding rectangle
// so the bounding rectangles that are tested are never rotated
// this is the like the hitTestObject method in Flash

if ( zim.hitTestBounds(circle, square) ) {
	zog("bounding rectangles of shapes are hitting");

// zim.boundsToGlobal is just a function that returns the bounds
// of an object as a rectangle on the global stage
// it is used in some of the hit tests

var globalRect = zim.boundsToGlobal(circle);

// a most annoying thing is always having to set both x and y scales
// 99% of the time these will both be the same
// so zim.scale() takes care of setting both scaleX and scaleY

zim.scale(circle, 2);

// in the age of multiples screen sizes we often want to scale to percentage
// of some bounds - like the stage
// zim.scaleTo() lets you do this based on horizontal or vertical percentage
// or both and it will take the smallest scale of the two
// here we do not scale to the x (null) but rather to the y (40%)

zim.scaleTo(circle, stage, null, 40);

// MOVE 
// use the zim.move(obj, x, y, milliseconds, ease); function to move an object
// just a little wrapper function for the createjs.Tween
// ease is optional and defaults to "quad" - use "elastic", "back", "bounce", etc.
// handles removing the Ticker when the tween is done
// use for the occasional movement as it makes a Ticker each time

circle2.on("pressup", function(){
    zim.move(circle2, 200, 500, 500);

// a wrapper for the createjs Tween class that makes and removes a Ticker
// target, obj, t, ease, callBack, params, wait
circle3.alpha = 0;
zim.animate(circle3, {alpha:1}, 1000, null, null, null,500);

// FIT
// fit an object into bounds - actually scales and moves
// obj, left, top, width, height, inside

zim.fit(square, 0, 0, w, h);

// outline is extremely handy to visualize objects
// especially with unusual bounds and registration points set	
// the rectangle shows the bounds, the circle the registration point
// and the cross shows the origin inside the object (0,0)
// use outline after the object has been added to the stage 
// and use after the object has been moved or scaled


// requires bounds to be set on the object
// but at least it shortens the following:
// obj.regX = obj.getBounds().width/2;
// obj.regY = obj.getBounds().height/2;
// also can center object on container

zim.centerReg(obj, stage);

ZIM Build :: make complex Interactive Media techniques easy!

CDN Links  |  Live Example  |  Docs

ZIM Build works with CreateJS to provide a growing list of canvas shapes, components and effects to make your building easier.
BUILD Examples:

// easy shapes that can have their color and strokes modified dynamically
// makes use of the new createjs Shape classes for redrawing commands
// the shapes are also containers so you can put things in them

// radius, fill, stroke color, stroke size
var circle = new zim.Circle(40, "black", "black", 4);

// width, height, fill, stroke color, stroke size, rounded corner size
var rectangle = new zim.Rectangle(20, 200, null, null, null, 10);
// rectangle.setStroke("yellow"); // cannot set because not set at start
// rectangle.setStrokeSize(10);	 // cannot set because not set at start
rectangle.alpha = .5;
rectangle.x = 10;
rectangle.y = 10;
rectangle.rotation = -10;

// three line lengths, fill, stroke color, stroke size, center, adjust
var triangle = new zim.Triangle(100, 100, 100, #CCC", "#444");
triangle.setStrokeSize(4); // can set as long as stroke color was initially set

// a traditional CheckBox ;-)
// label can just be text or can supply a ZIM Label
// ZIM Label object lets you customize labels of buttons, panes, checkboxes and radio buttons

// labelText, fontSize, font, textColor, textRollColor, shadowColor, shadowBlur
var label = new zim.Label("OPTIONS", 32, "verdana", "#222", "#C60");

// size, label, startChecked, color, margin
var checkBox = new zim.CheckBox(40, label, false, "#222222");
checkBox.x = 450; checkBox.y = 470;
checkBox.on("change", function(e) {
    zog(e.target.label.text, e.target.checked, e.target.label);
    // can use text or checked to figure out what to do

// A horizontal or vertical set of radio buttons
// size, buttonData, vertical, color, spacing, margin
// buttonData can also have more information:
// [{label:ZIM Label or text, id:optional id, selected:optional Boolean}, {etc...}]

var radio = new zim.RadioButtons(40, ["OFF", "MID", "MAX"], false, "#222222");
radio.x = 450; radio.y = 540;	
radio.on("change", function(e) {
    zog(e.target.text, e.target.selectedIndex, e.target.selected, e.target.label);

// use the zim.Button() class to make a button with rollovers
// requires stage.enableMouseOver(10); // for rollover
// requires createjs.Touch.enable(stage,true); // for mobile
// the following parameters are available (all are optional)

// width, height, label, 
// backingColor, backingRollColor, borderColor, borderThickness,
// corner, shadowColor, shadowBlur

// label is a reference to a ZIM Label object (or text for a default label)
// corner is the corner radius (default 20)
// shadow color defaults to # is a blur of the drop shadow (default 16)

var button = new zim.Button(300, 80, "Try Button");
button.on("click", function() {zog("Button Pressed");});

// extends a createjs.Container
// adds a little animated three dot wait widget
// var waiter = new zim.Waiter(parameters);
// you need to call the waiter.show() to show the waiter and waiter.hide() to hide it
// you do not need to add it to the stage - it adds itself centered
// you can change the x and y (with origin and registration point in middle)
// pass in the stage and speed in ms for the cycle time (default 600ms)
// pass in backing color and dot color
// corner is the corner radius default 14
// color and value for shadow blur - 0 for no shadow
// we will waiter.show() and waiter.hide() below as we open the pane

var waiter = new zim.Waiter(stage);

// use the zim.Pane() class to make a pop panel
// Pane extends createjs container so you can add objects to it
// the following are parameters:
// stage, width, height, color, drag, resets, modal, corner
// we center on the stage by default
// the panel is also added to the stage with the show() method
// and removed from the stage with the hide() method
// label is a reference to a ZIM Label object (or text for a default label)
// drag is a boolean that defaults to false - set to true to drag
// drag is limited to the stage
// resets is a boolean defaulting to false that if set to true
// makes it so the pane always starts at the start position on opening
// the modal parameter defaults to true so you can't click off the pane
// without the pane closing. if you set the modal to false
// then you must close the pane manually with hide()
// corner is the corner radius (default 20)
// backingAlpha defaults to .14 - you can set it to 0 if you want

var pane = new zim.Pane(stage, 600, 200, null, "white", true, true, true, 20, .3);
button.on("click", function() {
    // demonstrate the waiter
    setTimeout(function() {
    }, 1500);
}); // clicking off pane will close it

// use the zim.Stepper() class to step through numbers or string options
// stepper has two arrows that can be set above and below or next to the field
// see the docs for all the parameters including size, color, label, etc.

var stepper = new zim.Stepper([1,2,3,4,5]);
stepper.on("change", function(e) {
	zog(e.target.currentIndex, e.target.currentValue);	

// note:
// the parallax class has changed signature in ZIM 1.5
// this is to additionally handle window scroll input and custom input
// the old signature looked like this for the layers:
// var layers = [[person, 200, 0], [trees, 150, 0], [backing, 100, 0]];
// the new signature is below:

// use the zim.Parallax() class to set up a parallax scene with layers
// the parameters are stage, damp, layers, auto (allows custom input)
// Parallax can use the mouse position on the stage to change layer properties
// or it can use the window scroll to change layer properties
// any properties can be changed - common are x, y, alpha, scaleX, scaleY, rotation
// Parallax also gives two convenience properties: scale and frame

// for traditional mouse movement adjusting movement on layers
// things closer should move more so provide a larger layer distance
// things farther should move less so provide a smaller layer distance
// see the live example

// for window scroll adjusting properties, see http://zimjs.com/code/parallax.html

// use the dispose() method to stop the inner parallax events
// any objects you need, you must add to the stage and remove when not needed
// Parallax uses the zim.ProportionDamp() class 
// and automatically adds damping (default=.1) 
// assuming you have person, trees and backing objects
// this will move the person 200 pixels when the cursor moves from 0 to stageW
// the distance is automatically centered on the start x position (with mouseX input) 

var layers = [
    {obj:person,  prop:"x", propChange:200},
    {obj:trees,   prop:"x", propChange:150},
    {obj:backing, prop:"x", propChange:100}
var scene = new zim.Parallax(stage, .05, layers);

// alternatively, you can use the addLayer() method:
// there is also a removeLayer(index) method

scene.addLayer({obj:birds, property:"x", propChange:170});

// the above defaults to using the mouseX relative to the stageW
// here is an example that specifies all the layer properties


// this would move ufo 200 pixels in y between a window scroll in y of 100 and 200
// because the factor is -1 the ufo would start 200 from its initial position
// and then animate back to the initial position when the window scroll is 200
// very complex and wonderful animations can be created see http://danzen.com/holiday2015

// use the zim.Scroller() class to 
// create a horizontal or vertical animated looping background
// dynamically set the speed and direction 
// that is, if the scroller is horizontal you can set left or right
// if the scroller is vertical you can set up or down
// the parameters are backing1, backing2, speed, direction, horizontal
// backing1 and backing2 are copies of the same background object
// horizontal is a boolean that defaults to true 
// once you create a Scroller you cannot change its orientation
// but you can use the dispose() method and make a new one
// assuming you have forest1 and forest2 objects that are exact copies
// (Scroller swaps the backgrounds so they need to be the same)

var scene = new zim.Scroller(forest1, forest2, 5, 1, true);
scene.speed = 10; // scroller goes faster (should ease - version 2 ;-)
scene.direction = -1 // scene reverses direction 


ZIM Pages :: layout and control pages with mobile in mind!

CDN Links  |  Live Example  |  Docs

ZIM Pages is a light JavaScript framework that works with CreateJS to lay out flexive (responsive and adaptive) pages and control navigation and interface from one place:
PAGES Examples:


// guides can be horizontal or vertical (use only one per direction)
// the guides are dragable
// a matching text field tells you the distance from the cursor to the guide
// use this to measure distances in either pixels or percents (P Key)
// you can hide and show the guides with the G key
// (or assign your own keys instead of P and G)

var guide = new zim.Guide(stage); // defaults to vertical guide

var guideManager = new zim.GuideManager();

// you can update all guides to fit scaled pages
// so this would go down in your resize function

// grids let you overlay the page with a percentage or pixel grid
// you can toggle these with the P key
// you can hide and show the grid with the G key
// you can have both grids and guides on the same page if desired
// (or assign your own keys)

var grid = new zim.Grid(stage); // percentage grid on whole stage

var gridManager = new zim.GridManager();

// add a pixel grid to the content object and make it white
gridManager.add(new zim.Grid(content, "white", false));

// now you can update all grids to fit scaled pages
// so this would go down in your resize function

// capture swipe events - used by Pages objects as will be seen

var swipe = new zim.Swipe();
swipe.on("swipe", function() {
	zog(e.target.direction, e.target.obj); // left, right, up or down and swiped object

// layout = new zim.Layout(holder, regions, lastMargin, backgroundColor, vertical, regionShape, scalingObject)
// arranges objects on the page by fitting them in regions
// make a layout object for each page if desired
// and even nest layout objects inside regions
// good for flexive design where you anchor titles and navigation
// handles any number of regions vertically or horizontally
// pass in a holder object (stage, container, etc) that must have bounds set
// the bounds will constrain the layout
// pass in an array of region objects with specific properties for each
// these differ slightly for horizontal or vertical - see documentation
// lastMargin - the margin at the bottom (vertical) or at the right (horizontal) defaults to 0
// backgroundColor - for the whole holder - defaults to ""
// vertical - boolean defaults to true for vertical layout (set to false for horizontal)
// regionShape - a createjs Shape object to show where bounds are (optional) (added to holder)
// can toggle on and off with B key - but must pass in the Shape to use the B key
// scalingTarget - an object used as the bounds of the region scaling
// setting a scalingTarget will also set the bounds of the holder to the scalingTarget bounds
// it does not scale the holder - only scales the region objects inside
// hideKey defaults to B but you can pass in a different key if you want as parameter

var top = {object:title, marginTop:5, maxWidth:80, minHeight:10, align:"left", valign:"top"};
var middle = {object:content, marginTop:5, maxWidth:100, align:"middle", valign:"middle", backgroundColor:"purple"};
var middle2 = {object:content2, marginTop:5, maxWidth:50, align:"middle", valign:"middle", backgroundColor:"grey"};
var bottom = {object:nav, marginTop:5, maxWidth:80, height:10, minHeight:10, align:"right", valign:"bottom"};

var layout = new zim.Layout(holder, [top, middle, bottom], 5, "#ddd", true, shape, stage);
layout.resize(); // when you need it - or use zim.LayoutManager below:

// add the layouts to a LayoutManager object to control from one place

var layoutManager = new zim.LayoutManager();

// in the resizing function call

// when done with bounds and app is finished
layoutManager.dispose(); // will keep layouts but remove all bound shapes and key events

// to organize all your pages and page navigation use a Pages object
// this will let you specify which page goes to which and transitions between pages
// swipes are handled automatically
// click events can be handled with ZIM HotSpots() and the Pages go() method
// here we have three pages each containers with a name property set
// the swipe array represents the pages on the left, right, top and bottom of the current page

var pages = new zim.Pages(stage,[
    {page:home, swipe:[null,"info",hide,find]},
    {page:hide, swipe:[null,null,null,home]},
    {page:find, swipe:[null,null,home,null]}
], "slide", 200); // "reveal" // "fade" // "black" // "white" // default is "instant"

pages.on("page", function(e) {			
    // this is the automatic paging system
    // sometimes extra things have to happen and you can handle them here    
    zog(e.target.page.name, e.target.lastPage.name, e.target.direction);

// most page swipes go to other pages but you can specify a string
// and it will call an event like the info above calling below:
pages.on("info", function(e) {

// More Features:
// Pages can specify a big grid - or they can be nested for hierarchical navigation
// you can set pages active or inactive
// there are two ways to override the transitions
// swipe event and pause() unpause() methods to handle data before transitioning
// see the Pages live example that shows a full system in place

// HotSpots are like image maps - you can specify clickable areas (rectangles)
// or specify an object like a shape, text, container, ZIM Button, etc.
// then you can control the events of these from one location
// you can tie them in with the ZIM Pages go() method to handle press navigation
// see the Pages live example that shows a full system in place

var hs = new zim.HotSpots([
    {page:home, rect:[190,50,260,260], 	call:function() {pages.go(hide,"up");}},
    {page:home, rect:[70,405,500,150], 	call:function() {zog("info");}},
    {page:home, rect:[190,650,260,260],	call:function() {pages.go(find,"down");}},
    {page:hide, rect:[70,800,500,150],	call:function() {pages.go(home,"down");}},
    {page:find, rect:[70,10,500,150],	call:function() {pages.go(home,"up");}},
    {page:fp.intro, rect:fp.introNext,	call:function() {findPages.go(fp.story,"right");}},
    {page:fp.intro, rect:fp.introBack,	call:function() {findPages.go(fp.code,"left");}}
]); // etc

// a class to make a single hotSpot - used by ZIM HotSpots