DAN ZEN EXPO - CODE EXHIBIT -
ZIM PAGES
// ------------------ START APP ------------------
var data; // no data in this app - but include a light template for demonstration
var hLayoutManager; // organizes resizing
var vLayoutManager;
var hP; // object with all page layouts (hP = horizontal, vP = vertical)
var vP;
var hPages; // Pages object that controls directs transitions and swipes
var vPages;
var gridManager;
var guideManager;
var lastOrientation; // remember for orientation change
function pages() {
zog("hi from Pages");
// PART 1 - DATA (MODEL.JS) & INIT
// app is the namespace set out for the current application
// see the model.js for an example
// NOTE: would really put the data call up in the init function
// but wanted to separate from template for demonstration
data = new app.Data(); // in model.js - go get initial data
// pages will have assets positioned with ZIM Layout objects
// these can be stored and managed with LayoutManagers
hLayoutManager = new zim.LayoutManager();
vLayoutManager = new zim.LayoutManager();
// grids show either percentage or pixel lines to help layout
// sometimes we might want specific grids for scaled content regions
// these can be stored and managed with the GridManager
gridManager = new zim.GridManager();
// guides show a horizontal or vertical dragable line
// then a text field shows the distance of your cursor from the line
// handy for measuring the distance between things in percent or pixels
// these can be stored and managed with the GuideManager
guideManager = new zim.GuideManager();
// PART 1 - LAYOUT PAGES - VIEW.JS
// call remote js function to layout assets on pages
// function will return an object with all pages
// each page has parts like logos, content and navigation
hP = app.hLayouts(hLayoutManager, gridManager, guideManager, data);
vP = app.vLayouts(vLayoutManager, gridManager, guideManager, data);
// PART 2 - CREATE GENERAL NAVIGATION
// could have made the pages work exactly like a grid
// but made it so when you travel from section to section
// it always starts at the first page of the section
// ASIDE
// you can also nest Pages objects as I did in the Pieces app
// there, you go up to a hide section and then across the hide pages
// when you go down it always goes to the main menu
// but when you go up again, you are taken to the hide page you were in
// there is also a find section below the main menu that works the same way
// swipe directions are a little tricky
// because they are opposite to the side the page is on
// I tend to view where the pages are rather than the swipe directions
// so any directions you see in the PageManager and HotSpots, etc.
// are the directions to the side the new page is on
// for instance, below the swipe directions would be right, left, down, up
// but I think of it as the page on the left, right, top and bottom
// in general, it is two pairs of back and forward directions
// if we are on pages1 then there are no pages to the left
// there is the new section (layout) to the right
// there are no pages above and pages2 is below (east, west, north, south)
// it is the same way for horizontal and vertical pages
// but possibly the pages you go to will switch around as in this example
// probably would not recommend doing that
// but I wanted to demonstrate different directions ;-)
hPages = new zim.Pages(stage,[
{page:hP.pages1, swipe:[null, hP.layout1, null, hP.pages2]},
{page:hP.pages2, swipe:[null, hP.layout1, hP.pages1, hP.pages3]},
{page:hP.pages3, swipe:[null, hP.layout1, hP.pages2, null]},
{page:hP.layout1, swipe:[hP.pages1, hP.grid1, null, hP.layout2]},
{page:hP.layout2, swipe:[hP.pages1, hP.grid1, hP.layout1, hP.layout3]},
{page:hP.layout3, swipe:[hP.pages1, hP.grid1, hP.layout2, null]},
{page:hP.grid1, swipe:[hP.layout1, hP.guide1, null, hP.grid2]},
{page:hP.grid2, swipe:[hP.layout1, hP.guide1, hP.grid1, hP.grid3]},
{page:hP.grid3, swipe:[hP.layout1, hP.guide1, hP.grid2, null]},
{page:hP.guide1, swipe:[hP.grid1, null, null, hP.guide2]},
{page:hP.guide2, swipe:[hP.grid1, null, hP.guide1, hP.guide3]},
{page:hP.guide3, swipe:[hP.grid1, null, hP.guide2, null]}
], "slide", 500);
// transition options are: "reveal", "slide", "fade", "black", "white" or the default: "none"
// example of overriding transition for certain page changes
/* hPages.transitionTable = [
[hP.grid1,hP.grid2,"none"],[hP.grid2,hP.grid1,"none"],
[hP.grid2,hP.grid3,"none"],[hP.grid3,hP.grid2,"none"]
];*/
// you can also set an overoverriding transition on a go() method
// stage.addChild(hPages); // to test
// hPages.go(hP.layout1, "right", "black", 1000);
// stage.update(); return;
// pages are actually added to the pages object (a createjs.Container)
// so to see them you would addChild - we will do that in the resizing function
// NOTE: pages are added to stage when needed by the Pages object
// if you need your pages added to the stage to do some behind the scene operations
// you can call the puff() method and it will add the pages to the stage
// behind the main page and then call the puffed event when the ms time has elapsed
// or you can pass no time and manually call the settle() function
// which will remove the pages behind the main page
// pages.puff(200);
// pages.on("puffed", function() {zog("puffed");});
// MAKE VERTICAL PAGES OBJECT
// probably could have coded the two pages objects in a function with a lookup table
// like we did for the hotSpots below - but will just leave it like this for demonstration
vPages = new zim.Pages(stage,[
{page:vP.pages1, swipe:[null, vP.pages2, null, vP.layout1]},
{page:vP.pages2, swipe:[vP.pages1, vP.pages3, null, vP.layout1]},
{page:vP.pages3, swipe:[vP.pages2, null, null, vP.layout1]},
{page:vP.layout1, swipe:[null, vP.layout2, vP.pages1, vP.grid1]},
{page:vP.layout2, swipe:[vP.layout1, vP.layout3, vP.pages1, vP.grid1]},
{page:vP.layout3, swipe:[vP.layout2, null, vP.pages1, vP.grid1]},
{page:vP.grid1, swipe:[null, vP.grid2, vP.layout1, vP.guide1]},
{page:vP.grid2, swipe:[vP.grid1, vP.grid3, vP.layout1, vP.guide1]},
{page:vP.grid3, swipe:[vP.grid2, null, vP.layout1, vP.guide1]},
{page:vP.guide1, swipe:[null, vP.guide2, vP.grid1, null]},
{page:vP.guide2, swipe:[vP.guide1, vP.guide3, vP.grid1, null]},
{page:vP.guide3, swipe:[vP.guide2, null, vP.grid1, null]}
], "slide", 500);
// this event triggers whenever a page is changed
vPages.on("page", function(e) {
// zog(e.target.page.name, e.target.lastPage.name, e.target.direction, e.target.fromSwipe);
});
// just thought I would remind people that they can swipe (for demonstration purposes)
var pageTally=0;
var swipeWarn=3;
var onTransH = hPages.on("pageTransitioned", function(e) {
doTally(e.target.fromSwipe); // will be true if swipe or false of click
});
var onTransV = vPages.on("pageTransitioned", function(e) {doTally(e.target.fromSwipe);});
function doTally(fromSwipe) {
if (fromSwipe) {
removeTest(); return;
}
pageTally++;
if (pageTally==swipeWarn) {
removeTest();
// labelText, fontSize, font, textColor, textRollColor, shadowColor, shadowBlur
var label = new zim.Label("TRY SWIPING", 40, "verdana", "#eeeeee");
// stage, width, height, label, color, drag, resets, modal, corner, backingAlpha, shadowColor, shadowBlur - sigh
var pane = new zim.Pane(stage, 400, 140, label, "#666666", null, null, null, null, .4, null, 0);
pane.addChild(suggest);
zim.fit(pane, -stageW/5,-stageH/5,stageW/2.5,stageH/2.5);
pane.show();
setTimeout(function() {pane.hide();}, 1500);
}
}
function removeTest() {
hPages.off("pageTransitioned", onTransH);
vPages.off("pageTransitioned", onTransV);
}
// PART 3 - ADD HOTSPOTS - CONTROLLER.JS
// this handles all press navigation and interface
// make a ZIM Waiter object to show page is loading
// the controller will waiter.show() and waiter.hide() as needed
var waiter = new zim.Waiter(stage); // other parameters available
hHS = app.hotSpots(hP, hPages, data, waiter, "horizontal");
vHS = app.hotSpots(vP, vPages, data, waiter, "vertical");
// if you want to combine swipe events with hotSpot events, here is how:
// you can capture the swipe event and check data before changing pages
// say we want to check for data going from pages1 to layout1
// we want to do this if we swipe or press on the hotSpot
// so capture the swipe on the Pages object
// and call the same function the HotSpots object uses
hPages.hotSpots = hHS;
vPages.hotSpots = vHS; // rockin' the vHS!
hPages.on("swipe", useHotSpotFunctions);
vPages.on("swipe", useHotSpotFunctions);
function useHotSpotFunctions(e) {
var p = e.target;
if (!p.nextPage) return; // swiping to no page
if (p.page.name == "pages1" && p.nextPage.name == "layout1") {
p.pause(); // pause the transition to wait for the data
p.hotSpots.checkDataExample(p.page, p.nextPage, p.direction);
}
}
// hHS.show(); // previews the hotSpots
// gridManager.add(new zim.Grid(stage, "white", true)); // used in testing
appReady = true;
sizeCanvas();
stage.update();
}
// PART 4 - HANDLE STAGE SIZE CHANGE
// resize layoutManagers, gridManagers, pages
// handle orientation changes by disabling and enabling layoutManagers and pages
var suggest; var tallyK=0;
function resizing() { // called from the template sizeCanvas() (make sure ready)
if (!appReady) return;
// if orientation change then swap Pages objects
// puff new pages and resize before puff settles ;-)
if (appOrientation != lastOrientation) {
lastOrientation = appOrientation;
if (appOrientation == "horizontal") {
if (hLayoutManager) {
// disable the old
stage.removeChild(vPages);
vPages.disable(); // no swipe calls
vLayoutManager.disable();
// enable the new
stage.addChild(hPages);
hPages.enable();
// match pages via page names
hPages.go(hP[vPages.page.name],null,"none");
hLayoutManager.enable();
hLayoutManager.resize();
}
} else {
if (vLayoutManager) {
// disable the old
stage.removeChild(hPages);
hPages.disable(); // no swipe calls
hLayoutManager.disable();
// enable the new
stage.addChild(vPages);
vPages.enable();
// match pages via page names
vPages.go(vP[hPages.page.name],null,"none");
vLayoutManager.enable();
vLayoutManager.resize();
}
}
} else {
if (appOrientation == "horizontal") {
if (hLayoutManager) hLayoutManager.resize();
} else {
if (vLayoutManager) vLayoutManager.resize();
}
}
if (appOrientation == "horizontal") {
if (hPages) hPages.resize(); // for transitions
} else {
if (vPages) vPages.resize();
}
if (gridManager) gridManager.resize();
if (guideManager) guideManager.resize();
if (stage) stage.update();
}
// in the model.js file:
var app = function(app) {
app.Data = function () {
zog("hi from Data");
var that = this; // give access to object inside functions
firstData();
function firstData() {
// call AJAX go and get some data
// can dispatch an event (using fake delay - take this out)
setTimeout(function() {
that.dispatchEvent("data");
}, 500);
// or set a ready state
that.ready = true;
that.hSubtitles = [
"ZIM PAGES CLASS","ZIM LAYOUT CLASS","ZIM GRID CLASS","ZIM GUIDE CLASS",
"CENTRAL NAVIGATION","FLEXIVE HORIZONTAL / VERTICAL","PERCENT AND PIXELS (P KEY)","MOVE AND MEASURE",
"SWIPES AND HOTSPOTS","MAX, MIN, MARGIN, ALIGN","HIDE / SHOW (G KEY), NEST","P AND G KEYS"
];
that.vSubtitles = [
"ZIM PAGES CLASS","ZIM LAYOUT CLASS","ZIM GRID CLASS","ZIM GUIDE CLASS",
"CENTRAL NAVIGATION","FLEXIVE\nHORIZONTAL / VERTICAL","PERCENT / PIXELS\n(P KEY)","MOVE AND\nMEASURE",
"SWIPES AND HOTSPOTS","MAX, MIN,\nMARGIN, ALIGN","HIDE / SHOW\n(G KEY), NEST","P AND G KEYS"
];
}
// make methods for later access from controller
this.getData = function(p, d) {
// go get some more data with AJAX
that.result = {};
that.result.message = "more data";
that.result.page = p;
that.result.direction = d;
// dispatch and event when ready (using fake delay - take this out)
var counter=0;
setTimeout(function() {
counter++;
that.dispatchEvent("result");
}, 1000);
}
// etc.
}
app.Data.prototype = new createjs.EventDispatcher();
app.Data.prototype.constructor = app.Data;
return app;
} (app || {});
// in the view.js file:
var app = function(app) {
app.hLayouts = function (hLayoutManager, gridManager, guideManager, data) {
// HORIZONTAL LAYOUTS
// all the page layouts are stored in containers with name properties
// add any properties we want in the main file to the p object
// otherwise keep variables local
// will make demonstration page (pages1) and then loop to make other pages
// NOTE - there are FAKE TABS below to show nesting of content
// this is the first time I have done this - might not want to use for real
// as, of course, nesting is used for blocks of code in {} traditionally
var p = {};
// MAKE SAMPLE PAGE
p.pages1 = new createjs.Container();
p.pages1.name = "pages1";
p.pages1.setBounds(0,0,stageW,stageH);
// fake tab to remind us that assets below are in p.pages1
// make the logo, content and nav sections for the horizontal layout of pages1
// we will need to access the logo later for ZIM HotSpots
// so store it in the p object that gets returned to the main JS page
// and we will have one for each page so store it as a property of the page
var logo = p.pages1.logo = makeLogo();
logo.setBounds(0,0,200,500);
p.pages1.addChild(logo);
// as we build, we can see bounds if needed to debug (comment when done)
// we use the bounds to help fine tune the layout - play around with it to see how
// zim.outline(logo, new createjs.Shape());
// prepare the content region and give it specific bounds
// which will lock in the aspect ratio of the content
// the content will float in the middle, controlled by the horizontal layout
var content = p.pages1.content = new createjs.Container();
content.setBounds(0,0,600,700);
var b = new createjs.Shape();
b.graphics.f("black").r(0,0,600,701); // extra pixel for transition help
content.addChild(b);
p.pages1.addChild(content);
// fake tab to remind us these things are inside content
var text = new createjs.Container();
text.setBounds(0,0,300,140);
content.addChild(text);
// fake tab to remind us that t is inside the container text
// note, with custom fonts, I have found you must use "left"
// because Chrome has a radically different bounding box
// normal fonts, all seems good to use center and middle
var t = new createjs.Text("PAGES", "70px verdana", "#eeeeee");
t.textAlign = "center";
t.textBaseline = "middle";
t.x = text.getBounds().width/2;
t.y = text.getBounds().height/2-20;
text.addChild(t);
var t2 = new createjs.Text("ZIM PAGES CLASS", "30px verdana", "#d1a170");
t2.textAlign = "center";
t2.textBaseline = "middle";
t2.x = text.getBounds().width/2;
t2.y = text.getBounds().height/2+50;
text.addChild(t2);
// will need to access buttons so store them in the p object
// will have arrows for each page so store them on the page itself
p.pages1.upArrow = makeArrow(0);
content.addChild(p.pages1.upArrow);
p.pages1.downArrow = makeArrow(180);
content.addChild(p.pages1.downArrow);
var nav = p.pages1.nav = makeNav("LAYOUT");
p.pages1.addChild(nav);
// zim.outline(nav, new createjs.Shape()); // used in testing
// step 1 is to make this page so we want to view it
// step 2 is to put the pages into a ZIM Pages object so no longer need this
//stage.addChild(p.pages1);
// VERTICAL LAYOUT
// layout the content region with a vertical ZIM Layout object
// this layout has a fixed aspect ratio based on the content's bounding box
// so here, we use Layout to conveniently position (not to flex scale)
// in other words, we could have just hard coded these positions
// in that case, we could have used a ZIM Grid
// here is a grid - uncomment and use G key to toggle or P key for percent/pixels
// gridManager.add(new zim.Grid(content, "lime", false)); // check it out!
// we add the layout to the layoutManager for centralized updating, etc.
// vertical alignment defaults to top, middle and bottom for the three regions
// we pass in a shape if we want to see the bounds
// use the B key to toggle the bounds
p.pages1.contentLayout = new zim.Layout(content,
[{object:p.pages1.upArrow, minHeight:20, marginTop:5, maxWidth:25},
{object:text, marginTop:10, maxWidth:45},
{object:p.pages1.downArrow, minHeight:20, marginTop:10, maxWidth:25}],
5, null, true, new createjs.Shape());
hLayoutManager.add(p.pages1.contentLayout);
// HORIZONTAL LAYOUT
// layout the outer page in a horizontal layout
// set the stage as the bounds because the stage is what is scaling
// here we use Layout to flex scale (alignment, max and min)
// horizontal alignment defaults are left, middle, right for the three regions
// they are added here so you can see the format
// note: the bounds are drawn into the first object (stage below)
// unless you add a bounds-shape target object at the end (p.pages1)
// so now, when we hide the page, the bounds will hide too
// bound shapes are optional but handy when building
// you can toggle them with B but also remove them when done using the layoutManager
p.pages1.layout = new zim.Layout(p.pages1,
[{object:logo, marginLeft:2, maxHeight:85, minWidth:10, valign:"top", align:"left"},
{object:content, marginLeft:2, maxHeight:100, align:"middle", valign:"middle", backgroundColor:"#333"},
{object:nav, marginLeft:2, maxHeight:55, minWidth:10, valign:"middle", align:"right"}],
2, "#d1a170", false, new createjs.Shape(), stage);
hLayoutManager.add(p.pages1.layout);
// wanted to see the layouts when developing
// and wanted to show the code on how to pass in a shape and target as last parameters
// but do not want to show layout on first page - only the layout pages
// so... will remove the layout shapes here
p.pages1.layout.removeShape();
p.pages1.contentLayout.removeShape();
// CONVENIENCE FUNCTIONS
function makeLogo() {
var logo = new createjs.Container();
var circle = zimCircle();
logo.addChild(circle);
return logo;
}
function zimCircle() {
var colors = ["#f58e25","#acd241", "#e472c4", "#50c4b7 ", "#d1a170", "#222222"];
var c = new createjs.Shape();
var g = c.graphics;
c.radius = 100;
for (var i=0; i<colors.length; i++) {
g.f(colors[i]).dc(0,0,(c.radius/colors.length)*(colors.length-i));
}
c.setBounds(-c.radius,-c.radius,c.radius*2,c.radius*2);
c.regX = -c.radius; c.regY = -c.radius;
return c;
}
function makeNav(t,a) {
if (zot(a)) a = 90; // if not a
var nav = new createjs.Container();
nav.setBounds(0,0,120,250);
// fake tab
var arrow = nav.arrow = makeArrow(a,"black", "#d1a170", "#dddddd");
arrow.regX = arrow.getBounds().width;
arrow.regY = arrow.getBounds().height/2;
arrow.x = nav.getBounds().width;
arrow.y = nav.getBounds().height/2;
zim.scale(arrow,.5);
nav.addChild(arrow);
var t = new createjs.Text(t, "50px verdana", "#333333");
t.textAlign = "center";
t.textBaseline = "middle";
t.x = nav.getBounds().width/4;;
t.y = nav.getBounds().height/2;
t.rotation = -a;
nav.addChild(t);
return nav;
}
function makeArrow(rotation, color, backingColor, rollColor) {
if (zot(color)) color = "white"; // if not color
if (zot(backingColor)) backingColor = "black";
if (zot(rollColor)) rollColor = "#333333";
/*
Button(
width, height, label,
backingColor, backingRollColor, borderColor, borderThickness,
corner, shadowColor, shadowBlur
)
*/
var arrow = new zim.Button(120,120,"",backingColor,rollColor,backingColor,4,60,backingColor,30);
arrow.alpha = .7;
// fake tab - adding at (arrow triangle) to the arrow button
// Triangle(a, b, c, fill, stroke, strokeSize, center)
var at = new zim.Triangle(80,60,60,color,null,null,true,7);
at.rotation = rotation;
at.x = arrow.width/2;
at.y = arrow.height/2;
at.mouseChildren = false; // so arrow does not get in way of rollover
at.mouseEnabled = false;
arrow.addChild(at);
return arrow;
}
function makeDanZen() {
var dz = new createjs.Container();
dz.setBounds(0,0,120,250);
var logo = new createjs.Shape();
logo.graphics.f("#333333").p("EgaPAj2IAAnGQAYg2AthJQBui2ChiYQIAnlMzAAQMwAAH8HgQCeCWBtC0QA2BaAWA8IAKG4gASAL3Qp6gboOg7QrkhSmmiFQoQimgBjtQAAjrINiiQGkiBLghMQILg2J2gVQE6gLDSAAIqnK6IK8LFQjUgCk8gNgA6Ft9IQauEIwan0MA0pAAAItJMqINJJOg");
zim.scale(logo,.2);
logo.alpha = .8;
// gridManager.add(new zim.Grid(dz, "lime", false));
logo.x = 60;
logo.y = 125;
dz.addChild(logo);
return dz;
}
// MAKE REST OF PAGES
// now we will loop to make the rest of the pages
// unfortunately, pages are usually not so simple so would have to make each one
// certain sites will have areas in common that do not change and can be coded once
// if you want the whole page to slide then you would need to code things multiple times
p.sections = ["pages","layout","grid","guide"];
p.subtitles = data.hSubtitles; // imagining these came from database to start
var i; var k; var name; var subtitle; var cp; // current page
var logo; var content; var pageBacking; var text; var t; var t2; var nextSection; var nav;
var count=0;
for (i=1; i<=3; i++) {
for (k=0; k<p.sections.length; k++) {
count++;
if (i==1 && k==0) continue; // already made pages1 for demonstration
name = p.sections[k]+i; // pages1, layout1, grid1, pages2, layout2, etc.
cp = p[name] = new createjs.Container();
cp.name = name;
subtitle = p.subtitles[count-1];
cp.setBounds(0,0,stageW,stageH);
logo = cp.logo = makeLogo();
logo.setBounds(0,0,200,500);
cp.addChild(logo);
content = cp.content = new createjs.Container();
content.setBounds(0,0,600,700);
cp.addChild(content);
var b = new createjs.Shape();
b.graphics.f("black").r(0,0,600,701);
content.addChild(b);
text = new createjs.Container();
text.setBounds(0,0,300,140);
content.addChild(text);
t = new createjs.Text(p.sections[k].toUpperCase(), "70px verdana", "#eeeeee");
t.textAlign = "center";
t.textBaseline = "middle";
t.x = text.getBounds().width/2;
t.y = text.getBounds().height/2-20;
text.addChild(t);
t2 = new createjs.Text(subtitle, "30px verdana", "#d1a170");
t2.textAlign = "center";
t2.textBaseline = "middle";
t2.x = text.getBounds().width/2;
t2.y = text.getBounds().height/2+50;
text.addChild(t2);
cp.upArrow = makeArrow(0);
content.addChild(cp.upArrow);
cp.downArrow = makeArrow(180);
content.addChild(cp.downArrow);
nextSection = "";
if (p.sections[k+1]) {
nextSection = p.sections[k+1].toUpperCase();
}
nav = cp.nav = (k==3) ? makeDanZen() : makeNav(nextSection);
cp.addChild(nav);
cp.contentLayout = new zim.Layout(cp.content,
[{object:cp.upArrow, minHeight:20, marginTop:5, maxWidth:25},
{object:text, marginTop:10, maxWidth:45},
{object:cp.downArrow, minHeight:20, marginTop:10, maxWidth:25}],
5, null, true);
hLayoutManager.add(cp.contentLayout);
cp.layout = new zim.Layout(cp,
[{object:logo, marginLeft:2, maxHeight:85, minWidth:10, valign:"top", align:"left"},
{object:content, marginLeft:2, maxHeight:100, align:"middle", valign:"middle", backgroundColor:"#333"},
{object:nav, marginLeft:2, maxHeight:55, minWidth:10, valign:"middle", align:"right"}],
2, "#d1a170", false, null, stage);
hLayoutManager.add(cp.layout);
if (i==1) cp.upArrow.visible = false;
if (i==3) cp.downArrow.visible = false;
}
}
// stage.addChild(p.grid2); // used during testing
// took the bounding shapes out but want to put one back in
// for demonstration on the first layout page
p.layout1.contentLayout.addShape(new createjs.Shape());
p.layout1.layout.addShape(new createjs.Shape(), p.layout1);
gridManager.add(new zim.Grid(p.grid1.content, "lime", false)); // add grids to grid first page
guideManager.add(new zim.Guide(p.guide1.content, true, false)); // add vertical guide to guide first page
guideManager.add(new zim.Guide(p.guide1.content, false, false)); // add horizontal guide to guide first page
// turns out that we do not want to see the pages1 up arrow
// that we added in the demonstration code at top
p.pages1.content.removeChild(p.pages1.upArrow);
return p; // we send the p object with all the pages back to the main script
}
// --------------------------------------------------------------------
// --------------------------------------------------------------------
app.vLayouts = function (vLayoutManager, gridManager, guideManager, data) {
// VERTICAL LAYOUTS
// NOTE:
// just copied and adjusted for vertical
// could have streamlined a little, but will leave verbose for demonstration
// my estimated time to convert the horizontal layout to vertical is 1 HR
// this is my first time doing this and I am a coding ZOMBIE at the moment
// RESULTS:
// 30 minutes to remake a sample Vertical page by adjusting the Horizontal page
// 15 minutes to make all the Vertical pages (adjusting code in the loop)
// 10 minutes to add all the Vertical pages to a Pages object
// 05 minutes to add all the Vertical pages to a HotSpots object
// TOTAL: 60 Minutes
// CONCLUSION - Yay!
// the Layout was sufficiently different that scripting would have been a pain
// probably could have used the same set of convenience functions
// Pages and HotSpots were a lot of replacing v for h, left for up and right for down
// which means it could be scripted with parameters or a little lookup table
// all the page layouts are stored in containers with name properties
// add any properties we want in the main file to the p object
// otherwise keep variables local
// will make demonstration page (pages1) and then loop to make other pages
// NOTE - there are FAKE TABS below to show nesting of content
// this is the first time I have done this - might not want to use for real
// as, of course, nesting is used for blocks of code in {} traditionally
var p = {};
// MAKE SAMPLE PAGE
p.pages1 = new createjs.Container();
p.pages1.name = "pages1";
p.pages1.setBounds(0,0,stageW,stageH);
// fake tab to remind us that assets below are in p.pages1
// make the logo, content and nav sections for the horizontal layout of pages1
// we will need to access the logo later for ZIM HotSpots
// so store it in the p object that gets returned to the main JS page
// and we will have one for each page so store it as a property of the page
var logo = p.pages1.logo = makeLogo();
p.pages1.addChild(logo);
// as we build, we can see bounds if needed to debug (comment when done)
// we use the bounds to help fine tune the layout - play around with it to see how
// zim.outline(logo);
// prepare the content region and give it specific bounds
// which will lock in the aspect ratio of the content
// the content will float in the middle, controlled by the horizontal layout
var content = p.pages1.content = new createjs.Container();
content.setBounds(0,0,700,600);
var b = new createjs.Shape();
b.graphics.f("black").r(0,0,701,600);
content.addChild(b);
p.pages1.addChild(content);
// fake tab to remind us these things are inside content
// note the vertical extension of the background
// yet we lock down the bounds of the content above to the size we want
var text = new createjs.Container();
text.setBounds(0,0,300,100);
content.addChild(text);
// fake tab to remind us that t is inside the container text
// note, with custom fonts, I have found you must use "left"
// because Chrome has a radically different bounding box
// normal fonts, all seems good to use center and middle
var t = new createjs.Text("PAGES", "70px verdana", "#eeeeee");
t.textAlign = "center";
t.textBaseline = "middle";
t.x = text.getBounds().width/2;
t.y = text.getBounds().height/2-20;
text.addChild(t);
var t2 = new createjs.Text("ZIM PAGES CLASS", "30px verdana", "#d1a170");
t2.textAlign = "center";
t2.textBaseline = "middle";
t2.x = text.getBounds().width/2;
t2.y = text.getBounds().height/2+50;
text.addChild(t2);
// will need to access buttons so store them in the p object
// will have arrows for each page so store them on the page itself
p.pages1.leftArrow = makeArrow(-90);
content.addChild(p.pages1.leftArrow);
p.pages1.rightArrow = makeArrow(90);
content.addChild(p.pages1.rightArrow);
var nav = p.pages1.nav = makeNav("LAYOUT");
p.pages1.addChild(nav);
// zim.outline(nav, new createjs.Shape()); // used in testing
// step 1 is to make this page so we want to view it
// step 2 is to put the pages into a ZIM Pages object so no longer need this
// stage.addChild(p.pages1);
// HORIZONTAL LAYOUT
// layout the content region with a vertical ZIM Layout object
// this layout has a fixed aspect ratio based on the content's bounding box
// so here, we use Layout to conveniently position (not to flex scale)
// in other words, we could have just hard coded these positions
// in that case, we could have used a ZIM Grid
// here is a grid - uncomment and use G key to toggle or P key for percent/pixels
// gridManager.add(new zim.Grid(content, "lime", false)); // check it out!
// we add the layout to the layoutManager for centralized updating, etc.
// vertical alignment defaults to top, middle and bottom for the three regions
// we pass in a shape if we want to see the bounds
// use the B key to toggle the bounds
p.pages1.contentLayout = new zim.Layout(content,
[{object:p.pages1.leftArrow, minWidth:20, marginLeft:5, maxHeight:25, align:"left", valign:"middle"},
{object:text, marginLeft:5, maxHeight:80, valign:"middle"},
{object:p.pages1.rightArrow, minWidth:20, marginLeft:5, maxHeight:25, align:"left", valign:"middle"}],
5, null, false);
vLayoutManager.add(p.pages1.contentLayout);
// VERTICAL LAYOUT
// layout the outer page in a horizontal layout
// set the stage as the bounds because the stage is what is scaling
// here we use Layout to flex scale (alignment, max and min)
// horizontal alignment defaults are left, middle, right for the three regions
// they are added here so you can see the format
// note: the bounds are drawn into the first object (stage below)
// unless you add a bounds-shape target object at the end (p.pages1)
// so now, when we hide the page, the bounds will hide too
// bound shapes are optional but handy when building
// you can toggle them with B but also remove them when done using the layoutManager
p.pages1.layout = new zim.Layout(p.pages1,
[{object:logo, marginTop:2, maxWidth:35, minHeight:15, align:"middle", valign:"top"},
{object:content, marginTop:2, maxWidth:100, align:"middle", backgroundColor:"#333"},
{object:nav, marginTop:2, maxWidth:55, minHeight:15, align:"middle", valign:"bottom"}],
2, "#d1a170", true, null, stage);
vLayoutManager.add(p.pages1.layout);
// wanted to see the layouts when developing
// and wanted to show the code on how to pass in a shape and target as last parameters
// but do not want to show layout on first page - only the layout pages
// so... will remove the layout shapes here
// p.pages1.layout.removeShape();
// p.pages1.contentLayout.removeShape();
// CONVENIENCE FUNCTIONS
function makeLogo() {
var logo = new createjs.Container();
var circle = zimCircle();
logo.addChild(circle);
return logo;
}
function zimCircle() {
var colors = ["#f58e25","#acd241", "#e472c4", "#50c4b7 ", "#d1a170", "#222222"];
var c = new createjs.Shape();
var g = c.graphics;
c.radius = 100;
for (var i=0; i<colors.length; i++) {
g.f(colors[i]).dc(0,0,(c.radius/colors.length)*(colors.length-i));
}
c.setBounds(-c.radius,-c.radius,c.radius*2,c.radius*2);
c.regX = -c.radius; c.regY = -c.radius;
return c;
}
function makeNav(t,a) {
if (zot(a)) a = 0; // if not a
var nav = new createjs.Container();
nav.setBounds(0,0,250,120);
// fake tab
var arrow = nav.arrow = makeArrow(180,"black", "#d1a170", "#dddddd");
arrow.regX = arrow.getBounds().width/2;
arrow.regY = arrow.getBounds().height;
arrow.x = nav.getBounds().width/2;
arrow.y = nav.getBounds().height;
zim.scale(arrow,.5);
nav.addChild(arrow);
var t = new createjs.Text(t, "50px verdana", "#333333");
t.textAlign = "center";
t.textBaseline = "middle";
t.x = nav.getBounds().width/2;
t.y = nav.getBounds().height/4;
t.rotation = a;
nav.addChild(t);
return nav;
}
function makeArrow(rotation, color, backingColor, rollColor) {
if (zot(color)) color = "white"; // if not color
if (zot(backingColor)) backingColor = "black";
if (zot(rollColor)) rollColor = "#333333";
/*
Button(width, height, label,
backingColor, backingRollColor, borderColor, borderThickness,
corner, shadowColor, shadowBlur
)
*/
var arrow = new zim.Button(120,120,"",backingColor,rollColor,backingColor,4,60,backingColor,30);
arrow.alpha = .7;
// fake tab - adding at (arrow triangle) to the arrow button
// Triangle(a, b, c, fill, stroke, strokeSize, center)
var at = new zim.Triangle(80,60,60,color,null,null,true,7);
at.rotation = rotation;
at.x = arrow.width/2;
at.y = arrow.height/2;
at.mouseChildren = false; // so arrow does not get in way of rollover
at.mouseEnabled = false;
arrow.addChild(at);
return arrow;
}
function makeDanZen() {
var dz = new createjs.Container();
dz.setBounds(0,0,250,120);
var logo = new createjs.Shape();
logo.graphics.f("#333333").p("EgaPAj2IAAnGQAYg2AthJQBui2ChiYQIAnlMzAAQMwAAH8HgQCeCWBtC0QA2BaAWA8IAKG4gASAL3Qp6gboOg7QrkhSmmiFQoQimgBjtQAAjrINiiQGkiBLghMQILg2J2gVQE6gLDSAAIqnK6IK8LFQjUgCk8gNgA6Ft9IQauEIwan0MA0pAAAItJMqINJJOg");
zim.scale(logo,.2);
logo.alpha = .8;
//gridManager.add(new zim.Grid(dz, "lime", false));
logo.x = dz.getBounds().width/2;
logo.y = dz.getBounds().height/2;
dz.addChild(logo);
return dz;
}
//stage.addChild(p.pages1);
//stage.update();
// MAKE REST OF PAGES
// now we will loop to make the rest of the pages
// unfortunately, pages are usually not so simple so would have to make each one
// certain sites will have areas in common that do not change and can be coded once
// if you want the whole page to slide then you would need to code things multiple times
p.sections = ["pages","layout","grid","guide"];
p.subtitles = data.vSubtitles; // imagining these came from the database to start
var i; var k; var name; var subtitle; var cp; // current page
var logo; var content; var pageBacking; var text; var t; var t2; var nextSection; var nav;
var count=0;
for (i=1; i<=3; i++) {
for (k=0; k<p.sections.length; k++) {
count++;
if (i==1 && k==0) continue; // already made pages1 for demonstration
name = p.sections[k]+i; // pages1, pages2, pages3, layout1, layout2, etc.
cp = p[name] = new createjs.Container();
cp.name = name;
subtitle = p.subtitles[count-1];
cp.setBounds(0,0,stageW,stageH);
logo = cp.logo = makeLogo();
cp.addChild(logo);
content = cp.content = new createjs.Container();
content.setBounds(0,0,700,600);
var b = new createjs.Shape();
b.graphics.f("black").r(0,0,701,600);
content.addChild(b);
cp.addChild(content);
text = new createjs.Container();
text.setBounds(0,0,300,100);
content.addChild(text);
t = new createjs.Text(p.sections[k].toUpperCase(), "70px verdana", "#eeeeee");
t.textAlign = "center";
t.textBaseline = "middle";
t.x = text.getBounds().width/2;
t.y = text.getBounds().height/2-20;
text.addChild(t);
t2 = new createjs.Text(subtitle, "30px verdana", "#d1a170");
t2.textAlign = "center";
t2.textBaseline = "middle";
t2.x = text.getBounds().width/2;
t2.y = text.getBounds().height/2+50;
text.addChild(t2);
cp.leftArrow = makeArrow(-90);
content.addChild(cp.leftArrow);
cp.rightArrow = makeArrow(90);
content.addChild(cp.rightArrow);
nextSection = "";
if (p.sections[k+1]) {
nextSection = p.sections[k+1].toUpperCase();
}
nav = cp.nav = (k==3) ? makeDanZen() : makeNav(nextSection);
cp.addChild(nav);
cp.contentLayout = new zim.Layout(cp.content,
[{object:cp.leftArrow, minWidth:20, marginLeft:5, maxHeight:25, align:"left", valign:"middle"},
{object:text, marginLeft:5, maxHeight:80, valign:"middle"},
{object:cp.rightArrow, minWidth:20, marginLeft:5, maxHeight:25, align:"left", valign:"middle"}],
5, null, false);
vLayoutManager.add(cp.contentLayout);
cp.layout = new zim.Layout(cp,
[{object:logo, marginTop:2, maxWidth:35, minHeight:15, align:"middle", valign:"top"},
{object:content, marginTop:2, maxWidth:100, align:"middle", backgroundColor:"#333"},
{object:nav, marginTop:2, maxWidth:55, minHeight:15, align:"middle", valign:"bottom"}],
2, "#d1a170", true, null, stage);
vLayoutManager.add(cp.layout);
if (i==1) cp.leftArrow.visible = false;
if (i==3) cp.rightArrow.visible = false;
}
}
// stage.addChild(p.grid2); // used during testing
// took the bounding shapes out but want to put one back in
// for demonstration on the first layout page
p.layout1.contentLayout.addShape(new createjs.Shape());
p.layout1.layout.addShape(new createjs.Shape(), p.layout1);
gridManager.add(new zim.Grid(p.grid1.content, "lime", false)); // add grids to grid first page
guideManager.add(new zim.Guide(p.guide1.content, true, false)); // add vertical guide to guide first page
guideManager.add(new zim.Guide(p.guide1.content, false, false)); // add horizontal guide to guide first page
// turns out that we do not want to see the pages1 up arrow
// that we added in the demonstration code at top
p.pages1.content.removeChild(p.pages1.leftArrow);
return p; // we send the p object with all the pages back to the main script
}
return app;
} (app || {});
// in the controller.js file:
var app = function(app) {
app.hotSpots = function (assets, pages, data, waiter, type) {
// use ZIM HotSpots to add links to buttons and navigation press areas
// these look repetative for the current basic site
// however... I just made all the navigation in about 15 minutes
// we might have looped but there are all sorts of little exceptions so be careful
// if there is extra functionality to do you can just call a remote function
// or better yet, handle it in a "page" event on pages
// this allows you to handle swipes and presses in one place
// if you have extra interface not tied in to page navigation
// you can still use this hotSpot object
// we can add rectangle hotSpots (like image maps) - we will do the logo and nav this way
// this handles making graphical pages clickable in parts
// NOTE: hotSpots on the stage will not scale / move in scale mode "full" and "none"
// they do scale / move in "fit" and "outside" scale mode
// so we need to put rectangle hotspots in the container that is being scaled (usually the page)
// (if you are scaling with "fit" or "outside" then pass in a false as the next parameter)
// we can also pass in an object like a button, container or shape as the rect
// the hotSpots on these are actually put on the buttons, containers and shapes
// so just add the containing page as the page
// make grids where the logo and nav reside to help calculate rectangle dimensions
// gridManager.add(new zim.Grid(p.pages1.logo, "white", false));
// gridManager.add(new zim.Grid(p.pages1.nav, "white", false));
var zimURL = "http://zimjs.com/examples.html?pages";
var dzURL = "http://danzen.com";
var dzTarget = "dz";
// lookup table to handle different directions due to orientation change
// buttonForward, buttonBack,
// directionForwardSection, directionBackSection,
// directionForwardPages, directionBackPages
var dFS; var dBS; var dFP; var dBP; var bF; var bB; var logoRect; var dzRect;
if (type == "horizontal") {
dFS = "right"; dBS = "left";
dFP = "down"; dBP = "up";
logoRect = [0,0,200,200];
dzRect = [0,40,120,170];
} else {
dFS = "down"; dBS = "up";
dFP = "right"; dBP = "left";
logoRect = [0,0,200,200];
dzRect = [55,0,140,120];
}
bF = dFP+"Arrow"; bB = dBP+"Arrow";
var a = assets; // for brievity
var hs = new zim.HotSpots([
{page:a.pages1.logo, rect:logoRect, call:function() {zgo(zimURL);}},
{page:a.pages1, rect:a.pages1[bF], call:function() {pages.go(a.pages2, dFP);}},
{page:a.pages1, rect:a.pages1.nav.arrow, call:function() {hs.checkDataExample(a.pages1, a.layout1, dFS);}},
{page:a.pages2.logo, rect:logoRect, call:function() {zgo(zimURL);}},
{page:a.pages2, rect:a.pages2[bB], call:function() {pages.go(a.pages1, dBP);}},
{page:a.pages2, rect:a.pages2[bF], call:function() {pages.go(a.pages3, dFP);}},
{page:a.pages2, rect:a.pages2.nav.arrow, call:function() {pages.go(a.layout1,dFS);}},
{page:a.pages3.logo, rect:logoRect, call:function() {zgo(zimURL);}},
{page:a.pages3, rect:a.pages3[bB], call:function() {pages.go(a.pages2, dBP);}},
{page:a.pages3, rect:a.pages3.nav.arrow, call:function() {pages.go(a.layout1,dFS);}},
{page:a.layout1.logo, rect:logoRect, call:function() {pages.go(a.pages1, dBS);}},
{page:a.layout1, rect:a.layout1[bF], call:function() {pages.go(a.layout2,dFP);}},
{page:a.layout1, rect:a.layout1.nav.arrow, call:function() {pages.go(a.grid1, dFS);}},
{page:a.layout2.logo, rect:logoRect, call:function() {pages.go(a.pages1, dBS);}},
{page:a.layout2, rect:a.layout2[bB], call:function() {pages.go(a.layout1,dBP);}},
{page:a.layout2, rect:a.layout2[bF], call:function() {pages.go(a.layout3,dFP);}},
{page:a.layout2, rect:a.layout2.nav.arrow, call:function() {pages.go(a.grid1, dFS);}},
{page:a.layout3.logo, rect:logoRect, call:function() {pages.go(a.pages1, dBS);}},
{page:a.layout3, rect:a.layout3[bB], call:function() {pages.go(a.layout2,dBP);}},
{page:a.layout3, rect:a.layout3.nav.arrow, call:function() {pages.go(a.grid1, dFS);}},
{page:a.grid1.logo, rect:logoRect, call:function() {pages.go(a.layout1,dBS);}},
{page:a.grid1, rect:a.grid1[bF], call:function() {pages.go(a.grid2, dFP);}},
{page:a.grid1, rect:a.grid1.nav.arrow, call:function() {pages.go(a.guide1, dFS);}},
{page:a.grid2.logo, rect:logoRect, call:function() {pages.go(a.layout1,dBS);}},
{page:a.grid2, rect:a.grid2[bB], call:function() {pages.go(a.grid1, dBP);}},
{page:a.grid2, rect:a.grid2[bF], call:function() {pages.go(a.grid3, dFP);}},
{page:a.grid2, rect:a.grid2.nav.arrow, call:function() {pages.go(a.guide1, dFS);}},
{page:a.grid3.logo, rect:logoRect, call:function() {pages.go(a.layout1,dBS);}},
{page:a.grid3, rect:a.grid3[bB], call:function() {pages.go(a.grid2, dBP);}},
{page:a.grid3, rect:a.grid3.nav.arrow, call:function() {pages.go(a.guide1, dFS);}},
{page:a.guide1.logo, rect:logoRect, call:function() {pages.go(a.grid1,dBS);}},
{page:a.guide1, rect:a.guide1[bF], call:function() {pages.go(a.guide2, dFP);}},
{page:a.guide1.nav, rect:dzRect, call:function() {zgo(dzURL, dzTarget, true);}},
{page:a.guide2.logo, rect:logoRect, call:function() {pages.go(a.grid1,dBS);}},
{page:a.guide2, rect:a.guide2[bB], call:function() {pages.go(a.guide1, dBP);}},
{page:a.guide2, rect:a.guide2[bF], call:function() {pages.go(a.guide3, dFP);}},
{page:a.guide2.nav, rect:dzRect, call:function() {zgo(dzURL, dzTarget, true);}},
{page:a.guide3.logo, rect:logoRect, call:function() {pages.go(a.grid1,dBS);}},
{page:a.guide3, rect:a.guide3[bB], call:function() {pages.go(a.guide2, dBP);}},
{page:a.guide3.nav, rect:dzRect, call:function() {zgo(dzURL, dzTarget, true);}}
], true, true); // local (defaults to true) and enable swipe on button (defaults to false)
// example of handling some data before going to next page
// we receive the page and direction from the hotSpot (and the Page swipe - see main app)
// we send these to the data object for checking or whatever
// the data object goes to the database and issues a result event
// we then check the data object for the result
// in this case, we just are round tripping the page and direction for demonstration
hs.checkDataExample = function (currentPage, newPage, direction) {
// might want to start a spinner (hey... good idea for another ZIM object!)
data.getData(newPage, direction);
waiter.show();
// just going to position this relative to the content page
// the waiter gets added to the center of the stage automatically
// unfortunately, these pages are a bit off centered
// so will convert the center of the content area to a global value
// might want to scale it just in case - but it seems all right
var p = currentPage.content;
var w = p.getBounds().width;
var h = p.getBounds().height;
var point = p.localToGlobal(w/2, h*.2);
waiter.x = point.x;
waiter.y = point.y;
data.on("result", function(e) {
waiter.hide();
zog(data.result.message);
pages.go(data.result.page, data.result.direction);
pages.unpause(); // in case it comes from swipe
}, null, true); // event gets made each click - so remove the listener after using
}
return hs;
}
return app;
} (app || {});