Viết một cuốn sách có thể lật bằng cách sử dụng Khu vực CSS và tính năng biến đổi 3D

Ilmari Heikkinen

Ngày đó đã đến. Cuối cùng, bạn đã cảm thấy nhàm chán với việc cuộn văn bản dài và đang tìm một định dạng mới. Một cái gì đó trang nhã. Một thiết bị nhỏ gọn. Thứ cần cuộn dài, cắt thành các hình chữ nhật nhỏ gọn và liên kết chúng với nhau. Tôi gọi phát minh này là "sách".

Với sức mạnh của các khu vực CSS (CanIUse, hãy chuyển đến chrome://flags rồi bật các Khu vực CSS) và các tính năng chuyển đổi CSS 3D, cuối cùng, công nghệ sách tiên tiến đã có mặt trên các trình duyệt hiện đại. Tất cả những gì bạn cần là một vài dòng JavaScript và nhiều CSS.

Hãy bắt đầu bằng cách xác định cấu trúc sách. Cuốn sách bao gồm các trang và các trang gồm hai mặt. Các cạnh chứa nội dung sách:

<div class="book">
    <div> <!-- first page -->
    <div> <!-- front cover -->
        # My Fancy Book
    </div>
    <div> <!-- backside of cover -->
        # By Me I. Myself
        ## 2012 Bogus HTML Publishing Ltd
    </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>

Chúng tôi sẽ sử dụng các khu vực CSS để chuyển nội dung sách vào các trang sách. Nhưng trước tiên, chúng ta cần nội dung trong sách.

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

Bây giờ, chúng ta đã viết xong cuốn sách, hãy xác định luồng CSS. Tôi đang sử dụng ký tự + làm phần giữ chỗ tiền tố nhà cung cấp, thay thế bằng -webkit- cho các trình duyệt WebKit, -moz- cho Firefox, v.v.:

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

Bây giờ, nội dung trong khoảng #book-content sẽ được chuyển vào các div .book-pages. Tuy nhiên, đây là một cuốn sách khá kém. Để có thể đọc được nhiều sách hơn, chúng ta phải bắt tay vào nhiệm vụ. Hành trình của chúng ta sẽ đưa bạn qua cầu nối chuyển đổi CSS đến vương quốc đồng hồ JavaScript. Trong đại sảnh của các hội tiên cơ khí, chúng ta sẽ tung ra các phép thuật chuyển cảnh hoành tráng và có được ba chìa khoá huyền thoại điều khiển giao diện thế giới.

Người bảo vệ cây cầu cầu vồng mang đến cho chúng ta sự thông thái về bộ chọn cấu trúc hợp thời trang để chúng tôi có thể biến cấu trúc sách HTML của mình thành dạng sách giống hơn:

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;
}

Do đó, khi tạo ra một kiểu giấy tương đối giống như trên giấy cho HTML, chúng ta đã đi đến cổng bánh răng hàng tỷ tỷ của Vương quốc JavaScript. Để đi qua cổng, chúng ta phải chuyển cuốn sách phẳng thành một tập phù hợp. Để thêm một số tập vào sách, chúng tôi bù trừ một chút cho mỗi trang trên trục 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)');
    }
    }
}
})();

Việc truyền phép thuật chuyển tiếp để gây ấn tượng với các nàng tiên không phải là lệnh gọi khó nhất. Tuy nhiên, kết quả vẫn giúp các trang sách trở nên sinh động và dễ dàng chuyển trang.

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

Cuối cùng, để các trang thực sự chuyển sang trang mới, chúng tôi cần phải tự liên kết các sự kiện với mục đích cao cả của mình.

(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++;
        }
    };
})();

Nhờ đó, chúng tôi đã có được công nghệ "sách" và có thể di tản khỏi các tháp pha lê trên thế giới và để lại những ánh sáng chói mắt của chúng và đám cháy hạt nhân dữ dội của Achenar, ngôi sao màu xanh dương vĩ đại của mối liên hệ giữa thế giới. Chúng tôi hân hoan trở về nhà, hất đầu sách lên cao, chuẩn bị sẵn sàng cho những cuộc diễu hành và lễ kỷ niệm không thể tránh khỏi để tôn vinh chúng ta.

Bạn có thể xem một ví dụ trực tuyến tại đây và xem toàn bộ nguồn cho các ví dụ đó. Nếu bạn không có Khu vực CSS trong trình duyệt, ví dụ này sẽ không hiển thị như mong đợi. Trong trường hợp đó, bạn có thể thử ví dụ này.