Flipping Book Animation 3D Using CSS3 and JavaScript

Introduction

In this article, we will create a flipping book animation using CSS3 and JavaScript. This article assumes the reader is familiar with basic CSS3 and JavaScript syntax and styles. This flipping book effect can be used to design an entire website on this style or any specific section of the website. Mostly storytelling websites fit very well with this effect. So let's start building this effect.

Flipping Book Animation

Flipping book animation is an effect that emulates a page transition effect of a book. Use the following procedure to implement this effect.

First, we need to fix our camera. That is the distance between the user and the book. This is done using the perspective property of CSS3.

Now we have our camera fixed. The next task is to design a binding line of the book around which pages will turn. To do this first we need to change the flat web page to 3D view. This can be done using the transform style property of CSS3 and setting it to "preserve-3D". To add a bit of "book placed on the floor" effect I'm translating the Z axes away from the viewer and then rotating it by 45 degrees.

The next task in the list is to add pages to the book. Each page is represented as a div. To convert a box into a 3D page we need to apply a CSS3 transformation known as origin shift. Let's shift the origin of the pages to their left edge. This means that all the transformations will consider the left edge as the origin of transformation and that really simplifies our task.

Now we have our camera ready, book ready and the action is about to begin!

For the action part, we need to use JavaScript. Using JavaScript we will detect the left/right navigation and then turn the pages accordingly. Detecting keys is very easy and can be done by binding the "key-down" event to the document. The next interesting move is to turn the pages, well that's also very simple; just remember the rotate function of CSS3 and apply it with an angle of rotation equal to 180 degrees for the right to left and 0 degrees for the left to right. Here 0 degrees is not equal to -180 degrees since we are working in a 3D space. -180 degrees will rotate the page at the back of the book and this is not what we want so we need to use zero degrees to reset the rotation of 180 degrees.

So far so good! We are almost done but our JavaScript needs some tweaks for handling notorious user key inputs like if someone is turning the book page on the right when they all are already on the right side or vice versa. To handle such situations we will maintain the two stacks, one is for the left side book pages and the other is for the right-hand side book pages. Initially, the left side stack will be empty since the book is in a closed state. When the right side stack goes empty, it will indicate the closing of the book. So, in a nutshell, we need to take one page from the right stack and push it into the left stack or vice versa.

And here we go for the action! Copy and paste the following code.

HTML

<!DOCTYPE html>
<html>
<head>
  <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="camera">
    <div id="galry">
      <div id="pic1" class="pic">
        <img src="http://goo.gl/qePIfH" alt="Front page" width="450" height="450"/>
      </div>
      <div id="pic2" class="pic">
        <img src="http://goo.gl/hMf61G" width="450" height="450"/>
      </div>
      <div id="pic3" class="pic">
        <img src="http://goo.gl/hMf61G" width="450" height="450"/>
      </div>
      <div id="pic4" class="pic">
        <img src="http://goo.gl/hMf61G" width="450" height="450"/>
      </div>
      <div id="pic5" class="pic">
        <img src="http://goo.gl/hMf61G" width="450" height="450"/>
      </div>
      <div id="pic6" class="pic">
        <img src="http://goo.gl/AIHPPn" width="450" height="450"/>
      </div>
    </div>
  </div>
</body>
</html>

CSS

#camera {
  -webkit-perspective: 500px;
}

#galry {
  position: absolute;
  top: 100px;
  left: 50%;
  border: 1px solid black;
  width: 1px;
  height: 450px;
  -webkit-transform: translateZ(-100px) rotateX(45deg);
  -moz-transform: translateZ(-100px) rotateX(45deg);
  -o-transform: translateZ(-100px) rotateX(45deg);
  -ms-transform: translateZ(-100px) rotateX(45deg);
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  -ms-transform-style: preserve-3d;
  -o-transform-style: preserve-3d; /* not supported 12+ */
}

.pic {
  margin: 10%;
  position: absolute;
  border: 1px;
  width: 450px;
  height: 450px;
  -webkit-transition: all 2s;
  -ms-transition: all 2s;
  -moz-transition: all 2s;
  -o-transition: all 2s;
  -moz-transform-origin: left;
  -ms-transform-origin: left;
  -o-transform-origin: left;
  -webkit-transform-origin: left;
}

#pic1 {
  z-index: 6;
}

#pic2 {
  z-index: 5;
}

#pic3 {
  z-index: 4;
}

#pic4 {
  z-index: 3;
}

#pic5 {
  z-index: 2;
}

#pic6 {
  z-index: 1;
}

JavaScript

var yAngle = 180;
var pages = 6, tempPage = 0;
var pageLStack = [];
var pageRStack = [];

for (var i = pages; i >= 1; i--) {
  pageRStack.push(i);
}

document.addEventListener('keydown', function(e) {
  switch (e.keyCode) {
    case 37: // for left key
      yAngle = -180;
      var pl = pageRStack.pop();
      if (pl) {
        pageLStack.push(pl);
        $('#pic' + pl).css("webkit-transform", "rotateY(" + yAngle + "deg)");
        $('#pic' + pl).css("z-index", "" + tempPage++);
        console.log(tempPage + 1);
      }
      break;

    case 39: // for right key
      yAngle = 0;
      var pr = pageLStack.pop();
      if (pr <= pages) {
        pageRStack.push(pr);
        $('#pic' + pr).css("webkit-transform", "rotateY(" + yAngle + "deg)");
        $('#pic' + pr).css("z-index", "" + tempPage++);
        console.log(tempPage + 1);
      }
      break;
  }
}, false);

Output

Output 1

Output 2

Output 3

Output 4

Output 5

LIVE DEMO

Summary

That's all for this article. I hope you have enjoyed this Camera, Book, and Action style of effect. In case of any doubt feel free to ask in comments. Thanks for reading and don't forget to share and like this article.