CSS animation day12 となりました。
もはや自然ネタは枯渇してしまったので、本日は、興味深い動きの本の CSS アニメーションをしたいと思います。
#1. 完成版
See the Pen book.animation by hiroya iizuka (@hiroyaiizuka) on CodePen.
#2. なぜか?
医学書とかをパッと開く感じでSPAにアニメーションを入れられたら、かっこいいな!動機はそれだけです・・・はい。
#3. 参考文献
Pure CSS 3D Animated Flip Book or Card Design - 3D Perspective flip effect on Hover using CSS
3D Flip Hover Effects - CSS3 Hover Effects - Pure Html CSS 3D Flipping Image - Html5 CSS3 Tutorial
https://codepen.io/_fbrz/pen/whxbF?editors=110
#4. 分解してみる
❶.
まずは、長方形を作ります。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="css/styles.css" />
</head>
<body>
<div class="container">
<div class="cover"></div>
</div>
</body>
</html>
body {
margin: 0;
padding: 0;
}
.container {
width: 250px;
height: 350px;
background: #2e517d;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, 50%);
}
❷.
どうすれば、本のページをめくる動きをつけられるでしょうか?
・・・
- cover class に別のちょっと狭い長方形を作り、
- 左端から20px くらいのところを起点に
- hover時に、左にぺろっと、めくれる動きをつければ良さそうです。 (rotate Y)
では、やってみましょう。
.container {
width: 250px;
height: 350px;
background: #2e517d;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, 50%);
perspective: 1000px;
}
.cover {
width: 210px;
height: 100%;
position: absolute;
left: 40px;
background-color: #345b8c;
transform: rotateY(-10deg);
transform-style: preserve-3d;
transform-origin: left;
transition: all 0.5s ease-in;
}
.container:hover .cover {
transform: rotateY(-180deg);
}
ポイントは3つ
・perspective, transform-style
perspective プロパティは、要素に 遠近感 をつけることができます。z = 0平面と、ユーザー間の距離を設定することができます。
transform-style は、transformで変形した __要素の重なり__を、2Dか3Dで表現できます。 preserve-3d で、デモのように3D表示できます。
・transform-origin
要素の変形における、原点 を設定できます。
rotate() と合わせることで、回転の中心を設定できます。
ex: transform-origin: top left
・transition プロパティ
:hover や :active やJavascript でアニメーションを設定したいときに使うプロパティです。詳細はこちら をご参照ください。
本を開く動きは、はじめゆっくりあと素早くが、表現として合っていると思いますね。そんな時は、ease-in です!
❸.
本の表紙に画像を載せましょう!
Canva を使って、簡単に画像を作れます。
ダウンロードして、取り入れましょう。その際に、画像が重い方は、TinyPNG で、画像を圧縮しましょう。
.cover {
width: 210px;
height: 100%;
position: absolute;
left: 40px;
background: url("../img/bookcover.png");
background-size: cover;
transform: rotate(0deg);
transform-style: preserve-3d;
transform-origin: left;
transition: all 1s ease-in;
}
❹.
では、1ページ目の画像を同様にCanva で作り、取りこみます。
body {
margin: 0;
padding: 0;
}
.container {
width: 210px;
height: 350px;
background: url("../img/page.png");
background-size: cover;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, 50%);
perspective: 1000px;
}
/*left:40pxを削除してます。*/
.cover {
width: 210px;
height: 100%;
position: absolute;
background: url("../img/bookcover.png");
background-size: cover;
transform: rotate(0deg);
transform-style: preserve-3d;
transform-origin: left;
transition: all 1s ease-in;
border-radius: 1%;
}
.container:hover .cover {
transform: rotateY(-180deg);
}
❺.
表紙の背面が透けているので、変更し、影をつけましょう。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="css/styles.css" />
</head>
<body>
<div class="container page">
<div class="cover">
<figure class="back"></figure>
</div>
</div>
</body>
</html>
.container {
width: 210px;
height: 350px;
background: url("../img/page.png");
background-size: cover;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, 50%);
perspective: 1000px;
box-shadow: inset 210px 0 50px rgba(0, 0, 0, 0.5);
}
figure {
backface-visibility: hidden;
width: 100%;
height: 100%;
}
figure.back {
background: #f3f3f3;
transform: rotateY(-180deg) translateX(40px) translateY(-16px)
translateZ(0.1px);
}
ポイントは
box-shadow
影は、表紙によって作られ、1枚目の上の内側にできるので、inset キーワードで、影を内側につけます。また、box-shadowの最初の2つの値は、X軸とY軸の影の長さですが、3つめの値でぼかしの程度をつけます。
backfave-visibility
backfave-visibility は、要素が裏を向いたときに、見えなくするプロパティです。
❻.
影を動かします。
.container {
width: 210px;
height: 350px;
background: url("../img/page.png");
background-size: cover;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, 50%);
perspective: 1000px;
box-shadow: inset 210px 0 50px rgba(0, 0, 0, 0.5),
0 2px 50px rgba(0, 0, 0, 0.5);
transition: 1s ease-in;
}
.container:hover {
box-shadow: inset 20px 0 50px rgba(0, 0, 0, 0.5),
0 2px 50px rgba(0, 0, 0, 0.5);
}
完成しました!
長かった・・・
ではまた明日〜