aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartek Szopka <bartek.szopka+github@gmail.com>2012-03-10 22:36:08 +0000
committerBartek Szopka <bartek.szopka+github@gmail.com>2012-03-10 22:36:08 +0000
commit1bbf205bc71b89b0f72a83ac6a1e7f5c4c0f46b1 (patch)
tree019bea890629215edcdda0e961693226362a8dd5
parente2a13e35d681b9dd13700a49306c00031ae7d038 (diff)
downloadimpress.js-1bbf205bc71b89b0f72a83ac6a1e7f5c4c0f46b1.tar.gz
"added impressive events when step is entered and left, triggered by transition end"
-rw-r--r--js/impress.js95
1 files changed, 76 insertions, 19 deletions
diff --git a/js/impress.js b/js/impress.js
index c2458f4..bf824e2 100644
--- a/js/impress.js
+++ b/js/impress.js
@@ -108,7 +108,7 @@
var getElementFromUrl = function () {
// get id from url # by removing `#` or `#/` from the beginning,
- // so both `#slide-id` and "legacy" `#/slide-id` will work
+ // so both "fallback" `#slide-id` and "enhanced" `#/slide-id` will work
return byId( window.location.hash.replace(/^#\/?/,"") );
};
@@ -130,6 +130,16 @@
body.classList.add("impress-supported");
}
+ // cross-browser transitionEnd event name
+ // based on https://developer.mozilla.org/en/CSS/CSS_transitions
+ var transitionEnd = ({
+ 'transition':'transitionEnd',
+ 'OTransition':'oTransitionEnd',
+ 'msTransition':'MSTransitionEnd', // who knows how it will end up?
+ 'MozTransition':'transitionend',
+ 'WebkitTransition':'webkitTransitionEnd'
+ })[pfx("transition")];
+
var roots = {};
var defaults = {
@@ -276,10 +286,44 @@
});
- // making given step active
-
var active = null;
- var hashTimeout = null;
+
+ // step events
+
+ var triggerEvent = function (el, eventName) {
+ var event = document.createEvent("CustomEvent");
+ event.initCustomEvent(eventName, true, true);
+ el.dispatchEvent(event);
+ };
+
+ var lastEntered = null;
+ var onStepEnter = function (step) {
+ if (lastEntered !== step) {
+ triggerEvent(step, "impressStepEnter");
+ lastEntered = step;
+ }
+ };
+
+ var onStepLeave = function (step) {
+ if (lastEntered === step) {
+ triggerEvent(step, "impressStepLeave");
+ }
+ };
+
+
+ // transitionEnd event handler
+
+ var expectedTransitionTarget = null;
+
+ var onTransitionEnd = function (event) {
+ // we only care about transitions on `root` and `canvas` elements
+ if (event.target === expectedTransitionTarget) {
+ onStepEnter(active);
+ event.stopPropagation(); // prevent propagation from `canvas` to `root`
+ }
+ };
+ root.addEventListener(transitionEnd, onTransitionEnd, false);
+ canvas.addEventListener(transitionEnd, onTransitionEnd, false);
var windowScale = computeWindowScale();
@@ -309,15 +353,6 @@
body.classList.add("impress-on-" + el.id);
- // Setting fragment URL with `history.pushState`
- // and it has to be set after animation finishes, because in Chrome it
- // causes transtion being laggy
- // BUG: http://code.google.com/p/chromium/issues/detail?id=62820
- window.clearTimeout( hashTimeout );
- hashTimeout = window.setTimeout(function () {
- window.location.hash = "#/" + el.id;
- }, config.transitionDuration);
-
var target = {
rotate: {
x: -step.rotate.x,
@@ -337,8 +372,8 @@
// if presentation starts (nothing is active yet)
// don't animate (set duration to 0)
- var duration = (active) ? config.transitionDuration + "ms" : "0ms",
- delay = (config.transitionDuration / 2) + "ms";
+ var duration = (active) ? config.transitionDuration : 0,
+ delay = (config.transitionDuration / 2);
if (force) {
windowScale = computeWindowScale();
@@ -346,23 +381,33 @@
var targetScale = target.scale * windowScale;
+ expectedTransitionTarget = target.scale > current.scale ? root : canvas;
+
+ if (active) {
+ onStepLeave(active);
+ }
+
css(root, {
// to keep the perspective look similar for different scales
// we need to 'scale' the perspective, too
transform: perspective( config.perspective / targetScale ) + scale( targetScale ),
- transitionDuration: duration,
- transitionDelay: (zoomin ? delay : "0ms")
+ transitionDuration: duration + "ms",
+ transitionDelay: (zoomin ? delay : 0) + "ms"
});
css(canvas, {
transform: rotate(target.rotate, true) + translate(target.translate),
- transitionDuration: duration,
- transitionDelay: (zoomin ? "0ms" : delay)
+ transitionDuration: duration + "ms",
+ transitionDelay: (zoomin ? 0 : delay) + "ms"
});
current = target;
active = el;
+ if (duration === 0) {
+ onStepEnter(active);
+ }
+
return el;
};
@@ -380,6 +425,18 @@
return stepTo(next);
};
+ // HASH CHANGE
+
+ // `#/step-id` is used instead of `#step-id` to prevent default browser
+ // scrolling to element in hash
+ //
+ // and it has to be set after animation finishes, because in Chrome it
+ // causes transtion being laggy
+ // BUG: http://code.google.com/p/chromium/issues/detail?id=62820
+ document.addEventListener("impressStepEnter", function (event) {
+ window.location.hash = "#/" + event.target.id;
+ }, false);
+
window.addEventListener("hashchange", function () {
stepTo( getElementFromUrl() );
}, false);