"added impressive events when step is entered and left, triggered by transition end"

This commit is contained in:
Bartek Szopka
2012-03-10 22:36:08 +00:00
parent e2a13e35d6
commit 1bbf205bc7

View File

@@ -108,7 +108,7 @@
var getElementFromUrl = function () { var getElementFromUrl = function () {
// get id from url # by removing `#` or `#/` from the beginning, // 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(/^#\/?/,"") ); return byId( window.location.hash.replace(/^#\/?/,"") );
}; };
@@ -130,6 +130,16 @@
body.classList.add("impress-supported"); 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 roots = {};
var defaults = { var defaults = {
@@ -276,10 +286,44 @@
}); });
// making given step active
var active = null; 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(); var windowScale = computeWindowScale();
@@ -309,15 +353,6 @@
body.classList.add("impress-on-" + el.id); 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 = { var target = {
rotate: { rotate: {
x: -step.rotate.x, x: -step.rotate.x,
@@ -337,8 +372,8 @@
// if presentation starts (nothing is active yet) // if presentation starts (nothing is active yet)
// don't animate (set duration to 0) // don't animate (set duration to 0)
var duration = (active) ? config.transitionDuration + "ms" : "0ms", var duration = (active) ? config.transitionDuration : 0,
delay = (config.transitionDuration / 2) + "ms"; delay = (config.transitionDuration / 2);
if (force) { if (force) {
windowScale = computeWindowScale(); windowScale = computeWindowScale();
@@ -346,23 +381,33 @@
var targetScale = target.scale * windowScale; var targetScale = target.scale * windowScale;
expectedTransitionTarget = target.scale > current.scale ? root : canvas;
if (active) {
onStepLeave(active);
}
css(root, { css(root, {
// to keep the perspective look similar for different scales // to keep the perspective look similar for different scales
// we need to 'scale' the perspective, too // we need to 'scale' the perspective, too
transform: perspective( config.perspective / targetScale ) + scale( targetScale ), transform: perspective( config.perspective / targetScale ) + scale( targetScale ),
transitionDuration: duration, transitionDuration: duration + "ms",
transitionDelay: (zoomin ? delay : "0ms") transitionDelay: (zoomin ? delay : 0) + "ms"
}); });
css(canvas, { css(canvas, {
transform: rotate(target.rotate, true) + translate(target.translate), transform: rotate(target.rotate, true) + translate(target.translate),
transitionDuration: duration, transitionDuration: duration + "ms",
transitionDelay: (zoomin ? "0ms" : delay) transitionDelay: (zoomin ? 0 : delay) + "ms"
}); });
current = target; current = target;
active = el; active = el;
if (duration === 0) {
onStepEnter(active);
}
return el; return el;
}; };
@@ -380,6 +425,18 @@
return stepTo(next); 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 () { window.addEventListener("hashchange", function () {
stepTo( getElementFromUrl() ); stepTo( getElementFromUrl() );
}, false); }, false);