CSS Bölgeleri ve 3D dönüşümleri kullanarak çevrilebilir kitap yazma

Ilmari Heikkinen

O halde, gün geldi. Uzun metinlerden sıkılmaya başladınız ve yeni bir biçim arıyorsunuz. Zarif bir şey. Kompakt bir şey. Uzun parşömeni düzgün küçük dikdörtgenlere bölen ve bunları birbirine bağlayan bir şey. Bu buluşa "kitap" diyorum.

CSS bölgelerinin (CanIUse, chrome://flags adresine gidip CSS bölgelerini etkinleştirin) ve CSS 3D dönüşümlerinin gücüyle, en son kitap teknolojisi nihayet modern tarayıcılarda kullanılabilir hale geldi. Bunun için birkaç satır JavaScript ve çok fazla CSS'ye ihtiyacınız vardır.

Kitap yapımızı tanımlayarak başlayalım. Kitap sayfalardan oluşur ve sayfalar iki kısımdan oluşur. Kenarlarda kitap içeriği bulunur:

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

Kitap metnini kitap sayfalarına aktarmak için CSS bölgelerini kullanacağız. Ancak önce kitap metnine ihtiyacımız var.

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

Kitabımızı yazdığımıza göre akış CSS'sini tanımlayalım. Tedarikçi firma önek yer tutucusu olarak + karakterini kullanıyorum. Bu karakteri WebKit tarayıcıları için -webkit-, Firefox için -moz- vb. ile değiştirin:

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

Artık #book-content span'ındaki içerik, .book-pages div'lerine eklenecek. Ancak bu kitap pek iyi değil. Daha kitapsı bir kitap için bir maceraya atılmak zorundayız. Yolculuğumuz, CSS dönüşümlerinin gökkuşağı köprüsünden JavaScript'in saat gibi çalışan krallığına uzanacak. Makine cücelerinin salonlarında destansı geçiş büyülerini kullanacak ve üst dünya arayüzünü kontrol eden efsanevi üç anahtarı elde edeceğiz.

Gökkuşağı köprüsünün koruyucusu, HTML kitap yapımızı daha kitap şeklinde bir forma dönüştürebilmemiz için bize şık yapısal seçicilerden bahseder:

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

Böylece, HTML'miz için biraz kağıt şeklinde bir stil oluşturarak JavaScript krallığının trilyon dişli kapısına varırız. Kapıdan geçebilmek için düz kitabımızı uygun bir cilt haline getirmemiz gerekiyor. Kitaba biraz hacim kazandırmak için her sayfayı z ekseninde biraz kaydırırı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)');
    }
    }
}
})();

Peri lordlarını etkilemek için geçiş büyüsü yapmak, en zor çağrılardan biri değildir. Ancak sonuçlar, kitabımızın sayfalarının sorunsuz bir şekilde açılmasını sağlıyor.

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

Son olarak, sayfaların gerçekten dönmesi için etkinlikleri amacımıza bağlamamız gerekir.

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

Böylece "kitap" teknolojisini edinmiş olduk ve üst dünya kristal kulelerini boşaltarak bu kulelerin kör edici parıltısını ve üst dünya bağlantı noktasının büyük mavi yıldızı Achenar'ın şiddetli nükleer ateşlerini geride bırakabiliriz. Başımızın üzerinde kitaplarımızla zafer kazanmış bir şekilde evlerimize döneriz. Onurumuza düzenlenecek kutlamalara ve geçit törenlerine hazırızdır.

Burada online bir örnek görebilir ve örneklerin tam kaynağına ulaşabilirsiniz. Tarayıcınızda CSS bölgeleri yoksa örnek oldukça bozuk görünür. Bu durumda, bunun yerine bu örneği deneyebilirsiniz.