CSS3のプロパティtransformとtransitionを組み合わせると、3次元のアニメーションができます。Marcofolio.net「3d animation using pure CSS3」の作例を参考にして、要素を水平に回したり、手前に押し出したりしてみました。コードの行数はわかりやすいように減らし、手直ししたサンプルで仕組みをご説明します(サンプル001)。JavaScriptコードは書きません。
サンプル001■CSS3: 3D animation with the transform and the transition properties
01 画像とテキストのレイアウト
画面に置く画像とテキストの要素は、つぎのようにリストで組立てます。この枠組みに沿ってbody要素に加えたコードは以下のとおりです。
<div id="wrapper">
<ul id="books">
<li>
<img />
<div class="bookinfo">
<h3>タイトル</h3>
<p>説明</p>
<a>リンク</a>
</div>
</li>
<!-- li要素の繰返し -->
</ul>
</div>
<div id="wrapper">
<ul id="books">
<li>
<img src="images/ActionScript30for3D.png" alt="ActionScript 3.0による三次元表現ガイドブック" />
<div class="bookinfo">
<h3>ActionScript 3.0<br>
による三次元表現<br>
ガイドブック</h3>
<p>Flashコンテンツに差次元空間の表現力を加えるためのテクニックを完全解説</p>
<a href="http://fumiononaka.com/Books/ActionScript30for3D.html" title="ActionScript 3.0による三次元表現ガイドブック" target="_blank">More info</a>
</div>
</li>
<li>
<img src="images/ActionScript_30_Performance_Tuning.jpg" alt="ActionScript 3.0パフォーマンスチューニング" />
<div class="bookinfo">
<h3>ActionScript 3.0<br>
パフォーマンス<br>
チューニング</h3>
<p>3Dグラフィックス・Flashゲームから最大限のパフォーマンスを引き出せ!</p>
<a href="http://fumiononaka.com/Books/ActionScript_30_Performance_Tuning.html" title="ActionScript 3.0パフォーマンスチューニング" target="_blank">More info</a>
</div>
</li>
<li>
<img src="images/CreateJS_Style_Book_157x200.fw.png" alt="WebクリエイターのためのCreateJSスタイルブック" />
<div class="bookinfo">
<h3>Webクリエイター<br>
のためのCreateJS<br>
スタイルブック</h3>
<p>JavaScript + HTML5で作るアニメーション/インタラクティブコンテンツ</p>
<a href="http://fumiononaka.com/Books/CreateJS_Style_Book.html" title="WebクリエイターのためのCreateJSスタイルブック" target="_blank">More info</a>
</div>
</li>
</ul>
</div>
|
まずは、3次元アニメーションを加える前の画像とテキストのレイアウトとして、後に掲げるコード001のCSSを定めました(図001)。画像リスト(id属性books)とテキスト(クラスbookinfo)の領域には、box-shadowプロパティで影がつけてあります[*1]。プロパティの構文はつぎのとおりです。
box-shadow: 水平のずれ 垂直のずれ ぼかしの大きさ 影色
後掲コード001は、box-shadowプロパティをつぎの抜書きのように定めました(なお、行番号はコード001にもとづきます)。
- #books li img {
- box-shadow: 0 3px 10px #888;
- }
- .bookinfo {
- box-shadow:0 20px 40px #888;
- }
- #books li:hover .bookinfo {
- box-shadow: 0 5px 10px #888;
- }
|
図001■CSSで定めた画像とテキストのレイアウト
テキスト(クラスbookinfo)は、:hover擬似クラスで影が縮めてありました(第33行目)。さらに、ボタンの役割を担うa要素は、以下のように:hover擬似クラスで文字と背景のコントラストを強めています(第45と第47および第56〜57行目)。図002では少しわかりづらいと思いますので、前掲サンプル001でお確かめください。なお、ボーダーの角を丸めるのはborder-radiusプロパティです(第53行目)。
図002■ボタンにロールオーバーするとテキスト領域の影は縮んで背景と文字のコントラストが強まる
- .bookinfo a {
- background: #7a3f3a;
- color: #eee;
- border-radius: 5px;
- }
- .bookinfo a:hover {
- background: #6a191f;
- color: #fff;
- }
|
画像とテキストに定めたstyle要素をまとめたのが、以下のコード001です。ロールオーバーでテキストの影とボタンのコントラストが変わります。3次元のアニメーションは、これから加えてゆきます。
コード001■画像とテキストのレイアウトにロールオーバーのアニメーションを加える
- * {
- margin: 0;
- padding: 0;
- }
- body {
- font: 10px sans-serif;
- background: #deddcd;
- }
- #wrapper {
- width: 640px;
- margin: 10px auto;
- }
- #books {
- margin: 100px 0;
- }
- #books li {
- display: inline;
- float: left;
- }
- #books li img {
- border: 10px solid #fcfafa;
- box-shadow: 0 3px 10px #888;
- }
- .bookinfo {
- border: 5px solid #fcfafa;
- padding: 5px;
- width: 120px;
- background: #deddcd;
- margin: auto;
- box-shadow:0 20px 40px #888;
- }
- #books li:hover .bookinfo {
- box-shadow: 0 5px 10px #888;
- }
- .bookinfo h3 {
- color: #7a3f3a;
- font: "MS ゴシック", "MS Gothic", "Osaka−等幅", Osaka-mono, monospace;
- text-align: center;
- padding-bottom: 15px;
- }
- .bookinfo p {
- padding-bottom: 15px;
- }
- .bookinfo a {
- background: #7a3f3a;
- padding: 5px 10px;
- color: #eee;
- text-decoration: none;
- display: block;
- width: 80px;
- text-align: center;
- margin: 0 auto;
- border-radius: 5px;
- }
- .bookinfo a:hover {
- background: #6a191f;
- color: #fff;
- }
|
[*1] CSS3の機能は、ブラウザとそのバージョンによってベンダー接頭辞を加えなければなりません。たとえば、WebKit系なら-webkit-、Mozilla系は-moz-などです。本稿では、JavaScriptライブラリ「Prefix free」を用いることにより、ベンダー接頭辞は省きました(図003)。ベンダー接頭辞は、Prefix freeが自動的につけてくれるのです(「CSS3: 3次元空間に立方体をつくって回す ー transformプロパティ」02「CSSプロパティのベンダー接頭辞と『Prefix free』」参照)。
<script src="lib/prefixfree.min.js"></script>
|
図003■Prefix freeサイト
|
02 開けるサブメニューをターゲット要素から捉える
transformプロパティは、2次元または3次元の空間で座標を変換します(MDN「CSS transforms の利用」参照)。プロパティには、つぎのようにtransform-function(変換関数)を定めます。
transform: 変換関数
テキストの位置を移して画像に重ねると、ボーダーや背景は画像の後ろに隠れてしまいます(図004左)。そこで、テキストを手前にもってきます。transformプロパティに定めたのが、z座標を動かすtranslateZ()関数です(第39行目)。行番号は後にまとめて掲げるコード002にもとづきます。これで、テキストは画像の手前に表れます(図004右)。
- .bookinfo {
- margin: -75px auto;
- transform: translateZ(10px);
- }
|
図004■テキストのz座標を手前に動かす
さらに、transformプロパティにrotateY()関数を与えれば、要素をy軸で水平に回せます。ただし、transformプロパティを定めただけでは、水平に伸び縮みしているようにしか見えません(図004左)。つぎのように、perspectiveプロパティで遠近感を与えなければならないのです(第19行目)。定める数値は、カメラのレンズの焦点距離に当たります。値が小さいほど、遠近の差が際立ちます(ニコンイメージング「遠近感(パースペクティブ)」参照)。また、transform-styleプロパティをpreserve-3dとして、3次元座標空間の扱いであることを示します(第20行目)。これで、遠近感の加わった3次元表現になりました(図004右)。
- #books li {
- perspective: 500px;
- transform-style: preserve-3d;
- }
- #books li img {
- transform: rotateY(30deg);
- }
- .bookinfo {
- transform: translateZ(30px) rotateY(30deg);
- }
|
図005■3次元座標の扱いに遠近感を与える
3次元の移動と回転を加えたstyle要素が、以下のコード002です。画像リスト(id属性books)とテキスト(クラスbookinfo)の:hover擬似クラスで、角度を正面向きにしました(第31および第45行目)。したがって、マウスポインタのロールオーバーとロールアウトで、要素が水平に回ります(図006)。ただし、瞬時に切り替わるので、滑らかな動きにはなっていません。
図006■マウスポインタのロールオーバーとロールアウトで画像と適すが水平に回る
コード002■ロールオーバーとロールアウトで要素の3次元座標と角度を変える
- * {
- margin: 0;
- padding: 0;
- }
- body {
- font: 10px sans-serif;
- background: #deddcd;
- }
- #wrapper {
- width: 640px;
- margin: 10px auto;
- }
- #books {
- margin: 100px 0;
- }
- #books li {
- display: inline;
- float: left;
- perspective: 500px;
- transform-style: preserve-3d;
- }
- #books li:hover {
- perspective: 5000px;
- }
- #books li img {
- border: 10px solid #fcfafa;
- box-shadow: 0 3px 10px #888;
- transform: rotateY(30deg);
- }
- #books li:hover img {
- transform: rotateY(0deg);
- }
- .bookinfo {
- border: 5px solid #fcfafa;
- padding: 5px;
- width: 120px;
- background: #deddcd;
- margin: -75px auto;
- box-shadow:0 20px 40px #888;
- transform: translateZ(30px) rotateY(30deg);
- }
- #books li:hover .bookinfo {
- margin: -65px auto;
- box-shadow: 0 5px 10px #888;
- transform: translateZ(10px) rotateY(0deg);
- }
- .bookinfo h3 {
- color: #7a3f3a;
- font: "MS ゴシック", "MS Gothic", "Osaka−等幅", Osaka-mono, monospace;
- text-align: center;
- padding-bottom: 15px;
- }
- .bookinfo p {
- padding-bottom: 15px;
- }
- .bookinfo a {
- background: #7a3f3a;
- padding: 5px 10px;
- color: #eee;
- text-decoration: none;
- display: block;
- width: 80px;
- text-align: center;
- margin: 0 auto;
- border-radius: 5px;
- }
- .bookinfo a:hover {
- background: #6a191f;
- color: #fff;
- }
|
03 transitionプロパティで滑らかな3次元アニメーションを与える
transitionプロパティを使うと、プロパティの値を滑らかなアニメーションで変えられます。transitionに定めるもっとも基本的な値は、つぎのようにアニメーションの時間、および変化のタイミング関数のふたつです(「CSS3: transitionを使った回転と伸縮のアニメーション」02「プロパティをアニメーションさせる」参照)。タイミング関数を省くと、デフォルトのeaseが用いられます(図007)。
transition: 時間 タイミング関数
図007■タイミング関数easeの値の変わり方
滑らかなアニメーションを加えたstyle要素の定めは、後にコード003としてまとめました。transitionプロパティは、画像リスト(id属性books)とテキスト(クラスbookinfo)に、つぎの抜書きのように与えました。
- #books li {
- transition: 0.5s;
- }
- #books li img {
- transition: 0.5s;
- }
- .bookinfo {
- transition: 0.5s;
- }
|
前掲サンプル001に定めたstyle要素は、つぎのコード003にまとめたとおりです。マウスポインがロールオーバーすると、画像とテキストは水平に回って正面を向きます。テキストの位置も垂直および奥行きが少し変わり、影は狭まります。
コード003■ロールオーバーとロールアウトで要素に滑らかな3次元アニメーションを与える
- * {
- margin: 0;
- padding: 0;
- }
- body {
- font: 10px sans-serif;
- background: #deddcd;
- }
- #wrapper {
- width: 640px;
- margin: 10px auto;
- }
- #books {
- margin: 100px 0;
- }
- #books li {
- display: inline;
- float: left;
- perspective: 500px;
- transform-style: preserve-3d;
- transition: 0.5s;
- }
- #books li:hover {
- perspective: 5000px;
- }
- #books li img {
- border: 10px solid #fcfafa;
- box-shadow: 0 3px 10px #888;
- transform: rotateY(30deg);
- transition: 0.5s;
- }
- #books li:hover img {
- transform: rotateY(0deg);
- }
- .bookinfo {
- border: 5px solid #fcfafa;
- padding: 5px;
- width: 120px;
- background: #deddcd;
- margin: -75px auto;
- box-shadow:0 20px 40px #888;
- transform: translateZ(30px) rotateY(30deg);
- transition: 0.5s;
- }
- #books li:hover .bookinfo {
- margin: -65px auto;
- box-shadow: 0 5px 10px #888;
- transform: translateZ(10px) rotateY(0deg);
- }
- .bookinfo h3 {
- color: #7a3f3a;
- font: "MS ゴシック", "MS Gothic", "Osaka−等幅", Osaka-mono, monospace;
- text-align: center;
- padding-bottom: 15px;
- }
- .bookinfo p {
- padding-bottom: 15px;
- }
- .bookinfo a {
- background: #7a3f3a;
- padding: 5px 10px;
- color: #eee;
- text-decoration: none;
- display: block;
- width: 80px;
- text-align: center;
- margin: 0 auto;
- border-radius: 5px;
- }
- .bookinfo a:hover {
- background: #6a191f;
- color: #fff;
- }
|
04 少し細かな検討
書上げた前掲コード003のCSSについて、少し細かい説明を3つ補います。第1に、画像リスト(id属性books)のperspectiveプロパティは、:hover擬似クラスでつぎのように値を上げてあります(第24行目)。逆にいえば、マウスポインタがロールオーバーしていないときは、遠近感が強めになっているということです。そのため、ロールアウトすると、画像とテキストの手前側が少しせり出してくるような表現になりました。
- #books li {
- perspective: 500px;
- }
- #books li:hover {
- perspective: 5000px;
- }
|
第2は、参考にした作例「3d animation using pure CSS3」の作者も気づいて、つぎのように述べていたテキストのちらつきです。筆者の環境では、Safariで確認されました。マウスポインタがロールオーバーして要素が正面向きになったところで、一瞬テキストが画像の裏に隠れて戻るような動きです。
"For some reason, when animating the last element (the Tron Legacy Poster), the info box is quickly flickering just before the animation ends."
もとの作例はつぎのような記述で、ロールオーバーしたテキストにz座標値を与えていませんでした。そして、問題の動きから推測されるのは、z座標値がデフォルトの0に戻るとき一瞬2次元の表示になって、テキストが画像の裏に隠れるのではないかということでした(前掲図004左参照)。
#books li:hover .bookinfo {
transform: rotateY(0deg);
}
|
そこで、前掲コード003では、translateZ()関数でz座標値を与えたのです(なお、数値は0pxにしてもちらつきは防げました)。
- #books li:hover .bookinfo {
- transform: translateZ(10px) rotateY(0deg);
- }
|
第3は、筆者の環境ではFirefoxで、もとの作例に遠近感が加わらないことでした[*2]。コードをよく調べると、perspectiveプロパティに与えた数値に単位「px」が抜けていました。こういう小さな誤りは、見つけにくいものです。注意しましょう。
[*2] 厳密には、作例はベンダー接頭辞に-webkit-しか用いておらず、Firefoxは対象とされていませんでした。けれど、-moz-を加えても遠近感が与えられませんでした。
|
作成者: 野中文雄
作成日: 2015年2月2日