The rectangle behind you

The source code for my Webstock 2017 slides

Marcin Wichary
The rectangle behind you
8 min readFeb 18, 2017

--

This is a slide deck that accompanied my presentation Charles Babbage’s mouse pointer, delivered at the Webstock conference in February of 2017.

These slides are provided for those who have seen the talk and might be curious about how the slides were made.

If you’re interested in seeing the talk, the video is available on Vimeo. Going through this slide deck is not a good substitute for watching the talk, since without my commentary the slides will be rather opaque. And, if you want a good starting point for making your own presentation in HTML, I made a template that might be easier than these slides.

General notes and principles

Those slides, like many of my slides, are in code, but they’re not meant to celebrate the fact that they’re in code. The programmatic parts are meant to be invisible and just aid in storytelling.

To that effect, I actually prepared most of the slides in Keynote, and then exported them as images and plugged into HTML. This is inexcusable in normal applications (zero accessibility), but permissible in this context — and easier for me, since creating every slide in HTML would be much more effort. (I only reserved “true” HTML/CSS/JS for the slides that are animated or interactive in some way.)

The whole presentation is shared here as finished. It is a lot of bad quality code, cobbled together for a specific purpose. You will see leftover rejected slides, uncommented code, hardcoded magic numbers, and other bad practices, and a lot of setTimeouts and !importants. This is, effectively, a very hacky prototype. (Which is perfectly normal and expected. You gotta do what you gotta do. If you haven’t read the account of the first iPhone keynote, it shares that very mindset.)

How to run this presentation on your computer

  1. Download the slides.
  2. Unpack the archive to a folder.
  3. Open index.html in your Safari. Note: This presentation is only tested on Safari and on 1280×720. I also only ran it on a Mac.
  4. Press 0 (zero) to go into full screen. Press right arrow key to advance to the next slide.

If you want to do it exactly how I did it…

  1. Go to Terminal and go to the folder where you unpacked the slides, e.g.
    cd ~/Downloads/webstock-2017.
  2. In the Terminal, start a web server with
    php -S localhost:4444 router.php
  3. Open Safari and go to localhost:4444.

Fun stuff on the slides

  • There’s a fake “laser pointer” on slide 35. It moves automatically. I am trying to simulate imperfect hand-holding using two CSS animations layered on top of one another. Check out laser-pointer in styles.less.
  • On the Pac-Man slide (61), click in to start the game. Then, you can press F to freeze ghosts, S to slow things down, or P to pause.
  • On some Mac/text mode slides, you can use Z to zoom in and out.
  • On text mode slides, press Tab to split letters or combine them back.
  • On the Mac/Windows/text mode slides, make sure you wiggle your mouse around.

I wrote before about my philosophy of having two awesome slides in each slide deck, and about secret keyboard shortcuts.

Source code directories

  • /: main HTML file with all of the content
  • /fonts: fonts
  • /images: images used in the interactive slides
  • /images-keynote: slides imported from Keynote
  • /js: my JavaScript and libraries I use
  • /pages: the iframe(s) used in the presentation
  • /styles: CSS/LESS file
  • /videos: video(s) embedded in the presentation

