概要
- 3D Transforms はまだドラフトだからブラウザの実装具合もばらばら
- CSS Transition を動的に設定する場合、タイミングによって動かないことも
くるくるフリップとは
こんなやつ。クリックしたらくるっと回転する。動くブラウザは、2011年4月5日時点で、Safari 5 と、Chrome 10 あたり。要は Webkit 系のみ。
コード(Javascript)
<div onclick="flip()"> <div class="flipper" id="front">表</div> <div class="flipper" id="back">裏</div> </div> <style> .flipper { line-height: 130%; font-size: 240px; border: solid 1px black; text-align: center; width: 320px; height: 320px; } #back { display: none; background: black; color: white; } #front { background: white; color: black; } </style> <script> var flipper_front = document.getElementById('front'); var flipper_back = document.getElementById('back'); flipper_front.addEventListener('webkitTransitionEnd', tEnd); flipper_back.addEventListener('webkitTransitionEnd', tEnd); function flip() { flipper_back.style.webkitTransition = "none"; flipper_back.style.webkitTransform = "perspective(500) rotateY(-90deg)"; flipper_front.style.webkitTransition = "-webkit-Transform 0.5s ease-in"; flipper_front.style.webkitTransform = "perspective(500) rotateY(90deg)"; } function tEnd(e) { if(e.target == flipper_front) { flipper_front.style.display = "none"; flipper_back.style.display = "block"; flipper_back.style.webkitTransition = "-webkit-Transform 0.5s ease-out"; window.setTimeout(function() { flipper_back.style.webkitTransform = "perspective(500) rotate(0deg)"; }, 0); } else if(e.target == flipper_back) { var swap = flipper_front; flipper_front = flipper_back; flipper_back = swap; } }
くるくるフリップの実装方法
どうやって回転している風な見た目の変化をさせるか?については CSS 3D Transforms の rotateY 関数を使うのがよさげ。あと、アニメーションをどうやって実現させるかとか、オモテとウラの面の表示方法はどうするかとかについては、人によって色んな作り方があると思う。
上記コードではアニメーションについては CSS Transition とイベント処理(transitionEnd)を使っている。イベント処理を使わず、Transition のディレイを活用してもいいかもしれない。
また、オモテとウラ面の表示については、回転して切り替わる瞬間にスタイルの display プロパティを書き換えて、常にどちらか一方しか表示されないようにしている。これは、position を static のままにしたかったため。absolute なんかでよかったらまた別の作り方がありそう。
コードのポイント
perspective 関数は rotate 関数などよりも先に
perspective 関数を使うことで、奥行きがあるような表現がされるのだけど、どうやら rotateY 関数よりも先に書かないと効果が出ないみたい。最初、逆にしていて、かなり長い時間はまった。
これだとダメ→ element.style.webkitTransform = “rotateY(45deg) perspective(300)”
これならOK→ element.style.webkitTransform = “perspective(300) rotateY(45deg)”
Transition の設定タイミングはシビア?
Transition を DOM を使って動的に設定する場合、対象となるスタイルが設定されたタイミングによっては、思ったようなアニメーションが起きなかったり、逆に想定していないスタイルの変更に対してアニメーションが起きたりするみたい。
flipper_back.style.webkitTransition = "-webkit-Transform 0.5s ease-out"; window.setTimeout(function() { flipper_back.style.webkitTransform = "perspective(500) rotate(0deg)"; }, 0);
↑ここで一見意味がなさそうな setTimeout しているのも、こうしないと Transition によるアニメーションが起こらないため。たぶん、Transition のタイミングをちょっと遅らせないといけないのかな。
Chrome と Safari で回転方向が逆??
フリップを回転させるとき、現在表にきている面は 0度から 90度に、現在裏にきている面は -90度から0度に、それぞれ Y 軸で回転させているのだけど、なぜか Chrome と Safari で回転方向が逆になる。
こんなので実験するとよくわかる。rotateY の引数の角度が増すごとに、Chrome だと右側の辺が手前→左側というように回転するのに、Safari だと右側の辺が奥→左側というように回転する。なんで?
CSS 3 はまだまだドラフト段階の仕様だから、このあたり、将来のバージョンのブラウザでは、動作が変わったりするんだろうな。
他の人による、くるくるフリップの実装
jQTouch という、iPhone などiOS向けのウェブアプリケーションで派手な視覚効果を実現するためのライブラリがあって、そのデモページの中にフリップによる画面遷移も入っている。
ただし、そのライブラリは Safari でしか動かない。同じ Webkit 系の Chrome で動かないのは、上記のような実装の違いがあるため、あえてそのように作っているのだろう。
くるくるフリップよりももっと複雑なことをしているサンプルだったら、ここの Safari 用のデモがすごい。Chrome だと動かないものが多い(2011年4月5日現在)
参考文献
- Safari CSS Visual Effects Guide: Introduction <http://developer.apple.com/library/safari/#documentation/InternetWeb/Conceptual/SafariVisualEffectsProgGuide/Introduction/Introduction.html>
- Surfin' Safari – Blog Archive » 3D Transforms <http://www.webkit.org/blog/386/3d-transforms/>
- Chromium Blog: Web Graphics – Past, Present and Future <http://blog.chromium.org/2010/09/web-graphics-past-present-and-future.html>
- CSS 3D Transforms Module Level 3 <http://www.w3.org/TR/css3-3d-transforms/>