用CSS3 Region和3D变换实现书籍翻页效果

jopen 7年前

        前言:我曾在之前的分享里提到CSS3 Region(区域模块)的重要作用:实现更复杂的排版效果,实现更丰富的富文本体验。下文就是和此模块相关的实际应用,可以看到未来它将发挥出巨大的作用。

用CSS3 Region和3D变换实现书籍翻页效果

        这一天终于到来:你开始对大段滚动的文字感到厌倦,并正在寻找一种新的格式,更加优雅,更加紧凑。它可以把长长的滚动条切分为整齐的页面并结合在一起。我把这个发明叫做

        利用CSS3 Region(去CanIUse看看当前浏览器支持的情况,Chrome需要进入chrome://flags并激活CSS3 Region)和3D变换,我们终于可以在现代浏览器上实现先进的书籍效果。所有你需要的仅是几行JavaScript和一堆CSS

用CSS3 Region和3D变换实现书籍翻页效果

        让我们开始定义书籍结构。这本书由书页组成,而书页包括两面。每一面写满这本书的内容:

<div class="book">          <div> <!-- first page -->            <div> <!-- front cover -->              <h1>My Fancy Book</h1>            </div>            <div> <!-- backside of cover -->              <h1>By Me I. Myself</h1>              <h2>2012 Bogus HTML Publishing Ltd</h2>            </div>          </div>          <!-- content pages -->                  <div>            <!-- front side of page -->            <div class="book-pages"></div>            <!-- back side of page -->            <div class="book-pages"></div>          </div>         <div>            <div class="book-pages"></div>            <div class="book-pages"></div>          </div>          <div>            <div class="book-pages"></div>            <div class="book-pages"></div>          </div>  </div>

        我们将使用CSS Region控制文字流入书页。但是我们需要先定义这本书的内容。

<span id="book-content">    blah blah blah ...  </span>

        现在书已经写完了,让我们开始定义CSS流。我使用“+”字符作为占位符替换-webkit-moz这样的浏览器前缀:

#book-content {    +flow-into: book-text-flow;  }  .book-pages {    +flow-from: book-text-flow;  }

        现在来自span#book-content的内容会转而显示到div.book-pages元素里。这本书现在看起来相当差劲。为了让它看起来更美,我们需要更多努力。

        我们可能需要把HTML结构转换为更类似于书籍的形式:

html {    width: 100%;    height: 100%;  }  body {    /* The entire body is clickable area. Let the visitor know that. */    cursor: pointer;    width: 100%;    height: 100%;    /* Set the perspective transform for the page so that our book looks 3D. */    +perspective: 800px;    /* Use 3D for body, the book itself and the page containers. */    +transform-style: preserve-3d;  }  .book {    +transform-style: preserve-3d;    position: absolute;  }  /* Page containers, contain the two sides of the page as children. */  .book > div {    +transform-style: preserve-3d;    position: absolute;  }  /* Both sides of a page. These are flat inside the page container, so no preserve-3d. */  .book > div > div {    /* Fake some lighting with a gradient. */    background: +linear-gradient(-45deg, #ffffff 0%, #e5e5e5 100%);    width: 600px;    height: 400px;    overflow: hidden;    /* Pad the page text a bit. */    padding: 30px;    padding-bottom: 80px;  }  /* Front of a page */  .book > div > div:first-child {    /* The front side of a page should be slightly above the back of the page. */    +transform: translate3d(0px, 0px, 0.02px);    /* Add some extra padding for the gutter. */    padding-left: 40px;    /* Stylish border in the gutter for visual effect. */    border-left: 2px solid #000;  }  /* Back of a page */  .book > div > div:last-child {    /* The back side of a page is flipped. */    +transform: rotateY(180deg);    padding-right: 40px;    border-right: 2px solid #000;  }  /* Front cover of the book */  .book > div:first-child > div:first-child {    /* The covers have a different color. */    background: +linear-gradient(-45deg, #8c9ccc 0%, #080f40 100%);    /* Put a border around the cover to make it cover the pages. */    border: 2px solid #000;    /* And center the cover. */    margin-left: -1px;    margin-top: -1px;  }  /* Back cover of the book */  .book > div:last-child > div:last-child {    background: +linear-gradient(-45deg, #8c9ccc 0%, #080f40 100%);    border: 2px solid #000;    margin-left: -1px;    margin-top: -1px;  }

        我们完成了书籍风格的HTML页面,下面要开始添加JS 我们必须要给这本平平的书一些合适的体积。为了增加体积,我们在Z轴上定位每一页。

(function() {  var books = document.querySelectorAll('.book');  for (var i = 0; i < books.length; i++) {    var book = books[i];    var pages = book.childNodes;    for (var j = 0; j < pages.length; j++) {      if (pages[j].tagName == "DIV") {        setTransform(pages[j], 'translate3d(0px, 0px, ' + (-j) + 'px)');      }    }  }  })();

        下面的代码使我们的书页平滑的显示。

.book > div {    +transition: 1s ease-in-out;  }

        最后,为了自动翻页,我们需要绑定事件。

(function(){   // Get all the pages.   var pages = document.querySelectorAll('.book > div');   var currentPage = 0;   // Go to previous page when clicking on left side of window.   // Go to the next page when clicking on the right side.   window.onclick = function(ev) {     if (ev.clientX < window.innerWidth/2) {       previousPage();     } else {       nextPage();     }     ev.preventDefault();   };   var previousPage = function() {     if (currentPage > 0) {       currentPage--;              // Rotate the page to closed position and move it to its place in the closed page stack.       setTransform(pages[currentPage], 'translate3d(0px,0px,' + (-currentPage) + 'px) rotateY(0deg)');     }   };   var nextPage = function() {     if (currentPage < pages.length) {              // Rotate the page to open position and move it to its place in the opened stack.       setTransform(pages[currentPage], 'translate3d(0px,0px,' + currentPage + 'px) rotateY(-150deg)');       currentPage++;     }   };  })();

        最终,我们完成了这本

        你可以在这里看到示例以及源代码。如果你的浏览器不支持CSS Region,这本书会惨不忍睹,此时你可以试试这个例子 

用CSS3 Region和3D变换实现书籍翻页效果

        译自:http://updates.html5rocks.com/2012/07/Writing-a-flippable-book-using-CSS-Regions-and-3D-transforms

        转载请注明:来自蒋宇捷的博客(http://blog.csdn.net/hfahe)