Googleから学ぶ ヌルヌルサクサクなスライドメニュー

  • 866
    Like
  • 5
    Comment
More than 1 year has passed since last update.

スマフォwebページのスライドメニュー

アプリでは当たり前のように実装されているスライドメニューですが、webページではなかなか使い心地のよいスライドメニューが実装されているのは見かけません。
スマートフォンのブラウザではjavascriptでのアニメーションはどうしてもガタガタになってしまうし、ちらつきやスクロール制御のめんどくささからもうwebページでネイティブアプリ並のスライドメニューを実装するなんて無理と思っていました。
Facebookのwebページですらボタンの反応は悪いしアニメーションも動かないし最悪です。

一方Google先生はパーフェクトなスライドメニューを実装していた

写真 2013-06-07 22 17 19.png

さすがGoogle先生! 俺達に出来ないことを(

Googleのスライドメニューは以下の点でパーフェクトです。
1. スライドのアニメーションがとても滑らか・ちらつかない
2. ボタンの反応にストレスを感じない
3. メインコンテンツ部分のどこをさわってもメニューが閉じる
4. 横スクロール対策がしっかりされている
5. メニューだけスクロールできる

今回はこれらがどのように実装されているのか調査しながら、jQueryのプラグインとしてスライドメニューを実装しました。
具体的なソースはあまり載せていないので、この記事の最後に貼ってあるサンプルページとgithubを見てみてください。

アニメーションについて

GoogleといえばFlash使わずjavascriptでなんでもやっちゃうイメージが強かったので、当然スライドのアニメーションもjavascriptを使っていると思ってソースを眺めていると、CSSにこんな記述がありました。

    -webkit-transform: translateX(0);
    -webkit-transition: .2s -webkit-transform ease-in-out;

CSS3のアニメーション...だと...!
参考 CSS3 - transform

スマートフォンではjavascriptではクラスの切り替えのみを行い、アニメーションはCSSに任せるのが定石のようですねー。
また、GoogleはtranslateXを使っていますが、よくある実装としてはtranslate3dを使いGPUアクセラレーターを有効にすることでにぬるぬる描画を実現していることが多いです。

あとソースを読んでいて気づいた細かいテクニックとしては

実際に動かすのはコンテンツ部分

  メニューはz-indexに負の値をもって奥に隠れているだけです。
  横スクロール対策にもなっている

目立たない要素はアニメーション時はhiddenにする

  アニメーションを軽くするための努力

はじっこのちらつきは背景色でカバーする

  実装してみてわかってのですが、メニュークローズ時にbodyの色がちらつきます。
  Googleではメニューとちらつく部分の背景色を同じにすることで対策しているようです。

イベントについて

Facebookのスライドメニューの反応が悪いように感じるのは、おそらくonclickでアニメーションを発火しているからです。
スマートフォンではonclickの発生が遅いので、スマフォ特有のontouchstartontouchendを使うことでストレスなく操作できます。

メニューオープンはメニューボタンのontouchend、クローズはコンテンツ部分のontouchstartにするのがよさそうです。

メニューのスクロールについて

今回実装する上で一番苦労したがこれでした。
実際にさわってみるとわかりますがGoogleのスライドメニューはネイティブアプリと同じようにメニュー部分だけがスクロールでき、項目が多い場合でも対応できます。

なぜ苦労したか、結論から言うとスクロールの処理を自前で書いていたからです。

まず考えたのはメニュー部分をoverflow: scrollなどでスクロール可能にし、event.preventDefault()でページ全体にイベント伝播しないようにする方法でしたが、結局うまくいかず。
困って再度Googleのソースを見てみるとメニューを囲っているdivに怪しい記述が...

style="-webkit-transform:translate3d(0px, 0px, 0px)"

さきほども登場したtranslate3dですね!
Googleのjsは当然 圧縮難読化されているので実際に確認してはいないのですが、どうやらメニュー部分のontouchmoveを拾って、styleにy軸方向の値を設定したtranslate3dを連続的に書き込むことでスライドを実装しているようです。
実際この実装方法でうまくいきました。

今回作成したプログラムのソース & サンプルページ

今回作ったものを載せておきます
サンプルページ
※iPhone5でのみ動作確認してあります
※PCでは動きません(ontouch系が使えないので)

githubにもおいてあります
github - jSlideMenu

まとめ

・javascriptでなくCSS3のアニメーションを使おう

・ちらつくならtranslate3dを使おう

・ontouch系を使おう

最後に

CSS3すげぇ

 角丸くできるだけかと思ってました。ごめんなさい。

Googleすげぇ

 とても参考になりました。