【jQuery】CSS3のTransform3DでGPUによる滑らかなアニメーションを実装しよう【CSS3】
jQueryを使うと、手軽にアニメーションを実装することができて、とても便利です。
しかし、jQueryによるアニメーションは処理がどうしても重くなります。
特にスマホなどでは、元々アニメーションがネイティブアプリのUIに多く使われているため、
jQueryによるアニメーションがもっさりとした動きに感じることが多いのではないでしょうか。
jQueryのアニメーションは、通常CPU(コンピュータの総合的な演算装置)により処理されています。
CPUは元々画像処理だけに最適化されたものではない上に、アニメーションだけでなくコンピュータ全体の演算を担っているため、
CPUでアニメーション処理を行うとどうしても処理が遅くなってしまいます。
では、Webサイト上でスマホのネイティブアプリのように滑らかなアニメーションを実装する方法はないのでしょうか?
CSS3にはtransformのプロパティの中に、translate3d、scale3d、rotate3dなど、「3d」がつくものがあります。
これらをTransform3Dといいますが、実は、これらの処理はCPUではなくGPU(グラフィックを専門に処理する演算装置)により行われるため(参考サイト)、アニメーションがスマホのネイティブアプリ並みに滑らかになります。
GPUは画像処理を専門的に扱う演算装置なので、アニメーションなどの画像処理が得意です。
そのため、GPUを使って処理しているTransfomr3Dによるアニメーションは滑らかになります。
今回はそのTransfomr3DによるアニメーションをjQueryと合わせて実装する方法を、1つご紹介いたします。
↓Transfomr3Dのアニメーションを使ったサイドメニュー
↓jQueryのアニメーションを使ったサイドメニュー
方法
手順
- Transform3Dに対応していないデバイス向けに、CSSを設定しておく
- Modernizr.jsを使って、デバイスがTransform3Dに 対応しているかどうか調べる
- デバイスがTransform3Dに対応していたら、Transform3Dによるアニメーションを行うために、jQueryでCSSの書き換えを行う
- アニメーションを実装する
Transform3Dに対応していないデバイス向けに、CSSを設定しておく
Transform3DはGPUを使用しているため、デバイスのGPUが古い場合、Transfomr3Dに対応していない場合があります。
また、IEの9以下でも利用することができません。
そのため、現段階では、Transfomr3Dに対応したデバイスやブラウザ以外では、jQueryによるアニメーションを行うようにしておきます。
そのため、最初のCSSの設定は、jQueryによるアニメーションを前提としたものを設定しておきます。
↓こちらは、スライド式のサイドメニューを実装する場合のものです。
HTML body内
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <a id="menuButton" href="#"> <span></span> <span></span> <span></span> </a> <main> ・・・ </main> <aside> <nav> <ul> <li><a href="#">TOP PAGE</a></li> <li><a href="#">ABOUT</a></li> <li><a href="#">MENU</a></li> <li><a href="#">ACCESS</a></li> <li><a href="#">CONTACT</a></li> </ul> </nav> </aside> |
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | main { padding: 15px; text-align: center; position: relative; z-index: 1; } aside{ display: none; box-sizing: border-box; width: 240px; height: 100%; padding: 60px 15px 15px; background: #ddd; line-height: 42px; text-align: center; position: absolute; top: 0; right: -240px; z-index: 2 } |
Modernizr.jsを使って、デバイスがTransform3Dに 対応しているかどうか調べる
Transform3Dに対応しているかどうかの判定は難しいいところなので、Modernizr.jsというプラグインを使います。
公式サイトからダウンロードして配置し、読み込みます。
Transfomr3Dに対応していれば、htmlタグに「csstransforms3d」というクラスが追加されつので、それを元に判定を行います。
HTML head内
1 2 | <script src="js/jquery-2.1.1.min.js"></script> <script src="js/modernizr.js"></script> |
JavaScript
1 2 3 4 5 6 | $(function(){ var transform3d = false; if($("html").hasClass("csstransforms3d")) transform3d = true; ・・・ }); |
デバイスがTransform3Dに対応していたら、Transform3Dによるアニメーションを行うために、jQueryでCSSの書き換えを行う
Transform3Dでアニメーションを実装する場合、jQueryでアニメーションする場合と初期のCSSの設定が変わってくるので、
デバイスがTransform3Dに対応している場合はjQueryを使ってCSSの初期設定を変更します。
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | $(function(){ var transform3d = false; if($("html").hasClass("csstransforms3d")) transform3d = true; if(transform3d) { $("aside").css({ "display": "block", //最初から表示させる "right": 0, //配置を変更 "transform": "scale3d(0, 1, 1)", //scale3dで横方向の大きさをを0まで縮小 "transform-origin": "right" //transformの位置の基準を右端に設定 }); $("main, aside").css("transition", "all 0.4s cubic-bezier(.02, .01, .47, 1) 0s"); //transitionでアニメーションの設定を行う cubic-bezier(.02, .01, .47, 1)はjQueryのイージングのswingに近い動きを指定している } ・・・ }); |
アニメーションを実装する
最後にjQueryでアニメーションの実装部分を記述します。
Transfomr3Dに対応していないデバイス向けに、jQueryのアニメーションも場合分けして記述します。
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | $(function(){ var transform3d = false; if($("html").hasClass("csstransforms3d")) transform3d = true; if(transform3d) { $("aside").css({ "display": "block", "right": 0, "transform": "scale3d(0, 1, 1)", "transform-origin": "right" }); $("main, aside").css("transition", "all 0.4s cubic-bezier(.02, .01, .47, 1) 0s"); } //ここから実装部分 $("#menuButton").click(function(){ $(this).toggleClass("active"); //メニューボタンの切りs替え /*-- メニューの開閉 --*/ if($(this).hasClass("active")) { if(transform3d){ //Transfomr3Dに対応している場合 $("main").css("transform", "translate3d(-240px, 0, 0)"); $("aside").css({ "transform": "scale3d(1, 1, 1)" }); } else { //Transfomr3Dに対応していない場合 $("body").css("oveflow", "hidden"); $("main").animate({ "left": "-240px" }, 400); $("aside") .show() .animate({ "right": "0" }, 400); } }else{ if(transform3d){ //Transfomr3Dに対応している場合 $("main").css("transform", "translate3d(0, 0, 0)"); $("aside") .css({ "transform": "scale3d(0, 1, 1)" }); } else { //Transfomr3Dに対応していない場合 $("main").animate({ "left": 0 }, 400); $("aside") .show() .animate({ "right": "-240px" }, 400, function(){ $("aside").hide(); $("body").css("oveflow", "visuble"); }); } } return false; }); }); |
jQueryのアニメーションをTransform3Dによるアニメーションに置き換えるときは、
どうすればそれまでjQueryで実装していた動きを、
Transform3Dを使ったアニメーションで再現できるかということが、鍵になってくると思います。
より快適なサイトづくりのため、どんどんTransform3Dを使ったアニメーションへの移行に挑戦していきたいです。
参考サイト
【CSS3】 jQuery を使って iPad でネイティブアプリ並に滑らかなアニメーションを実現する書き方 (フェンリル | デベロッパーズブログ)
Author Profile
NINOMIYA
Webデザイナー兼コーダー出身のフロントエンド開発者です。 UXデザインやチーム開発の効率化など、勉強中です。
SHARE