I’ve been social distancing for a while now and I’m working from home full time. I live in an old building with unreliable internet but, using a LAN cable, I get by most of the time. I disable my video and avoid sharing my screen wherever possible. However what happens when I need to present something to my team? Well, then my colleagues get a pixelated presentation and the occasional drop from their host.
The UX designer in me thinks this is less than ideal. I spend considerable time putting presentations together and they deserve a proper delivery. I started to wonder if there was a better way to deliver slide decks — one that didn’t involve sharing my screen.
PowerPoint and me are not friends. My slide decks are normally minimalist. They feature a title, an image, some code or an emoji per slide and that’s about it. Almost always these elements are centered in the middle of the slide and when working in PowerPoint, I would find myself spending most of my time scaling images to fit the slide.
Whilst building out my personal website last year in Gatsby, I came across
gatsby-theme-mdx-deck. As its name suggests, this theme takes MDX and turns it into slide decks — it was the PowerPoint alternative I was looking for.
The first step is to add
gatsby-theme-mdx-deck to your gatsby config:
The plugin expects a location where your MDX files are located and a basepath on where your decks should be found on your site.
In the folder I specified as the content path, I create a new
.mdx file and add the following:
You’ll see at the top of the file I have frontmatter that acts much like meta data, I query this data to show you information about the presentation you are about to open. The theme reads three dashes in a row as a signal to split the document and create a new slide. The above code outputs the following three slides when run:
That was easy! I can then navigate to
/decks and surf through these slides using my arrow keys.
Another cool part to this is that your slides are hosted on a website. You can give anyone the URL and they can recap your slides at a later date. This method is how I built version one of my presentations page.
This was when I had a sudden idea: When I give a presentation, my slide decks are already hosted. Why don’t I just send people to the URL and let them “follow along” as I present?
This takes the pressure off my bandwidth and instead pushes it off to each individual client. Yes, it means they have to download the slide assets, but this load is far smaller than streaming video — everyone wins. It also gives me the ability to add far more interactive elements to my slides to keep interest from viewers.
In order to start working on this library I moved it from my
node-modules folder into a folder called
plugins. Gatsby knows that this folder contains any local versions of plugins that I am working on.
The first thing I wanted to do was make the way in which you interact with the slide decks more obvious. When you navigate to a slide deck there are no instructions and no interact-able elements. I decided that I should add the following buttons:
Note that the toggle button will only be present when I am presenting a talk. When I am not, you get control of the slides!
In the situations when I am not around to give you the tour of how these buttons work, I thought I would let
react-joyride do it for me. I decided to use a cookie to determine whether the user had seen the tour before. I would only trigger the tour if that cookie had not been set:
I tried to keep the instructions short and sharp. You can check it out by checking out one of my presentations.
In order to get this to work I was going to need two new features — an internal state to monitor the position in the slides for viewers and a way of sending realtime updates from my machine. A Redux + Socket.IO combination would do nicely.
Up to this point my personal website had been entirely static. I had had no need to introduce internal state on any other page so I consulted the Gatsby docs on the subject. That combined with this awesome repo on Redux and Socket.IO combined, gave me all the pieces I needed to create the feature — I just had to bring them together.
I spun up a Node.js server on and added the following code:
First we need to add a custom wrapper around Gatsby:
This wrapper needs to wrap our site content in a Redux provider.
In our store we add methods to handle any incoming actions from the server. Notice the
socketIoMiddleware that catches any actions that start with
/server and emits them to our server.
Now if we connect any component using Redux we will have access to these values.
And just like that we can now control slide decks remotely!
I recently attended a conference called “HalfStack”. While I was there I saw a demo of PoseNet. An awesome library that uses a model to identify key body parts from an image or video. I thought it would be cool to use this library to create touch-free slide navigation for presenters using just their gestures.
PoseNet uses a trained model to take an image and make an attempt at guessing the location of key body parts in that photo. You can see how, in the preview below, the skeleton is very closely matching my actual position — I was super impressed with its accuracy.
Being a magician! 🎩
It can be implemented relatively easily (code borrowed from Kirsten Lindsmith’s “PoseNet for React” repo on GitHub):
Now what this gives us access to is an array of keypoints. Each point represents a body part, PoseNet’s estimate of where that body part is and its confidence score.
For my purposes, I focused on the wrists. When gesturing right or left, both wrists are close together and in a specific portion of the screen.
When both wrists were in the same box, I knew I was gesturing for a slide change.
All that was left was to work out whether my poses array containing the positions of the left and right wrist had placed them both in the bounding box. I could then use my socket connection as above to change the slide.
I hope you have enjoyed this little experiment. If you have questions or want to join me on some of my other adventures you can find me at sld.codes.