Menulis buku yang dapat dilipat menggunakan Region CSS dan transformasi 3D

Ilmari Heikkinen

Jadi. Harinya telah tiba. Akhirnya Anda merasa bosan dengan gulungan teks yang panjang dan sedang mencari format baru. Sesuatu yang elegan. Sesuatu yang ringkas. Sesuatu yang membutuhkan gulungan panjang, memotongnya menjadi persegi panjang kecil yang rapi dan mengikatnya menjadi satu. Saya menyebut penemuan ini sebagai "buku".

Dengan kecanggihan wilayah CSS (CanIUse, buka chrome://flags dan aktifkan Wilayah CSS) serta transformasi 3D CSS, teknologi buku canggih akhirnya tersedia di browser modern. Yang Anda butuhkan hanyalah beberapa baris JavaScript dan banyak CSS.

Mari kita mulai dengan menentukan struktur buku. Buku ini terdiri dari halaman dan halamannya terdiri dari dua sisi. Bagian samping berisi konten buku:

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

Kita akan menggunakan wilayah CSS untuk mengalirkan teks buku ke halaman buku. Tapi pertama-tama, kita perlu teks buku.

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

Setelah menulis buku, mari kita definisikan flow CSS. Saya menggunakan karakter + sebagai placeholder awalan vendor, ganti dengan -webkit- untuk browser WebKit, -moz- untuk Firefox, dan seterusnya:

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

Sekarang konten dari span #book-content akan masuk ke div .book-pages. Ini adalah buku yang agak buruk. Untuk buku yang lebih kutu buku, kita harus melakukan misi. Perjalanan kita akan melewati jembatan pelangi dari transformasi CSS ke kerajaan jam JavaScript. Di aula peri mekanis kita akan mengeluarkan sihir transisi yang epik dan mendapatkan tiga kunci dongeng yang mengontrol antarmuka dunia nyata.

Penjaga jembatan pelangi itu memberi kita kebijaksanaan dari pemilih struktural yang bergaya sehingga kita dapat mengubah struktur buku HTML kita menjadi bentuk yang lebih berbentuk buku:

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

Dengan demikian, menciptakan gaya yang agak berbentuk kertas untuk HTML kita, kita tiba di gerbang kerajaan JavaScript yang memiliki banyak roda gigi. Untuk melewati gerbang, kita harus mengubah buku datar menjadi volume yang tepat. Untuk menambah volume ke buku, kami sedikit mengimbangi setiap halaman pada sumbu 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)');
    }
    }
}
})();

Mentransmisikan sihir transisi untuk mengesankan para peri bukanlah pemanggilan yang sulit. Namun, hasilnya membuat halaman-halaman buku bergerak dengan cara yang mulus.

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

Akhirnya, untuk membuat halaman berubah, kita harus mengaitkan peristiwa itu sendiri ke tujuan kita.

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

Dengan itu, kami telah memperoleh teknologi "buku" dan dapat mengevakuasi menara kristal dunia dan meninggalkan pantulan cahaya yang menyambut dan api nuklir Achenar yang dahsyat, bintang biru besar dari nexus dunia. Dengan penuh kemenangan, kami kembali ke rumah masing-masing, dengan mengacungkan buku di atas kepala kami, bersiap untuk mengikuti aliran parade dan perayaan yang tak terelakkan untuk kehormatan kami.

Anda dapat melihat contohnya secara online di sini dan dapatkan sumber lengkap untuk contoh tersebut. Jika Anda tidak memiliki Region CSS di browser, contoh akan terlihat tidak lengkap. Dalam hal ini, Anda dapat mencoba contoh ini.