Responsive magazine using Turn.js

Creating a page turn effect is hard...very hard! There are lots of solutions that exist, but many of them miss the small details which make the turn animation look good. Here is a look at how to achieve it using the Turn.js plugin.



Turn.js is a plugin which allows you to quickly create a book or magazine using your images. However it has the extra detail such as shadows, highlights and drop shadows which make it look amazing.

Using a plugin is great, but it gets more tricky when you want to make the page responsive. Turn.js doesn't support it natively and there isn't much help out there in terms of examples. Here's how I achieved it!

The first step was to add a resize event handler to the window:

window.addEventListener('resize', function (e) {
    var size = resize(el);
    $(el).turn('size', size.width, size.height);
});

After that you need to set the page elements size based on the dimensions of the window but always keeping it at the book ratio:

function resize(el) {
    // reset the width and height to the css defaults
    el.style.width = '';
    el.style.height = '';

    var width = el.clientWidth,
        height = Math.round(width / this.ratio),
        padded = Math.round(document.body.clientHeight * 0.9);

    // if the height is too big for the window, constrain it
    if (height > padded) {
        height = padded;
        width = Math.round(height * this.ratio);
    }

    // set the width and height matching the aspect ratio
    el.style.width = width + 'px';
    el.style.height = height + 'px';

    return {
        width: width,
        height: height
    };
}

Then we have some css to control the responsive width and centering of the pages:

html, body {
    margin: 0;
    height: 100%;
}

body {
    background-color: #333;
}

body.hide-overflow {
    overflow: hidden;
}

/* helpers */

.t {
    display: table;
    width: 100%;
    height: 100%;
}

.tc {
    display: table-cell;
    vertical-align: middle;
    text-align: center;
}

.rel {
    position: relative;
}

/* book */

.book {
    margin: 0 auto;
    width: 90%;
    height: 90%;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

.book .page {
    height: 100%;
}

.book .page img {
    max-width: 100%;
    height: 100%;
}

You can view the fully working responsive magazine example here:

http://jsfiddle.net/GGea5/1246/

And a second version showing only single pages:

http://jsfiddle.net/kmturley/GGea5/32/

Hope that's useful!