diff options
author | James Bottomley <JBottomley@Parallels.com> | 2014-03-01 15:44:46 -0800 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2014-03-03 07:56:04 -0800 |
commit | 80e759c66ca6b6c628b8910c8a23f90f76a18530 (patch) | |
tree | 72dc8ef14a0a748de77baaf7c628978a5326ad01 | |
parent | d505df4e4ed20f91b589893cba306fe693ab17d3 (diff) | |
download | impress.js-80e759c66ca6b6c628b8910c8a23f90f76a18530.tar.gz |
impress.js: add build transitions
The idea of this new element is that some scenes are built up while you
explain them on the podium. For instace, you can take a diagram and add and
remove arrow pointers to interesting bit. The way this is done is to use a
build class. Now every step is either a step or a build. a build keeps all
the prior elements up to the step active (so there's no transition and they're
still at full opacity).
The way this works is simple, the goto() function now maintains a list of
elements building from the last executed step. When it moves to a new step,
these are all made inactive together. For goto() which is not a linear
move from the previous, all the active builds are torn down and the new prior
step located and all builds executed to the new point.
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r-- | js/impress.js | 62 |
1 files changed, 56 insertions, 6 deletions
diff --git a/js/impress.js b/js/impress.js index dedcefa..3071cb0 100644 --- a/js/impress.js +++ b/js/impress.js @@ -243,6 +243,9 @@ // element of currently active step var activeStep = null; + + // array of elements being built on (always has a step first) + var lastBuild = null; // current state (position, rotation and scale) of the presentation var currentState = null; @@ -387,7 +390,7 @@ body.classList.add("impress-enabled"); // get and init steps - steps = $$(".step", root); + steps = $$(".step, .build", root); steps.forEach( initStep ); // set a default initial state of the canvas @@ -438,11 +441,48 @@ window.scrollTo(0, 0); var step = stepsData["impress-" + el.id]; + + // indicates we're doing a build on to an existing step + var isBuild = el.classList.contains("build"); + + // navigating builds is a pain. If we're not linearly stepping + // up the build, then we have to tear everything down and build + // it up from the new position. jumpStep is true if we have + // to tear down and rebuild + var jumpStep = steps.indexOf(el) - 1 != steps.indexOf(activeStep) + && el != activeStep; if ( activeStep ) { - activeStep.classList.remove("active"); - body.classList.remove("impress-on-" + activeStep.id); + if ( !isBuild || jumpStep ) { + // tear down last transition + for (var i = 0; i < lastBuild.length; i++) { + var curStep = lastBuild[i] + curStep.classList.remove("active"); + body.classList.remove("impress-on-" + curStep.id); + } + } } + if ( jumpStep || ( !activeStep && isBuild ) ) { + // build up from first prior step + lastBuild = new Array(); + var i = el; + while (true) { + if (i.classList.contains("step")) { + break; + } + // will throw error if step is not first div + i = steps[steps.indexOf(i) - 1]; + lastBuild.unshift(i); + } + // lastBuild now contains all the builds from the + // prior step except this one, so activate them + for (var j = 0; j < lastBuild.length; j++) { + var cel = lastBuild[j]; + cel.classList.add("active"); + body.classList.add("impress-on-" + cel.id); + } + } + el.classList.add("active"); body.classList.add("impress-on-" + el.id); @@ -469,10 +509,15 @@ // and the scaling is delayed, but when we are zooming out we start // with scaling down and move and rotation are delayed. var zoomin = target.scale >= currentState.scale; - - duration = toNumber(duration, config.transitionDuration); + + // built outs have no transition duration because that + // would delay any animation being done in the build + if (isBuild && !jumpStep ) { + duration = 0; + } else { + duration = toNumber(duration, config.transitionDuration); + } var delay = (duration / 2); - // if the same step is re-selected, force computing window scaling, // because it is likely to be caused by window resize if (el === activeStep) { @@ -527,6 +572,10 @@ // store current state currentState = target; activeStep = el; + if ( !isBuild ) { + lastBuild = new Array(); + } + lastBuild.push(el); // 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. @@ -785,6 +834,7 @@ window.addEventListener("resize", throttle(function () { // force going to active step again, to trigger rescaling api.goto( document.querySelector(".step.active"), 500 ); + api.goto( document.querySelector(".build.active"), 500 ); }, 250), false); }, false); |