CSS 영역 및 3D 변환을 사용하여 플립형 책 작성

Ilmari Heikkinen

그날이 왔습니다. 긴 텍스트 스크롤이 지겹게 느껴져 새로운 형식을 찾고 있습니다. 우아한 느낌 소형 기기 긴 스크롤을 가져와서 깔끔한 작은 직사각형으로 자르고 함께 결합하는 작업입니다. 저는 이 발명품을 '책'이라고 부릅니다.

CSS 영역 (CanIUse, chrome://flags로 이동하여 CSS 영역 사용 설정)과 CSS 3D 변환을 사용하면 최신 브라우저에서 최신 도서 기술을 사용할 수 있습니다. JavaScript 몇 줄과 CSS가 있으면 됩니다.

먼저 책 구조를 정의해 보겠습니다. 책은 페이지로 구성되며 페이지는 앞면과 뒷면으로 구성됩니다. 측면에는 도서 콘텐츠가 포함됩니다.

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

CSS 영역을 사용하여 책 텍스트를 책 페이지로 전송합니다. 하지만 먼저 도서 텍스트가 필요합니다.

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

이제 책을 작성했으므로 흐름 CSS를 정의해 보겠습니다. + 문자를 공급업체 접두사 자리표시자로 사용하고 있습니다. WebKit 브라우저의 경우 -webkit-, Firefox의 경우 -moz- 등으로 바꿉니다.

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

이제 #book-content 스팬의 콘텐츠가 .book-pages div로 대신 이동합니다. 하지만 이 책은 꽤 좋지 않습니다. 더 전문적인 책을 찾으려면 탐색을 시작해야 합니다. CSS 변환의 무지개 다리를 건너 JavaScript의 시계 장치 왕국으로 이동합니다. 기계공 요정 영주들의 홀에서 장엄한 전환 마법을 발휘하고 오버월드 인터페이스를 제어하는 전설적인 세 개의 열쇠를 얻습니다.

무지개 다리의 수호자가 HTML 책 구조를 더 책 모양의 형식으로 바꿀 수 있도록 세련된 구조 선택자의 지혜를 전해 줍니다.

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

이렇게 HTML에 종이 모양의 스타일을 만들면 JavaScript 왕국의 수조 개의 기어로 된 문에 도착하게 됩니다. 게이트를 통과하려면 평면 책을 적절한 볼륨으로 변환해야 합니다. 책에 볼륨을 추가하기 위해 각 페이지를 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)');
    }
    }
}
})();

요정 영주에게 깊은 인상을 주기 위해 전환 마법을 시전하는 것이 가장 어려운 호출은 아닙니다. 하지만 결과적으로 책 페이지가 부드럽게 넘기는 애니메이션을 적용할 수 있습니다.

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

마지막으로 페이지가 실제로 전환되도록 하려면 이벤트 자체를 원인에 바인딩해야 합니다.

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

이를 통해 '책' 기술을 획득하여 오버월드 크리스탈 타워를 대피시키고 눈부신 빛과 오버월드 네크서스의 거대한 파란 별인 아케나르의 맹렬한 핵 불꽃을 뒤로 남겨둘 수 있습니다. 우리는 책을 높이 들고 집으로 돌아와, 우리를 기리는 행진과 축하 행사가 이어질 것에 대비합니다.

여기에서 온라인 예시를 확인하고 예시의 전체 소스를 가져올 수 있습니다. 브라우저에 CSS 지역이 없으면 예시가 제대로 표시되지 않습니다. 이 경우 이 예시를 사용해 보세요.