はじめに
iPhoneやiPadなどiOSに組み込まれているmobile SafariでJavaScriptを使ったアニメーションを動かすと動作が遅くなる事があります。
そこで、CSS3のアニメーションを利用して軽快なUIを実装しようという風潮が高まっているのですが、実はすべてのCSS3アニメーションがmobile safariで軽快に動くという訳ではないようです。
CSS3のアニメーションが軽快に動く(と言われている)理由
結論からいうと、safariというソフトウェアの力だけでなく、iPhoneやiPadのハードウェアの力を借りられるからです。
そういった、ハードウェアのことをアクセラレーターと呼ぶようです。詳しくは参考ページをご覧ください。
※参考
Hardware acceleration – Wikipedia, the free encyclopedia
アクセラレータとは【accelerator】 – 意味/解説/説明/定義 : IT用語辞典
GPUとは【Graphics Processing Unit】 – 意味/解説/説明/定義 : IT用語辞典
しかし先に述べた通りCSS3でアニメーションを書いたからといってすべてがアクセラレーターを利用して軽快に動作するとは限りません。
実際に、iPhoneのmobile safariのアクセラレーターがどこで動いているか見てみます。
アクセラレーターが機能している箇所を見る方法
お手元のmacにiOSシュミレーターをインストールして、ターミナルを開いて以下のコマンドを入力してください。
CA_COLOR_OPAQUE=1 /Developer/Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone\ Simulator.app/Contents/MacOS/iPhone\ Simulator
すると画像のように色がついた状態でシュミレーターが立ち上がります。
-200x300.png)
そして、赤い色がついているところがアクセラレーターが効いているところです。
アクセラレーターの動作を見えるようにしたところで、CSS3でアニメーションを書いてみましょう。
実験方法
今回使用するサンプルは、表示という黄色いボタンを押すと、青いボックスが、画面左からスライドインしてくるものです。
アクセラレーターが作動している箇所は赤く表示されます。もし、青いボックスがアニメーションしているときにアクセラレーターが作動していたら青いボックスごと赤いオーバーレイがかかるはずです。
サンプル1〜3(アクセラレーターが作動しない)
サンプル1は、マイナスマージンを利用して左側に隠した青いボックスを、CSS3のkeyframesアニメーションを利用して動かします。
#slideMenu.slideIn {
-webkit-animation-timing-function: ease;
-webkit-animation-duration: 350ms;
-webkit-animation-name: slidein;
margin-left:0px;
}
#slideMenu.slideOut {
-webkit-animation-timing-function: ease;
-webkit-animation-duration: 350ms;
-webkit-animation-name: slideout;
}
@-webkit-keyframes slidein {
from {margin-left:-320px; }
to { margin-left:0;}
}
@-webkit-keyframes slideout {
from {margin-left:0; }
to { margin-left:-320px;}
}
サンプル2も1と同じく、keyframesアニメーションです。
ただ、今回はマイナスマージンではなく、絶対配置のleftを使っています。
#slideMenu.slideIn {
-webkit-animation-timing-function: ease;
-webkit-animation-duration: 350ms;
-webkit-animation-name: slidein;
left:0px;
}
#slideMenu.slideOut {
-webkit-animation-timing-function: ease;
-webkit-animation-duration: 350ms;
-webkit-animation-name: slideout;
}
@-webkit-keyframes slidein {
from {left:-320px;}
to {left:0;}
}
@-webkit-keyframes slideout {
from {left:0;}
to {left:-320px;}
}
サンプル3は、jQueyのアニメーションで実装してみました。
function hideSlideMenu(){
$("#slideMenu").animate({left:"-320px"}, 350);
showMenuBtn();
}
function showSlideMneu(){
$("#slideMenu").animate({left:0}, 350);
$("#page").bind("click", function(){
hideSlideMenu();
});
hideMenuBtn();
}
$("#menuBtn").bind("click", function(){
showSlideMneu();
});
-200x300.png)
これらのサンプルを実際にシュミレーターで動かすとわかる通り、アニメーションの最中に青いボックスの上に赤いオーバーレイが表示されることはありません。
translate
最後に、CSS3のtransformと、translateを使ってみます。
#slideMenu.slideIn {
-webkit-transform: translate(0, 0);
left: 0;
}
#slideMenu.slideOut {
-webkit-transform: translate(-320px, 0);
left: -320px;
}
結果
-196x300.png)
これを利用すると、青いボックスの上に赤いオーバーレイがかかっています。
どうやらアクセラレーターが動作しているようです。
まとめ
iOSのsafari上でアクセラレーターを利用して、このようなアニメーションを実行するにはtranslateを利用するべきなのでしょう。
まだ、-webkit-transformに適応できるほかの値を試していないのですが、随時試してみたいと思います。
※参考
mir.aculo.us JavaScript with Thomas Fuchs » Blog Archive » Visualizing WebKit’s hardware acceleration
Code blogCSS3 Transitions and Transforms in Gmail for the iPad – The official Google Code blog