Een omklapbaar boek schrijven met behulp van CSS-regio's en 3D-transformaties

Ilmari Heikkinen

Dus. De dag is gekomen. Je bent eindelijk verveeld geraakt door lange tekstrollen en bent op zoek naar een nieuw formaat. Iets elegants. Iets compacts. Iets dat de lange boekrol in nette, kleine rechthoekjes snijdt en ze aan elkaar bindt. Ik noem deze uitvinding het "boek".

Met de kracht van CSS-regio's ( CanIUse , ga naar chrome://flags en schakel CSS Regions in) en CSS 3D-transformaties is de allernieuwste boektechnologie eindelijk beschikbaar in moderne browsers. Het enige dat je nodig hebt zijn een paar regels JavaScript en heel veel CSS.

Laten we beginnen met het definiëren van onze boekstructuur. Het boek bestaat uit pagina's en de pagina's bestaan ​​uit twee zijden. Op de zijkanten staat de inhoud van het boek:

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

We gaan CSS-regio's gebruiken om de boektekst naar de boekpagina's te laten stromen. Maar eerst hebben we de boektekst nodig.

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

Nu we ons boek hebben geschreven, gaan we de CSS-stroom definiëren. Ik gebruik het teken + als tijdelijke aanduiding voor het leveranciersvoorvoegsel, vervang het door -webkit- voor WebKit-browsers, -moz- voor Firefox, enzovoort:

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

Nu wordt de inhoud uit de #book-content-reeks in plaats daarvan in de .book-pages-divs geplaatst. Dit is echter een nogal mager boek. Voor een meer boekenachtig boek moeten we aan een zoektocht beginnen. Onze reis zal leiden over de regenboogbrug van CSS-transformaties naar het uurwerkkoninkrijk van JavaScript. In de hallen van de mechanische sprookjesheren zullen we epische overgangsmagie ontketenen en de legendarische drie sleutels verkrijgen die de interface van de bovenwereld besturen.

De bewaker van de regenboogbrug schenkt ons de wijsheid van stijlvolle structurele selectors, zodat we onze HTML-boekstructuur in een meer boekvormige vorm kunnen veranderen:

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

Door zo een enigszins papiervormige stijl voor onze HTML te creëren, komen we bij de biljoenen-gerichte poorten van het JavaScript-koninkrijk. Om door de poort te gaan, moeten we van ons platte boek een echt boek maken. Om wat volume aan het boek toe te voegen, hebben we elke pagina iets verschoven op de z-as.

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

Het gebruik van overgangsmagie om indruk te maken op de sprookjesheren is niet de moeilijkste aanroeping. Toch zorgen de resultaten ervoor dat de pagina's van ons boek het omslaan op een soepele manier animeren.

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

Ten slotte moeten we, om de bladzijden daadwerkelijk om te laten slaan, de gebeurtenissen zelf aan onze zaak binden.

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

Daarmee hebben we de 'boek'-technologie verworven en kunnen we de kristallen torens van de bovenwereld evacueren en hun verblindende schittering en de felle nucleaire vuren van Achenar, de grote blauwe ster van het knooppunt van de bovenwereld, achter ons laten. Triomfantelijk keren we terug naar onze huizen, zwaaiend met onze boeken hoog boven ons hoofd, klaar voor de onvermijdelijke waterval van optochten en vieringen ter ere van ons.

U kunt hier online een voorbeeld bekijken en de volledige bron voor de voorbeelden verkrijgen. Als u geen CSS-regio's in uw browser heeft, ziet het voorbeeld er behoorlijk slecht uit. In dat geval kunt u dit voorbeeld proberen.