Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: bartaz/impress.js
base: 9efe06633b
...
head fork: bartaz/impress.js
compare: e57204eb27
Checking mergeability… Don't worry, you can still create the pull request.
  • 5 commits
  • 2 files changed
  • 0 commit comments
  • 1 contributor
Showing with 57 additions and 53 deletions.
  1. +13 −1 README.md
  2. +44 −52 js/impress.js
View
14 README.md
@@ -20,7 +20,19 @@ It's an (un)fortunate coincidence that a Open/LibreOffice presentation tool is c
VERSION HISTORY
-----------------
-### 0.5.2 ([browse](http://github.com/bartaz/impress.js/tree/0.5.1), [zip](http://github.com/bartaz/impress.js/zipball/0.5.1), [tar](http://github.com/bartaz/impress.js/tarball/0.5.1))
+### 0.5.3 ([browse](http://github.com/bartaz/impress.js/tree/0.5.3), [zip](http://github.com/bartaz/impress.js/zipball/0.5.3), [tar](http://github.com/bartaz/impress.js/tarball/0.5.3))
+
+#### BUGFIX RELEASE
+
+Version 0.5 introduced events including `impress:stepenter`, but this event was not triggered properly in some
+specific transition types (for example when only scale was changing between steps). It was caused by the fact that
+in such cases expected `transitionend` event was not triggered.
+
+This version fixes this issue. Unfortunately modern `transitionend` event is no longer used to detect when the
+transition has finished, but old school (and more reliable) `setTimeout` is used.
+
+
+### 0.5.2 ([browse](http://github.com/bartaz/impress.js/tree/0.5.2), [zip](http://github.com/bartaz/impress.js/zipball/0.5.2), [tar](http://github.com/bartaz/impress.js/tarball/0.5.2))
#### DOCUMENTATION RELEASE
View
96 js/impress.js
@@ -11,7 +11,7 @@
*
* ------------------------------------------------
* author: Bartek Szopka
- * version: 0.5.2
+ * version: 0.5.3
* url: http://bartaz.github.com/impress.js/
* source: http://github.com/bartaz/impress.js/
*/
@@ -191,17 +191,6 @@
// GLOBALS AND DEFAULTS
- // Getting cross-browser transitionEnd event name.
- // It's hard to detect it, so we are using the list 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")];
-
// This is were the root elements of all impress.js instances will be kept.
// Yes, this means you can have more than one instance on a page, but I'm not
// sure if it makes any sense in practice ;)
@@ -224,7 +213,7 @@
// IMPRESS.JS API
- // And that's where intresting things will start to happen.
+ // And that's where interesting things will start to happen.
// It's the core `impress` function that returns the impress.js API
// for a presentation based on the element with given id ('impress'
// by default).
@@ -304,33 +293,6 @@
}
};
- // To detect the moment when the transition to step element finished
- // we need to handle the transitionEnd event.
- //
- // It may not sound very hard but to makes things a little bit more
- // complicated there are two elements being animated separately:
- // `root` (used for scaling) and `canvas` for translate and rotations.
- // Transitions on them are triggered with different delays (to make
- // visually nice and 'natural' looking transitions), so we need to know
- // that both of them are finished.
- //
- // It sounds like a simple counter to two would be enough. Unfortunately
- // if there is no change in the transform value (for example scale doesn't
- // change between two steps) only one transition (and transitionEnd event)
- // will be triggered.
- //
- // So to properly detect when the transitions finished we need to keep
- // the `expectedTransitionTarget` (that can be one of `root` or `canvas`)
- // and only call `onStepEnter` then transition ended on the expected one.
-
- var expectedTransitionTarget = null;
-
- var onTransitionEnd = function (event) {
- if (event.target === expectedTransitionTarget) {
- onStepEnter(activeStep);
- }
- };
-
// `initStep` initializes given step element by reading data from its
// data attributes and setting correct styles.
var initStep = function ( el, idx ) {
@@ -421,8 +383,6 @@
});
css(canvas, rootStyles);
- root.addEventListener(transitionEnd, onTransitionEnd, false);
-
body.classList.remove("impress-disabled");
body.classList.add("impress-enabled");
@@ -455,6 +415,9 @@
return (step && step.id && stepsData["impress-" + step.id]) ? step : null;
};
+ // used to reset timeout for `impress:stepenter` event
+ var stepEnterTimeout = null;
+
// `goto` API function that moves to step given with `el` parameter (by index, id or element),
// with a transition `duration` optionally given as second parameter.
var goto = function ( el, duration ) {
@@ -518,18 +481,19 @@
var targetScale = target.scale * windowScale;
- // Because one of the transition is delayed depending on zoom direction,
- // the last transition will happen on `root` or `canvas` element.
- // Here we store the expected transition event target, to be able to correctly
- // trigger `impress:stepenter` event.
- expectedTransitionTarget = target.scale > currentState.scale ? root : canvas;
-
// trigger leave of currently active element (if it's not the same step again)
if (activeStep && activeStep !== el) {
onStepLeave(activeStep);
}
- // alter transforms of `root` and `canvas` to trigger transitions
+ // Now we alter transforms of `root` and `canvas` to trigger transitions.
+ //
+ // And here is why there are two elements: `root` and `canvas` - they are
+ // being animated separately:
+ // `root` is used for scaling and `canvas` for translate and rotations.
+ // Transitions on them are triggered with different delays (to make
+ // visually nice and 'natural' looking transitions), so we need to know
+ // that both of them are finished.
css(root, {
// to keep the perspective look similar for different scales
// we need to 'scale' the perspective, too
@@ -544,14 +508,42 @@
transitionDelay: (zoomin ? 0 : delay) + "ms"
});
+ // Here is a tricky part...
+ //
+ // If there is no change in scale or no change in rotation and translation, it means there was actually
+ // no delay - because there was no transition on `root` or `canvas` elements.
+ // We want to trigger `impress:stepenter` event in the correct moment, so here we compare the current
+ // and target values to check if delay should be taken into account.
+ //
+ // I know that this `if` statement looks scary, but it's pretty simple when you know what is going on
+ // - it's simply comparing all the values.
+ if ( currentState.scale === target.scale ||
+ (currentState.rotate.x === target.rotate.x && currentState.rotate.y === target.rotate.y &&
+ currentState.rotate.z === target.rotate.z && currentState.translate.x === target.translate.x &&
+ currentState.translate.y === target.translate.y && currentState.translate.z === target.translate.z) ) {
+ delay = 0;
+ }
+
// store current state
currentState = target;
activeStep = el;
- // manually trigger enter event if duration was set to 0
- if (duration === 0) {
+ // And here is where we trigger `impress:stepenter` event.
+ // We simply set up a timeout to fire it taking transition duration (and possible delay) into account.
+ //
+ // I really wanted to make it in more elegant way. The `transitionend` event seemed to be the best way
+ // to do it, but the fact that I'm using transitions on two separate elements and that the `transitionend`
+ // event is only triggered when there was a transition (change in the values) caused some bugs and
+ // made the code really complicated, cause I had to handle all the conditions separately. And it still
+ // needed a `setTimeout` fallback for the situations when there is no transition at all.
+ // So I decided that I'd rather make the code simpler than use shiny new `transitionend`.
+ //
+ // If you want learn something interesting and see how it was done with `transitionend` go back to
+ // version 0.5.2 of impress.js: http://github.com/bartaz/impress.js/blob/0.5.2/js/impress.js
+ window.clearTimeout(stepEnterTimeout);
+ stepEnterTimeout = window.setTimeout(function() {
onStepEnter(activeStep);
- }
+ }, duration + delay);
return el;
};

No commit comments for this range

Something went wrong with that request. Please try again.