Possibly interesting details in code

  • This has only been tested on Safari in 1280×720. It’s really fun and freeing to code something for one browser and one resolution only. (However, I need to make sure to confirm the resolution with the organizers early on. Which is just one of the many questions I ask.) I would normally use Chrome, but this time around Safari seemed to have been faster with some transitions.
  • Once you open the presentation, you will see that the first slide is a slide with a Mac mouse pointer. This is not actually part of the presentation, but I put it there to remember to test it — I had a lot of trouble with operating system mouse pointer still showing up even after using cursor: none, so I wanted to remember to test it once plugging into the venue projector. Testing the presentation carefully is important to me.
  • At the bottom right of each slide, there’s a dead area, called focus-stealer in code. It serves two purposes: you can park your mouse pointer there and it’ll disappear (there’s nothing more annoying than a mouse pointer in the middle of the slide, distracting people). Also, for the slides with iframes, clicking on this dead area is the way to bring focus back to the presentation and be able to control it again.
  • Some later slides are designated to be optional “skip slides” (named skip-if-pressed-on-time in code). Those are here for a possible solution if I felt I was running short on time. Since running over is disrespectful to the audience and other speakers, I could then press the minus key and the presentation would skip slides I thought were less important. (I could always press +/equals key to undo this.) If you press either key, you will see a little indicator flash in the upper left corner, to quickly confirm things took effect for me (the speaker), but otherwise this is meant to be transparent to the audience. I wrote more about skip slides and bonus slides before.
  • For slide zooming, I use a CSS transition. I also use the nice CSS feature image-rendering: pixelated property to make sure pixels remain sharp as they’re zoomed in.
  • The CRT monitors are layered on top of other things and composited using mix-blend-mode: screen and made transparent to the mouse pointer with pointer-events: none.
  • The videos on slides 27, 28 and 33 are just one video, cropped in code. (See videostarttime and videoendtime.)
  • There are three types of transitions: cross-fade (used when the drawing of Difference Engine becomes real), slide (between Mac and Windows, between Windows and text mode), and half-slide (to juxtapose text mode with Mac on one slide). They’re implemented in a really hacky way using data-transition. Confusingly, I also use this transition “framework” to zoom Charles Babbage’s face on an early slide, and for the fake laser pointer.
  • The slides with three things across revealed one by one are not transitions or builds. They are just three separate slides. It’s just so much easier to do it this way.
  • All of the text mode screens are actually generated programmatically, not as images. You can see it in nortonScreens. This includes a weird way to change colours.
  • I used some of the fonts from the amazing collection of fonts from INT10h.org. I actually had to modify one font since some of the characters I needed could not be displayed in JavaScript. I modified the font using an application called Glyphs and you can find the Glyphs master file in fonts directory. There is probably overall a much easier way to accomplish this, but as I’m familiar with Glyphs, this was comfortable for me.
  • The slides that explain text mode have “sub slides” — those are slides with state. (See data-subslidecount and handleSubslide.) Those are pretty hacky. Going back within those essentially resets and replays them, which can be slow.
  • I like using a remote for presentation, but my remote started misbehaving, sometimes firing a lot of “next slides” keystrokes instead of just one. That’s why I implemented a little software debouncing routine in onKeyDown that doesn’t allow slides to advance faster than 450ms each. However, you can override it for testing by holding Shift.
  • The Norton Utilities mouse pointer is recreated using SVG because SVG seemed like a nice way to achieve scaling, and — more importantly — to be able to “colourize” the mouse pointer easily as needed. The two SVG files were created in Sketch.
  • The Pac-Man slide is an iframe. It is sometimes easier to just integrate an iframe, instead of incorporating the HTML inside the slide deck. Note that this causes focus issues as explained above. Also, the slides have a simple mechanism to preload/offload iframes for performance reasons.
  • Setting up a local web server was not be necessary in this case, but I do it out of habit — it’d be necessary in some cases, owing to CORS. I use PHP as a server, because it’s convenient. It is installed by default on a Mac; you can just go to a directory and type in php -S localhost:port to get an instant web server. It is much easier to set up than Apache, and it seems better than Python’s built-in server in handling multiple connections. However, it doesn’t handle streaming video very well, hence the router.php helper that was created by Rana Md Ali Ahsan and posted on GitHub.

Closing thoughts

Making slides in HTML is both frustrating and empowering.

Frustrating, because making slides in HTML forces you to care about many more things. As far as I know, there is no easy way to add scripting to Keynote or other presentation apps, so you can’t easily build on that — if you move to HTML, you have to recreate slide management, redo animations by hand, etc.

Empowering, because you can get creative and do all sorts of amazing things that are not available in Keynote and it enables all sorts of new ways of telling stories.

Let me know what you think! If you have specific questions about these slides, you can always find me on Twitter.

The rectangle behind you, a series of articles about interactive presentations.

By Marcin Wichary (@mwichary)

--

--