Brief introduction
2010 F-i.com and Google Chrome team work together to focus on the Lord things I learned about Browsers and the Web (www.20thingsilearned.com) The web app's propaganda education. The main idea of this project is to communicate that the content of e-books is the most appropriate choice for Web presentation. Because the content of e-books is unprecedented web technology, we firmly believe that today's technology can be used in a container to show such an example.
The cover of the book is also the homepage of "things I learned about Browsers and the Web" (www.20thingsilearned.com)
We believe that the best way to realize the feeling of reading real books is to imitate the reading experience of books while making full use of the advantages of electronic media such as navigation. I put a lot of effort on the visual and interactive effects of books, especially the effect of page flipping.
Start making
This tutorial will lead you through the process of HTML5 ebook production and teach you to use canvas elements and JavaScript to make your own ebook. The underlying code for JavaScript, such as variable declaration and event interception, is beyond the scope of this tutorial, please refer to the instance source code.
Before we start, let's take a look at the demo , so we can have a purpose to learn.
ebook Structure
You must always remember that all the information drawn in the canvas cannot be searched by the search engine, nor can it be searched by the user in the browser . For this reason, we display the text content in the DOM, which is then manipulated by JavaScript. So the structure of the ebook is very simple:
xml/html Code copy content to clipboard
- <div id="book">
- <canvas id="Pageflip-canvas"></canvas>
- <div id="pages">
- <section>
- <div> <!--any type of contents--- </div>
- </Section>
- <!--more <section> ' s -here
- </div>
- </div>
The structure of an ebook contains a main container that contains all the pages and the canvas elements used to draw the page-flipping effect. The section element contains a DIV element that contains the contents of the ebook page, and we can adjust the width of the div without affecting the layout of the page content. The div has a fixed width, and the section setting overflows the hide, so that the function of the section element is actually a mask in the horizontal direction of the div.
Open the ebook and you'll see a background image that contains the paper's material and the book effect.
Logic
The code that implements the page turn effect is not very complex, but the code is large because there are many graphical effects that need to be implemented in code. First we start with the constants in the code, which are used throughout the program.
JavaScript Code to copy content to clipboard
- var book_width = 830;
- var book_height = 260;
- var page_width = 400;
- var page_height = 250;
- var page_y = (book_height-page_height)/2;
- var canvas_padding = 60;
Canvas_padding is the white space around the canvas so that pages can go beyond the size of the book when the page is paged. Note that the constants set here also have these values set in the CSS, so if you want to modify the size of the book, you also need to modify the corresponding values in the CSS.
Constant throughout the code to track mouse interactions and draw page flipping
The next step is to define a flip object for each page, which will continue to update to reflect the state of the current page turn during page-flipping interactions.
JavaScript Code to copy content to clipboard
- Create a reference to the book container element
- var book = document.getElementById ( "book");
- Grab a list of all sections elements (pages) within the book
- var pages = book.getelementsbytagname ( "section");
- for ( var i = 0, len = pages.length; i < Len; i++) {
- Pages[i].style.zindex = Len-i;
- Flips.push ({
- Progress:1,
- Target:1,
- Page:pages[i],
- Dragging: false
- });
- }
First, we want to ensure that the z-index of the section elements are arranged in an orderly manner so that the page can be sorted correctly, that is, the first page is above and the last page is at the bottom. The most important properties of the flip object are the progress and target values. They are used to define the size of the flip page folding, 1 means that the whole page is turned to the left, 0 means the middle of the book, and +1 means the entire page is turned to the far right of the book.
The progress and target values are used to define the amount of folding of the page, which can be a value between 1 and 1.
Now that each page has its own flip object, let's learn to get the user's mouse position and start page by this value.
JavaScript Code to copy content to clipboard
- function Mousemovehandler (event) {
- //Offset mouse position So, the top of the book Spine is 0,0
- mouse.x = Event.clientx-book.offsetleft-(BOOK_WIDTH/2);
- Mouse.y = Event.clienty-book.offsettop;
- }
- function Mousedownhandler (event) {
- //Make sure the mouse pointer are inside of the book
- if (Math.Abs (mouse.x) < Page_width) {
- if (mouse.x < 0 && page-1 >= 0) {
- //We are on the left side, drag the previous page
- Flips[page-1].dragging = true;
- }
- Else if (mouse.x > 0 && page + 1 < flips.length) {
- //side, drag the current page
- Flips[page].dragging = true;
- }
- }
- //prevents the text selection
- Event.preventdefault ();
- }
- function Mouseuphandler (event) {
- For ( var i = 0; i < flips.length; i++) {
- //If This flip is being dragged, animate to its destination
- if (flips[i].dragging) {
- //Figure out which page we should navigate to
- if (mouse.x < 0) {
- Flips[i].target =-1;
- page = math.min (page + 1, flips.length);
- }
- else {
- Flips[i].target = 1;
- page = Math.max (page-1, 0);
- }
- }
- Flips[i].dragging = false;
- }
- }
The Mousemovehandler method updates the contents of the mouse object in real time so that we can get the exact position of the mouse.
In the Mousedonwhandler, the test mouse is on the left or right of the book, remember to know the direction of the page. I also need to know if the next page in the flip direction is still there, because we will encounter the first page or the last page. If all the flip options have no problem detecting, set the Flip object's dragging property to true.
In Mouseuphandler, we detect if each page is being dragged, and if so, the drag of the page is released. When you stop dragging, the page determines whether to flip forward or backward depending on the position of the mouse. At the same time the page will be updated, as the navigation of the page.
Rendering
Now that most of the logical operations are done, let's learn how to render collapsed pages in a canvas element. Most of these rendering effects are done in the render () method, which executes 60 times per second to update the state of the page in real time.
JavaScript Code to copy content to clipboard
- function render () {
- //Reset all pixels in the canvas
- Context.clearrect (0, 0, canvas.width, canvas.height);
- for ( var i = 0, len = flips.length; i < Len; i++) {
- var flip = flips[i];
- if (flip.dragging) {
- Flip.target = Math.max (Math.min (mouse.x/page_width, 1),-1);
- }
- //Ease progress towards the target value
- Flip.progress + = (flip.target-flip.progress) * 0.2;
- //If The flip is being dragged or was somewhere in the middle
- //The book, render it
- if (flip.dragging | | Math.Abs (flip.progress) < 0.997) {
- Drawflip (flip);
- }
- }
- }
Reset the canvas with the Clearrect (X,y,w,h) method before you start rendering. Reset the entire canvas canvas
will greatly reduce the performance of the operation, in contrast, simply resetting the parts that need to be redrawn will be more efficient. But in order not to deviate from the topic of this tutorial, we still reset the canvasCanvas
.
If the page is being dragged, then his target value is set to the position of the mouse coordinates relative to the e-book width, not the actual pixel value. At the same time, the progress will be added to the target value a little bit, so the flip of each frame will be updated, we can see the page smooth flip animation effect.
Because every frame has to traverse all the pages, we need to make sure that only the currently active page is redrawn. If the page flipping is not close to the edge of the book (Book_width 0.3%), or the flagged property value of the page is dragging, we think the page is the currently active page.
Now that all the logical operations have been completed, the following need to draw the page effect based on the current state of the page. Let's look at the first part of the Pancreatic Cancer Drawflip () method.
JavaScript Code to copy content to clipboard
- Determines the strength of the fold/bend on a 0-1 range
- var strength = 1-math.abs (flip.progress);
- Width of the folded paper
- var foldwidth = (Page_width * 0.5) * (1-flip.progress);
- X position of the folded paper
- var foldx = page_width * flip.progress + foldwidth;
- How far outside of the book The paper are bent due to perspective
- var verticaloutdent = * Strength;
- The maximum widths of the three shadows used
- var papershadowwidth = (page_width*0.5) * Math.max (Math.min (1-flip.progress, 0.5), 0);
- var rightshadowwidth = (page_width*0.5) * Math.max (Math.min (strength, 0.5), 0);
- var leftshadowwidth = (page_width*0.5) * Math.max (Math.min (strength, 0.5), 0);
- Mask the page by setting it width to match the FOLDX
- Flip.page.style.width = Math.max (foldx, 0) + "px";
This part of the code starts with a calculation of some variables that are used to draw the actual page flipping effect. The progress variable plays the most important role in these variables because it is where the page is to be flipped. To add depth effects, we let the page go beyond the bounds of the book, and when the page flips to the spine position, the excess reaches the limit.