Embedding Revealjs

Filed under: JavaScript

Providing easy-to-follow tutorials is a major goal for this site. I’ve embedded revealjs, a JavaScript presentation framework, into the custom WordPress theme that I’ve built for this site.

Unlike other sites, I have zero plans to inject ads into the slides. The whole point of the slideshow is to present step-by-step instructions in an easy-to-consume format.

Slides make it easier to follow a long list of instructions than the default vertical scrolling behavior of a web page. Once you finish a step click the next arrow or use a touch screen with the sliding gesture.

Sample Slide show.

Double click on any of the steps below that have the angled arrows in the top right corner to open the slideshow.

Step One

Click on this box to open the slide show.

Step Two

Think of all the cool tutorials you could create in this format

Step Three: Think big

How to open desktop and add a new graphic’s card, build a bike, build a blog, build an empire

Step Four: Think of some clever memes

??? Profit

Step Five: Escaping the Alternate Reality

Press the esc button

The code that helps to create this effect.

You need to change RevealJS slightly to get this to work as it relies on injecting the slides inside a custom modal that takes over the whole screen, var modal = $("<div class='bg'>");.

In the RevealJS CSS you need to replace the body tag that generates the background with a custom class. I do this using gulp and gulp-replace npm modules, .pipe(replace("body {\n background:", ".bg {\n background:"). This will apply the gradient background to a modal rather than whole HTML page.

What the script below does is find all the <section> tags within a .slides css class. The script clones all the section nodes and injects them into a modal dialog. This keeps RevealJS isolated within your web page. The default behavior of RevealJS is to basically take over your page.

The script adds a click handler to the original <section> tags in the page. When one of the sections is clicked, it will pull in the reveal.js file if the script is not loaded, then open up the slide show.

It also binds to the esc key so that a user can get back to the regular article.

 /**
  * <div class="slides"> 
  *      <section> 
  *           Slide 1
  *      </section>
  * </div>
  *
  * You'll also need to adjust the default styles of reveal and apply a css class to the page
  * rather than appling the background styles to the body / html tags of the page
  * https://gitlab.com/badmishkallc/wp-bad-mishka-theme/blob/master/src/gulpfile.js
  */

    // TODO: remember scroll position
    // TODO: remember the last slide the user was on.
    var base = "/";
    var registerReveal = function() {
        // keep a copy of the original dom in memory before augmentation.
        var slidesClone = slides.clone();
        // create a slide to let the user know they can esc out of the slideshow.
        var startSlide = $("<section class='slide'>");
        var h1 = $("article > h1").clone();
        startSlide
            .append(h1)
            .append("<p>To end the slideshow at any time press the <strong>esc</strong> button.</p>");
        revealStates = {
            init: "init",
            initializing: "initializing",
            loading: "loading",
            loaded: "loaded",
            ready: "ready",
            rendering: "rendering",
            rendered: "rendered"
        };
        slides.on('click', function(){
            var state = mk.reveal.state;
            // initialize the state if none exists. 
            if(!state)
                mk.reveal.state = revealStates.init;
            // if the user clicks too many times ignore.
            if(state !== revealStates.init && state !== revealStates.ready) {
                return;
            }
            if(mk.reveal.state !== revealStates.ready)
                mk.reveal.state = revealStates.initializing;
            mk.reveal(); 
        });
        slides.css({
            "cursor": "pointer"
        }).attr("title", "Double click on the section to show slideshow")
        mk.reveal = function() {
            var state = mk.reveal.state || revealStates.init;
            mk.rev
            if(state === "loading") {
                return;
            }
            var base = "/wp-content/themes/bad-mishka/"
            var stylesheet = null;
            var render = function() {
                if(mk.reveal.state != revealStates.ready &&
                    mk.reveal.state != revealStates.loaded) {
                    var state = mk.reveal.state;
                    if(state == revealStates.init || state == revealStates.rendered ||
                    state == revealStates.rendering) {
                        return;
                    }

                    setTimeout(render, 300);
                    return;
                }
                mk.reveal.state = revealStates.rendering;

                layout = mk.ui.loadStyleSheet(base + "css/reveal/index.css");
                theme  = mk.ui.loadStyleSheet(base + "css/reveal/default.css");
                var modal = $("<div class='bg'>");
                var slides = $(".slides section");
                var reveal = $("<div class='reveal'>");
                var show = $("<div class='slides'>");

                reveal.append(show);
                show.append(startSlide);
                show.append(slides.clone());
                modal.append(reveal);
                modal.css({
                    zIndex: 9999,
                    position: "absolute",
                    top: 0,
                    bottom: 0,
                    left: 0,
                    right: 0
                });
                $(document.body).append(modal);
                Reveal.initialize({
                    keyboard: {
                        27: function() {

                            if(theme) {

                                modal.remove();
                                head.removeChild(layout);
                                head.removeChild(theme);
                                stylesheet = null;
                                mk.reveal.state = revealStates.ready;
                            }
                        }
                    }
                });
                mk.reveal.state = revealStates.rendered;
                debug("[reveal]" + mk.reveal.state);
            };
            if(state === revealStates.initializing) {
                mk.reveal.state = revealStates.loading;
                debug("[reveal]" + mk.reveal.state);

                var deps = [
                    base + "js/reveal.js"
                ];
                $.getScript(base + "js/reveal.js", function() {
                    mk.reveal.state =  revealStates.loaded;
                    debug("[reveal]" + mk.reveal.state);
                    render();
                });
            }
            if(mk.reveal.state === revealStates.loaded || mk.reveal.state === revealStates.ready) {
                render();
            }
        };
    };
    var slides = $(".slides section");
    if(slides.length > 0) {
        registerReveal();
    }
Nerdy Mishka