Skip to content

Instantly share code, notes, and snippets.

@lavallee
Created April 8, 2012 22:41
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save lavallee/2340157 to your computer and use it in GitHub Desktop.
Save lavallee/2340157 to your computer and use it in GitHub Desktop.
Working with impress.js
/*
If you want more control over impress.js, the first thing is to change the way you call it. The demo
initializes impress.js like this:
<script src="js/impress.js"></script>
<script>impress().init();</script>
You want to change this to the following:
<script src="js/impress.js"></script>
<script>
var api = impress();
api.init();
</script>
The key difference here is that you now have a JavaScript variable called api that you can call
impress's methods on. The full documentation is in impress's index.html, but in short, you now have
api.next(), api.prev(), and api.goto() for moving around the slideshow.
For timing the transitions between slides, you can use two functions that are part of JavaScript
itself; no need for jQuery or anything. These functions are setInterval() and setTimeout(). They both
take two arguments: a thing to call, and a delay (in milliseconds) to wait before calling it.
setInterval() will call your thing over and over again; setTimeout() will call it once.
For instance, if you make the changes above, the simplest thing you can add is an auto-advancing
interval, like so:
setInterval(api.next, 5000);
That will move to the next slide every 3 seconds.
It's important to note the difference between passing a function or method by name, like api.next,
versus actually calling the method: api.next(). Those parentheses tell JavaScript to actually
call/invoke the method. Another way to deal with this is to pass the name of the function as a string,
which is what the w3schools example does: http://www.w3schools.com/jsref/met_win_setinterval.asp .
That works in their examples, but I think it's better to understand passing a function vs. calling it,
and know when to use which.
As the w3schools example makes clear, you can pass your own functions to setInterval() and
setTimeout().
The other thing was attaching additional functionality to specific slides, like being able to redirect
to another page on the last slide, or load a video on a given slide.
There are a bunch of ways to do this. A key thing we discovered this week is that impress.js adds
classes to a slide when visible, and removes them when not visible. All slides receive the classes
"step" and "slide". The current slide additionally receives "active" and "present". Previous slides all
have "past" and upcoming slides all have "future".
Therefore, if you give your all your slides ids, like "slide2", it's just a matter of knowing when
"slide2" has the "active" class. There's a simple jQuery method, hasClass() that provides this
functionality: $("#slide2").hasClass('active') . Conversely, you can find out which slide is currently
active by looking up the "active" class and finding the corresponding element id: $('.active').attr('id')
(impress.js does not rely on jQuery, so you need to load it separately.)
One way to track the slide transitions and current slide is to use setInterval() to see what the
current slide is every so often, and so something when appropriate. Here's some barebones code that
does just that:
*/
function handleCurrentSlide() {
var currentSlide = $('.active').attr('id');
if (currentSlide === 'slide2') {
console.log('on slide 2!');
} else if (currentSlide === 'slide3') {
console.log('on slide 3!');
}
}
setInterval(handleCurrentSlide, 200);
/*
Here, handleCurrentSlide() is called 5 times a second, and logs when you're on slide2 or slide3, but
not slide1. There's an obvious flaw in the code as-is. It will log to the console every time it runs,
regardless of whether it's a new slide or not. That is almost always NOT what you want.
One way to improve this is to keep track of what slide the user was on the last time the function ran,
and only do things when the previous slide and current slide are different, indicating a slide change:
*/
var previousSlide;
function handleCurrentSlide() {
var currentSlide = $('.active').attr('id');
if (previousSlide !== currentSlide) {
if (currentSlide === 'slide2') {
console.log('on slide 2!');
} else if (currentSlide === 'slide3') {
console.log('on slide 3!');
}
}
previousSlide = currentSlide;
}
setInterval(handleCurrentSlide, 200);
/*
The lines involving previousSlide were the only ones I added.
That gets the job done, but it's a little inefficient. After all, your code is constantly checking to
see if something has changed, instead of just being told when it changes, kind of like Kramer and
Moviefone: http://www.youtube.com/watch?v=qM79_itR0Nc#t=15s .
JavaScript has a great mechanism for code to trigger and respond to events, and impress.js uses this
internally to make things work. With jQuery, it's easy to hook into events using on(). Here's an
example that does roughly the same thing, but only gets called when a slide transition actually occurs:
*/
$(document).ready(function() {
$(document).on('impress:stepenter', function(e) {
var currentSlide = $(e.target).attr('id');
if (currentSlide === 'slide2') {
setTimeout(api.next, 2000);
} else if (currentSlide === 'slide3') {
window.location = 'http://www.google.com/';
}
});
});
/*
Here, when the user gets to the second slide, it will automatically advance to the third slide after 2
seconds, and the third slide will result in redirecting the user to Google.
There are a TON of ways to improve this but this should work well enough for your case.
I think combining setInterval()/setTimeout() with knowing when a user lands on a slide should make a
lot of things possible.
*/
@creativetim
Copy link

I wanted to make my presentation play automatically on a continuous loop without using jQuery and came away with the following:

document.addEventListener('impress:stepenter', function(e){
  if (typeof timing !== 'undefined') clearInterval(timing);
  var duration = (e.target.getAttribute('data-transition-duration') ? e.target.getAttribute('data-transition-duration') : 2000); //use the value set or default to 2000
  timing = setInterval(api.next, duration);
});

@xBlazeTECH
Copy link

@creativetim I submitted an issue with that, as a feature! I do not know if he will add it or if it has been added, as I am a novice programmer, and am just learning javascript.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment