Features I've added to Impress.js (and the Plugin API)

hingo's picture

This is the third post in my series of blog posts on Impress.js. As I've already mentioned, I've also written some new code to impress.js. Now I want to finally present the new features I've added (currently available in my github fork).


The historical context for these additions is that Bartek Szopka, the original creator of Impress.js, wrote it in 2012. After a few iterations, he was happy, and lots of users were happy. Impress.js became one of the most popular projects on github, but in the meantime Bartek has been busy doing some other work. Still today Impress.js is pretty much exactly the same as it was in 2012.

This wasn't a big problem, because in some ways Impress.js was complete, and people were using it to do awesome presentations. But some people also wanted to add features. While Bartek wasn't actively working on it anymore, he did have a clear architectural vision for Impress.js. One imperative was not to add "yet another feature" to the code, rather to have a more modular system so that features could be added without bloating the core rendering code. But, as Bartek wasn't actively working on the code, there wasn't anyone to add such a plugin api. So pull requests accumulated, but couldn't be committed, because of a lack of a plugin api.

Last year I decided to do something about this. I like nice architectures, and also I thought it just makes sense to respect the architectural vision of the creator of the project. The original Impress.js code in fact already included a hint towards a plugin API. The code that provided navigation between slides - such as by pressing arrow keys - was a separate plugin. Of course it was a rather important plugin, as without it a normal user could only ever see his first slide and not move to the other ones!

Taking a queue from that, I proceeded to break out that plugin into a separate file, and then generalized the approach so that other plugins could be created the same way. Bartek briefly looked at what I had done, and didn't protest. (After all, it was his creation too, I just generalized it.

Impress.js now has a plugin API!

I won't describe the plugin API in detail in this post, rather I want to focus on what new features I've added that end users will benefit from. But the basic idea is pretty simple: plugins are independent pieces of javascript code, wrapped in those idiomatic (function(){ ... })(); enclosures so as not to pollute the global namespace. Most plugins become activated asynchronously, by listening to events triggered by the core impress.js code: impress:init, impress:next and impress:prev. When I understood how Bartek had intended it to work, I was quite impressed by the simplicity and minimalism of it all!

If you want to know more about the details of the plugin API, the Plugins README should be a good read for you.

New features available as plugins

So, in addition to the basic navigation being a plugin, what new features are available?

Relative positioning

This was perhaps the most wanted feature, and had been implemented in a non-plugin way both by myself and several others before. Also some wrapper utilities like Hovercraft provide it: Positioning slides relative to the previous slide, instead of using absolute positioning coordinates.

The use case for this is pretty simple to explain: Imagine you have 20 slides, and you need to add one to the middle. You now need to adjust the positioning of the 10 last slides, to make room for the new one. Very tedious! With relative positioning, you just add a slide, and maybe that's it, or at the most you need to maybe adjust the slide right after it.

In addition, my implementation of this also makes slides by default inherit the positioning attributes of the previous slide. So if you're lazy, you can just set data-rel-x="1000" on the first slide, and after that, every slide will be 1000 pixels to the right of the previous one!

The rel plugin now provides relative positioning attributes, like this:

    <div class="step" data-rel-x="1000" data-rel-y="1000" data-rel-z="10" data-rotate="45">

(The rotation attributes cannot be relative, it didn't quite make sense. Or if you think it does, it can be added in the future.)


This is a really simple plugin, that I added mostly to make a point. The Autoplay plugin is another kind of navigation plugin, in the sense that it moves forward in the presentation. But instead of moving when user presses an arrow key, it moves after a given time.

You use the data-autoplay attribute to set the number of seconds after which presentation moves to next slide. This can be done for each div.step or globally for the div#impress.

I've used the autoplay feature for some demos. I find it annoying that once I use it, I cannot stop it. I plan to add a play/pause button where the user can control this.

Navigation UI

To show off some GUI widgets, I added a toolbar where you can click on the mouse to navigate between the slides too. So now we have 3 navigation plugins to choose from! The power of modular architecture...

Demo presentation

I've also added a new demo presentation to show off these new features. (It also shows off some "extra plugins", which I didn't cover in this blog post.)

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Use [fn]...[/fn] (or <fn>...</fn>) to insert automatically numbered footnotes.
  • Allowed HTML tags: <h1> <h2> <h3> <h4> <p> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <br> <sup> <div> <blockquote> <pre> <img>
  • Lines and paragraphs break automatically.
  • Web page addresses and e-mail addresses turn into links automatically. (Better URL filter.)

This question is for testing whether you are a human visitor and to prevent automated spam submissions.
10 + 3 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.