Scrivere un libro ribaltabile utilizzando le regioni CSS e le trasformazioni 3D

Ilmari Heikkinen

Il giorno è arrivato. Finalmente ti sei annoiato dei lunghi rotoli di testo e sei alla ricerca di un nuovo formato. Qualcosa di elegante. Qualcosa di compatto. Qualcosa che prende il lungo rotolo, lo taglia in piccoli rettangoli precisi e li unisce. Chiamo questa invenzione il "libro".

Con la potenza delle regioni CSS (CanIUse, vai a chrome://flags e abilita le regioni CSS) e le trasformazioni 3D CSS, l'innovativa tecnologia per i libri è finalmente disponibile sui browser moderni. Tutto ciò che ti serve sono poche righe di codice JavaScript e tanto CSS.

Iniziamo definendo la struttura del nostro libro. Il libro è costituito da pagine e le pagine sono disposte su due facciate. I lati includono i contenuti del libro:

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

Useremo le regioni CSS per inserire il testo del libro nelle pagine del libro. Ma prima abbiamo bisogno del testo del libro.

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

Ora che abbiamo scritto il nostro libro, definiamo il codice CSS del flusso. Sto utilizzando il carattere + come segnaposto per il prefisso del fornitore, sostituendolo con -webkit- per i browser WebKit, -moz- per Firefox e così via:

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

Ora i contenuti dell'intervallo #book-content verranno inseriti nei div .book-pages. Questo libro è però piuttosto scadente. Per un libro più librario, dobbiamo intraprendere una missione. Il nostro viaggio porterà oltre il ponte arcobaleno delle trasformazioni CSS verso il regno degli orologi di JavaScript. Nelle sale dei fairylords meccanici sveleremo epiche magie di transizione e otterremo le leggendarie tre chiavi che controllano l'interfaccia dell'overmondo.

Il guardiano del ponte arcobaleno ci conferisce la saggezza degli eleganti selettori strutturali in modo da poter trasformare la struttura del nostro libro HTML in una forma più simile a un libro:

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

Creando così uno stile simile a quello cartaceo per il nostro codice HTML, arriviamo alle porte del regno JavaScript, con un numero di trilioni di ingranaggi. Per attraversare il cancello, dobbiamo trasformare il nostro libro piano in un volume adeguato. Per aggiungere un po' di volume al libro, applichiamo uno scostamento leggermente a ogni pagina sull'asse 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)');
    }
    }
}
})();

Trasmettere magia di transizione per stupire i fairylord non è il più difficile. Eppure, i risultati fanno sì che le pagine del nostro libro animano la loro rotazione in modo fluido.

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

Infine, per far sì che le pagine svolgano effettivamente le pagine, dobbiamo associare gli eventi stessi alla nostra causa.

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

Con ciò, abbiamo acquisito la tecnologia del "libro" e possiamo evacuare le torri di cristallo dell'oltremondo e lasciare dietro il loro bagliore accecante e i feroci incendi nucleari di Achenar, la grande stella blu del nesso sopramondo. Torniamo trionfanti alle nostre case, brandendo i nostri libri sopra le nostre teste, pronti per l'inevitabile cascata di parate e celebrazioni in nostro onore.

Puoi consultare un esempio online qui e consultare la fonte completa degli esempi. Se nel browser non sono presenti regioni CSS, l'esempio non funzionerà. In questo caso, puoi provare questo esempio.