3D CSS3 Book Generator with jQuery

3D CSS3 Book Generator with jQuery

17 195
3D CSS3 Book Generator with jQuery

3D CSS3 Book Generator with jQuery

Today we made up my mind to develop something really interesting and useful for you. A new jQuery plugin – as a generator of books. The main idea is to display user friendly book basing on raw text (with images). The book consists of pages, each page consists of 2 sides (as in a usual book), there are buttons Back-Next at the sides of pages to navigate through the pages, and when we turn the pages we see that the pages are turned in 3D (powered by CSS3). In order to achieve this 3D effect we use CSS3 transform (rotate3d, preserve-3d and rotateY) and transition effects.

Live Demo

Step 1. HTML

As we told, our HTML markup is a raw text with image (as a cover of our book). But you can use everything you want here:

index.html

<div class="book">
    <img src="book.jpg" alt="JavaScript Programmer's Reference" style="display:block" />
    <h2>JavaScript Programmer's Reference</h2>
    <h4>Cliff Wootton</h4>
    <h4>Wrox Press Ltd.</h4>
    <div>JavaScript Programmer's Reference</div>
    <h3>About the Author</h3>
    <div>Cliff Wootton lives in the south of England and works on multimedia systems and content management software for large data driven web sites. Currently he is developing interactive TV systems for BBC News Online in London ( http://www.bbc.co.uk/news ) and previously worked for other commercial broadcasters on their web sites. Before that he spent several years developing geophysical software and drawing maps with computers for oil companies.</div>
    <div>Cliff is married with three daughters and a growing collection of bass guitars.</div>
    <h3>Acknowledgements</h3>
    <div>It's hard to believe I've actually reached the stage of writing the introductory pages to this book. It's been a long process and I don't think I would have reached this point without the help of Tim Briggs at Wrox, who very gently urged me onwards and gave me encouragement when I needed it.</div>
</div>

Step 2. CSS

Now we have to define general CSS3 styles for our book:

style.css

body {
    background: url('background.png') no-repeat center center fixed;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover;

    /* CSS3 perspective and transform */
    -webkit-perspective: 1800px;
    -moz-perspective: 1800px;
    -moz-transform-style: preserve-3d;
    -webkit-transform-style: preserve-3d;
}

.book {
    left: 530px;
    position: absolute;
    top: 70px;
    width: 400px;

    /* CSS3 transform */
    -webkit-transform: rotate3d(0, 0, 1, 0deg);
    -moz-transform: rotate3d(0, 0, 1, 0deg);
    -webkit-transform-style: preserve-3d;
    -moz-transform-style: preserve-3d;
}

.page {
    background-color: #fff;
    position: absolute;

    /* CSS3 transform */
    -webkit-transition: all 1s ease-in-out 0s;
    -moz-transition: all 1s ease-in-out 0s;
    -webkit-transform-style: preserve-3d;
    -moz-transform-style: preserve-3d;
}

.side:first-child {
    background: -webkit-linear-gradient(-45deg, #fff 0%, #ddd 100%) repeat scroll 0 0 transparent;
    background: -moz-linear-gradient(-45deg, #fff 0%, #ddd 100%) repeat scroll 0 0 transparent;
    border-left: 2px solid #000;
    height: 500px;
    overflow: hidden;
    padding: 30px 35px 80px 35px;
    position: absolute;
    width: 400px;

    /* CSS3 transform */
    -webkit-transform: translate3d(0px, 0px, 0.5px);
    -moz-transform: translate3d(0px, 0px, 0.5px);
}

.side:last-child {
    background: -webkit-linear-gradient(-45deg, #fff 0%, #ddd 100%) repeat scroll 0 0 transparent;
    background: -moz-linear-gradient(-45deg, #fff 0%, #ddd 100%) repeat scroll 0 0 transparent;
    border-right: 2px solid #000;
    height: 500px;
    overflow: hidden;
    padding: 30px 35px 80px 35px;
    position: absolute;
    width: 400px;

    /* CSS3 transform */
    -webkit-transform: rotateY(180deg);
    -moz-transform: rotateY(180deg);
}

button {
    margin-top:10px;
    float:right;
    cursor:pointer;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 14px;
    color: #050505;
    padding: 10px 20px;
    background: -moz-linear-gradient(
        top,
        #fff 0%,
        #ebebeb 50%,
        #dbdbdb 50%,
        #b5b5b5);
    background: -webkit-gradient(
        linear, left top, left bottom, 
        from(#fff),
        color-stop(0.50, #ebebeb),
        color-stop(0.50, #dbdbdb),
        to(#b5b5b5));
    -moz-border-radius: 10px;
    -webkit-border-radius: 10px;
    border-radius: 10px;
    border: 1px solid #949494;
    -moz-box-shadow:
        0px 1px 3px rgba(000,000,000,0.5),
        inset 0px 0px 2px rgba(255,255,255,1);
    -webkit-box-shadow:
        0px 1px 3px rgba(000,000,000,0.5),
        inset 0px 0px 2px rgba(255,255,255,1);
    box-shadow:
        0px 1px 3px rgba(000,000,000,0.5),
        inset 0px 0px 2px rgba(255,255,255,1);
    text-shadow:
        0px -1px 0px rgba(000,000,000,0.2),
        0px 1px 0px rgba(255,255,255,1);
}

Step 3. HTML5 JavaScript

Now, the most important step – javascript code (of our jQuery generator plugin), please create an empty script.js file and paste the next code:

script.js

// Goto page function
function gotoPage(i) {
    $('.page').eq(i).removeClass('active');
    if ((i-1) >= 0) {
        $('.page').eq(i-1).addClass('active');
    }
}

// Wrap everything as a jQuery plugin
(function($){
    $.fn.extend({
        EbookTransformer: function(options) {
            var defaults = {
                height: 400
            };
            var options = $.extend(defaults, options);

            // The book object
            var objBook = $(this);

            // Inner variables
            var vPages = new Array();
            var vSides = new Array();
            var vSubObj = new Array();
            var iTmpHeight = 0;

            // initialization function
            init = function() {
                // Walk through all the objects of the book, and prepare Sides (for Pages)
                objBook.children().each(function(i){
                    if (iTmpHeight + this.clientHeight > options.height && vSubObj.length) {
                        vSides.push(vSubObj);
                        vSubObj = new Array();
                        iTmpHeight = 0;
                    }

                    iTmpHeight += this.clientHeight;
                    vSubObj.push(this);
                });

                if (iTmpHeight > 0) {
                    vSides.push(vSubObj);
                }
                $(vSides).wrap('<div class="side"></div>');

                // Prepare Pages (each Page consists of 2 Sides)
                var iPage = 1;
                var vCouples = Array();
                objBook.children().each(function(i){
                    // Add Next and Prev buttons
                    if (vCouples.length == 0) {
                        $(this).append('<button onclick="gotoPage('+iPage+')">Next page</button>');
                    }
                    if (vCouples.length == 1) {
                        $(this).append('<button onclick="gotoPage('+(iPage-1)+')">Previous page</button>');
                    }
                    vCouples.push(this);

                    if (vCouples.length == 2) {
                        vPages.push(vCouples);
                        vCouples = new Array();
                        iPage++;
                    }
                });
                if (vCouples.length == 1) {
                    vCouples.push($('<div class="side"><h2>The end</h2><button onclick="gotoPage('+(iPage-1)+')">Previous page</button></div>')[0]);
                    vPages.push(vCouples);
                }
                $(vPages).wrap('<div class="page"></div>');

                // Add extra CSS for the pages
                var sExtraCSS = '';
                objBook.children().each(function(i){
                    //alert(i); // 0 .. 2
                    sExtraCSS += ''+
                    '.page:nth-child('+(i+1)+') {'+
                    '-moz-transform: translate3d(0px, 0px, -'+i+'px);'+
                    '-webkit-transform: translate3d(0px, 0px, -'+i+'px);'+
                    '}'+
                    '.active:nth-child('+(i+1)+') {'+
                    '-moz-transform: rotateY(-179deg) translate3d(0px, 0px, -'+i+'px);'+
                    '-webkit-transform: rotateY(-179deg) translate3d(0px, 0px, -'+i+'px);'+
                    '}';
                });
                $('.book').append('<style>'+sExtraCSS+'</style>');
            };

            // initialization
            init();
        }
    });
})(jQuery);

// Window onload
jQuery(window).load(function() {
    $('.book').EbookTransformer({height: 480});
});

The main idea is similar which we used in my jQuery pagination tutorial. This idea is to parse all the input data (our raw text) and compose a new HTML structure for our 3D book. In the first step we go through all the inner elements, and turn them into Sides (for our pages). We should check for heights of inner elements, and, in case if total height of a side elements is more than max allowed, we start collecting the next side. In the second step we turn the result Sides into pages. Each page consists of a couple of Sides. Also we add the navigation buttons in the second step. And finally, to position the pages one on top of another we have to compose extra CSS styles (on fly). We use CSS3 translate3d property to prepare custom styles (with different Z value) for all the generated pages.


Live Demo

Conclusion

The future is getting closer. I hope that everything is clean for today. If you have any suggestions about further ideas for articles – you are welcome to share them with us. Good luck in your work!

SIMILAR ARTICLES


17 COMMENTS

  1. Thats awesome man! Great idea, and it looks good. I did notice that some of the text was a little off after going through the pages in firefox v15 but it wasnt by much. Its still an awesome effect and feature!

  2. Hi Andrew,
    A very good example, Thank you.
    It is possible for a large number of pages, you will need on the last page of the link on the first page.
    I added a little in css
    .book img {width:330px; margin: 0 auto;}

    • Hello Viktor,
      Yes, I think that it should work for a pretty big books. I haven’t checked it yet, but I hope.
      and, if you want to put back link to the first page, you can try to add it.

  3. Hi,your work is so cool! I like it very much.
    But it has problem. This does not work on IE.Can you do this work!

  4. Hi Admin,

    I tried this plugin, but when I click the next page button, the page posts back and because of that the CSS effects are not working!
    Any comments?

    Thanks

    • Hi Raja,
      It should work only with the most modern browsers (FF, Chrome, Safari). You should know, that css3 transitions don’t work in IE browser.

  5. Hello Andrew, you have such a wonderful tutorials. But i want you to help out with some codes for online shopping cart i want to add to my website.
    Will highly appreciate it.
    Thanks.
    George.

Leave a Reply