「transitionプロパティ」で設定したアニメーションでは、アニメーションの終了をJavaScriptのイベントとして取得することができます。
アニメーションイベントを利用することで、ちょっと複雑なアニメーションを作成することができます。
transition終了を検知
このサンプルでは、2カラム構成のボックスを2段階のtransitionで表示します。Flashコンテンツなどで、こういった展開をするサイトをよく見かけますね。transitionプロパティと終了イベントをうまく利用することで、簡単にこういった処理を行えます。
※今回も、CSS3の「transitionプロパティ」に対応した「Firefox」「Chrome」「Safari」でしか動作しません。 残念ながら現時点ではIEは「transitionプロパティ」には対応していません。
では早速記述を見てみます。
<style>
#wrap
{
width:80px;
height:80px;
background:#CCC;
color:#FFFFFF;
overflow:hidden;
transition:height 200ms ease-out;
}
#box
{
width:400px;
height:600px;
}
#box2
{
float:right;
width:300px;
height:600px;
background:#000;
}
#box p
{
font-size:12px;
cursor:pointer;
margin-top:25px;
margin-left:10px;
padding:5px;
float:left;
background:#666;
}
</style>
</head>
<body>
<div id="wrap">
<div id="box">
<p>クリック</p>
<div id="box2"></div>
</div>
</div>
</body>
「#box」を固定幅にして、その中に「p」と「#box2」をFloatで配置します。 そして、それら全体を覆う「#wrap」を用意し、「overflow:hidden;」を設定。この「#wrap」の幅と高さを変更することで、コンテンツ全体の表示・非表示を切り替えられます。
図にすると下のようになります。
ではJavaScriptの記述を見てみましょう。
<script>
var callBack;
$(function ()
{
$("#wrap p").toggle(
function()
{
$("#wrap").css("height", "600px");
callBack = function()
{
$("#wrap").css("transition", "width 200ms ease-out");
$("#wrap").css("width", "400px");
}
},
function()
{
$("#wrap").css("width", "80px");
callBack = function()
{
$("#wrap").css("transition", "height 200ms ease-out");
$("#wrap").css("height", "80px");
}
}
);
$("#wrap").bind("webkitTransitionEnd" , function(e){callBack();});
$("#wrap").bind("transitionend" , function(e){callBack();});
});
</script>
transitionプロパティのアニメーションの終了を検知するコードは下記2行です。 「#wrap」に、transition終了イベントを、jQueryの「bindメソッド」を使ってイベントハンドラを指定します。
$("#wrap").bind("webkitTransitionEnd" , function(e){callBack();});
$("#wrap").bind("transitionend" , function(e){callBack();});
ChromeやSafari、iPhone、AndroidなどのWebkit系では「webkitTransitionEnd」、Firefoxでは「transitionend」という名前のイベントが発生します。 ここでもベンダープリフィックスのような感じで名前が違ってたりしますが、イベント名に関しては「prefixfree」も対応していません。 まぁ、存在しないイベントに関しては無視されるので、両方書いても大したコード量ではないので、ここは我慢しましょう(笑)
あとは前回おなじみの「toggleメソッド」で、開く・閉じるを実装します。
考え方としては、
開くとき:「heightを600pxに変更」 → transition終了のイベントハンドラ内で「transitionプロパティをwidthに変更」 → widthを400pxに変更
閉じるとき:「widthを80pxに変更」 → transition終了のイベントハンドラ内で「transitionプロパティをheightに変更」 → heightを80pxに変更
という処理を交互に行います。
その際、toggle内で
callBack = function()
{
$("#wrap").css("transition", "height 200ms ease-out");
$("#wrap").css("height", "80px");
}
この様に「callBack」を毎回書き換えることで、イベントハンドラを交互に切り替える処理を実現しています。
このサンプルはあまり派手なことはしてませんが、transitionを工夫すれば、下記のようなアニメーションも簡単に実装できてしまいます。
transition終了イベントの落とし穴
この様に一見簡単そうに見えるtransition終了イベントの取得ですが、始めてtransitionを弄るときに陥りやすい落とし穴があります。 百聞は一見にしかず、サンプルを見てみてください。 このサンプルでは、「transitionプロパティ」に「all」を指定し、幅・高さのtransitionの実行を交互にではなく、 同時に実行しています。
イベント終了時に、「OPEN」「CLOSE」とアラートするだけのプログラムですが、なぜか2回アラートされますね。 これはtransitionしているプロパティが2つあるためで、transitionの終了イベントは、transitionしているプロパティの分発生します。
なので、transitionの終了を検知して、処理を繋げたい場合は、transitionするプロパティを一つにするか、変数をカウントして、一回だけ処理されるような工夫を入れるのが良いでしょう。
河野 義貴
インハウスのFlashクリエイターとして勤務後、2010年独立。一年間のフリーランス期間を経て、2011年9月にスウィーツアンドストリーム株式会社を設立。主にFlash・HTML5を駆使した、PC・スマートフォン向けインタラクティブコンテンツを中心に活動中。マイナビクリエイターセミナー(WCBセミナー)の講師としてもおなじみ。