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

最后更新于:2022-04-01 19:44:10

      前言:我曾在之前的[分享](http://blog.csdn.net/hfahe/article/details/7388938)里提到CSS3 Region(区域模块)的重要作用:实现更复杂的排版效果,实现更丰富的富文本体验。下文就是和此模块相关的实际应用,可以看到未来它将发挥出巨大的作用。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-09_57a9a2e887394.gif)       这一天终于到来:你开始对大段滚动的文字感到厌倦,并正在寻找一种新的格式,更加优雅,更加紧凑。它可以把长长的滚动条切分为整齐的页面并结合在一起。我把这个发明叫做“书”。       利用CSS3 Region(去[CanIUse](http://caniuse.com/#feat=css-regions)看看当前浏览器支持的情况,Chrome需要进入chrome://flags并激活CSS3 Region)和3D变换,我们终于可以在现代浏览器上实现先进的书籍效果。所有你需要的仅是几行JavaScript和一堆CSS。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-09_57a9a2e8b8d54.jpg)       让我们开始定义书籍结构。这本书由书页组成,而书页包括两面。每一面写满这本书的内容: ~~~

My Fancy Book

By Me I. Myself

2012 Bogus HTML Publishing Ltd

~~~       我们将使用CSS Region控制文字流入书页。但是我们需要先定义这本书的内容。 ~~~ blah blah blah ... ~~~       现在书已经写完了,让我们开始定义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++; } }; })(); ~~~       最终,我们完成了这本“书”。       你可以在[这里](http://kig.github.com/html-book)看到示例以及[源代码](http://github.com/kig/html-book)。如果你的浏览器不支持CSS Region,这本书会惨不忍睹,此时你可以试试[这个例子](http://kig.github.com/html-book/no_regions.html) 。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-09_57a9a2e908aab.jpg)       译自:[http://updates.html5rocks.com/2012/07/Writing-a-flippable-book-using-CSS-Regions-and-3D-transforms](http://updates.html5rocks.com/2012/07/Writing-a-flippable-book-using-CSS-Regions-and-3D-transforms)       转载请注明:来自蒋宇捷的博客(http://blog.csdn.net/hfahe)
';