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

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.)

MikeLo (not verified)

Sat, 2017-09-02 00:09

Congratulations, you converted an amazing fluid page into powerpoint slides. This is like going a thousand steps back. And also, you converted what was supossed to be highly scalable into fixed patches, a clasic Win-OS style. Well done. In your next project you might want to print the slides to be prjected against the light just like in the 60s.

Haha. Yeah, that's true!

But I would claim my work didn't really make it PowerPointish until I recently added substeps, with request from the community, as covered in my newest blog post.

As for the "classic-slides" demo, that you see in this post, that one is intentionally made to look just like old school slides, because that's often what people want and where they start. I felt it was a more approachable starting point for some. Also, it is a valid question to ask, whether it is possible to migrate existing PowerPoint presentations to impress.js. The answer is yes.

Personally, I'd only actually do such a presentation if I was in a hurry and it's not an important presentation to a big audience. As you can see, the other example presentations in the repository do not try to look like PowerPoint presentations at all.

It's unclear to me what you mean with the fixed patches? I agree it is unfortunate that the upstream impress.js has not had any new development for years. Git and Github makes it relatively easy to deal with the situation (no patches), but I know it would make a lot of users happy if we could get some life back into the official impress as well.

Add new comment

The content of this field is kept private and will not be shown publicly. Cookie & Privacy Policy
  • No HTML tags allowed.
  • External and mailto links in content links have an icon.
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
  • Use [fn]...[/fn] (or <fn>...</fn>) to insert automatically numbered footnotes.
  • Each email address will be obfuscated in a human readable fashion or, if JavaScript is enabled, replaced with a spam resistent clickable link. Email addresses will get the default web form unless specified. If replacement text (a persons name) is required a webform is also required. Separate each part with the "|" pipe symbol. Replace spaces in names with "_".
About the bookAbout this siteAcademicAccordAmazonBeginnersBooksBuildBotBusiness modelsbzrCassandraCloudcloud computingclsCommunitycommunityleadershipsummitConsistencycoodiaryCopyrightCreative CommonscssDatabasesdataminingDatastaxDevOpsDistributed ConsensusDrizzleDrupalEconomyelectronEthicsEurovisionFacebookFrosconFunnyGaleraGISgithubGnomeGovernanceHandlerSocketHigh AvailabilityimpressionistimpressjsInkscapeInternetJavaScriptjsonKDEKubuntuLicensingLinuxMaidanMaker cultureMariaDBmarkdownMEAN stackMepSQLMicrosoftMobileMongoDBMontyProgramMusicMySQLMySQL ClusterNerdsNodeNoSQLodbaOpen ContentOpen SourceOpenSQLCampOracleOSConPAMPPatentsPerconaperformancePersonalPhilosophyPHPPiratesPlanetDrupalPoliticsPostgreSQLPresalespresentationsPress releasesProgrammingRed HatReplicationSeveralninesSillySkySQLSolonStartupsSunSybaseSymbiansysbenchtalksTechnicalTechnologyThe making ofTransactionsTungstenTwitterUbuntuvolcanoWeb2.0WikipediaWork from HomexmlYouTube