impressive API

This commit is contained in:
Bartek Szopka
2012-02-01 21:28:55 +01:00
parent 9641f5750b
commit cfe6448594
2 changed files with 228 additions and 188 deletions

View File

@@ -286,6 +286,7 @@
-->
<script src="js/impress.js"></script>
<script>impress();</script>
</body>
</html>

View File

@@ -86,7 +86,13 @@
var scale = function ( s ) {
return " scale(" + s + ") ";
}
};
var getElementFromUrl = function () {
// get id from url # by removing `#` or `#/` from the beginning,
// so both "fallback" `#slide-id` and "enhanced" `#/slide-id` will work
return byId( window.location.hash.replace(/^#\/?/,"") );
};
// CHECK SUPPORT
@@ -94,26 +100,37 @@
var impressSupported = ( pfx("perspective") != null ) &&
( ua.search(/(iphone)|(ipod)|(ipad)|(android)/) == -1 );
var roots = {};
var impress = window.impress = function ( rootId ) {
rootId = rootId || "impress";
// if already initialized just return the API
if (roots["impress-root-" + rootId]) {
return roots["impress-root-" + rootId];
}
// DOM ELEMENTS
var impress = byId("impress");
var root = byId( rootId );
if (!impressSupported) {
impress.className = "impress-not-supported";
root.className = "impress-not-supported";
return;
} else {
impress.className = "";
root.className = "";
}
var canvas = document.createElement("div");
canvas.className = "canvas";
arrayify( impress.childNodes ).forEach(function ( el ) {
arrayify( root.childNodes ).forEach(function ( el ) {
canvas.appendChild( el );
});
impress.appendChild(canvas);
root.appendChild(canvas);
var steps = $$(".step", impress);
var steps = $$(".step", root);
// SETUP
// set initial values and defaults
@@ -132,8 +149,8 @@
transformStyle: "preserve-3d"
}
css(impress, props);
css(impress, {
css(root, props);
css(root, {
top: "50%",
left: "50%",
perspective: "1000px"
@@ -148,6 +165,10 @@
var stepData = {};
var isStep = function ( el ) {
return !!(el && el.id && stepData["impress-" + el.id]);
}
steps.forEach(function ( el, idx ) {
var data = el.dataset,
step = {
@@ -187,12 +208,8 @@
var active = null;
var hashTimeout = null;
var isStep = function ( el ) {
return !!(el && el.id && stepData["impress-" + el.id]);
}
var select = function ( el ) {
if ( !el || !isStep(el) || el == active) {
var goto = function ( el ) {
if ( !isStep(el) || el == active) {
// selected element is not defined as step or is already active
return false;
}
@@ -214,7 +231,7 @@
}
el.classList.add("active");
impress.className = "step-" + el.id;
root.className = "step-" + el.id;
// `#/step-id` is used instead of `#step-id` to prevent default browser
// scrolling to element in hash
@@ -247,7 +264,7 @@
// don't animate (set duration to 0)
var duration = (active) ? "1s" : "0";
css(impress, {
css(root, {
// to keep the perspective look similar for different scales
// we need to 'scale' the perspective, too
perspective: step.scale * 1000 + "px",
@@ -268,36 +285,57 @@
return el;
};
var selectPrev = function () {
var prev = function () {
var prev = steps.indexOf( active ) - 1;
prev = prev >= 0 ? steps[ prev ] : steps[ steps.length-1 ];
return select(prev);
return goto(prev);
};
var selectNext = function () {
var next = function () {
var next = steps.indexOf( active ) + 1;
next = next < steps.length ? steps[ next ] : steps[ 0 ];
return select(next);
return goto(next);
};
// EVENTS
window.addEventListener("hashchange", function () {
goto( getElementFromUrl() );
}, false);
// START
// by selecting step defined in url or first step of the presentation
goto(getElementFromUrl() || steps[0]);
return (roots[ "impress-root-" + rootId ] = {
goto: goto,
next: next,
prev: prev
});
}
})(document, window);
// EVENTS
(function ( document, window ) {
'use strict';
// keyboard navigation handler
document.addEventListener("keydown", function ( event ) {
if ( event.keyCode == 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) {
switch( event.keyCode ) {
case 33: ; // pg up
case 37: ; // left
case 38: // up
selectPrev();
impress().prev();
break;
case 9: ; // tab
case 32: ; // space
case 34: ; // pg down
case 39: ; // right
case 40: // down
selectNext();
impress().next();
break;
}
@@ -305,12 +343,12 @@
}
}, false);
// delegated handler for clicking on the links to presentation steps
document.addEventListener("click", function ( event ) {
// event delegation with "bubbling"
// check if event target (or any of its parents is a link or a step)
// check if event target (or any of its parents is a link)
var target = event.target;
while ( (target.tagName != "A") &&
(!isStep(target)) &&
(target != document.body) ) {
target = target.parentNode;
}
@@ -320,28 +358,29 @@
// if it's a link to presentation step, target this step
if ( href && href[0] == '#' ) {
target = byId( href.slice(1) );
target = document.getElementById( href.slice(1) );
}
}
if ( select(target) ) {
if ( impress().goto(target) ) {
event.stopImmediatePropagation();
event.preventDefault();
}
}, false);
var getElementFromUrl = function () {
// get id from url # by removing `#` or `#/` from the beginning,
// so both "fallback" `#slide-id` and "enhanced" `#/slide-id` will work
return byId( window.location.hash.replace(/^#\/?/,"") );
// delegated handler for clicking on step elements
document.addEventListener("click", function ( event ) {
var target = event.target;
// find closest step element
while ( !target.classList.contains("step") &&
(target != document.body) ) {
target = target.parentNode;
}
window.addEventListener("hashchange", function () {
select( getElementFromUrl() );
if ( impress().goto(target) ) {
event.preventDefault();
}
}, false);
// START
// by selecting step defined in url or first step of the presentation
select(getElementFromUrl() || steps[0]);
})(document, window);