メディア掲載_Web Designing

Web Designing 2012年7月号

執筆:伊藤洋介 執筆:伊藤洋介

SmartphoneLab.2012年7月号

フリックを独自実装してスマホ的な技法を学ぶ

「フリック」は、スマートフォン向けWebページの特徴的なUI操作の一つだ。フリックを実現するライブラリやプラグインなども数多く出回っているが、今回はフリックを独自に実装していく。その際のJavaScriptの仕組みがどのようになっているのかを解説しながらサンプルページを作成していくので、スマートフォンならではのコーディングのコツや技法を学んでほしい。

表示エリアすべてを縦横フリックに対応し、快適な操作感を実現しよう。

スマートフォンはPCに比べて画面領域が狭いが、フリックを活用すれば、より多くの情報を掲載できる。ただし、フリック可能なエリアが狭いと操作がしにくくなってしまうという点には気をつけなければならない。フリックしたいエリアにタッチしようとして、間違えて隣接するボタンにタッチしてしまうといったことは、スマートフォンユーザーなら一度は経験しているはずだ。
今回は、限られた画面領域の中で、快適な操作で多くのコンテンツを閲覧するためのアプローチの一つとして、表示エリアすべてが縦横にフリック可能なページ構造の作成方法を紹介しよう。
このような機能を実現するライブラリやプラグインも数多くリリースされているが、今回のサンプルではjQueryのみを使って実装している。PC向けの場合のページ構造や記述などの違いを確認して、スマートフォン向けのコーディングを身につけてほしい。具体的には、BOX01からBOX04(02)までの「ページ」を用意し、それをフリックした方向と距離(03)によって、縦もしくは横にスライドする。ボックスの数を増加させることで、より多くの情報を掲載することもできるが、実際には1ページのHTMLなので、データの容量の増加にも気を配っておこう。

01今回作成するサンプルページ

01 今回作成するサンプルページ

左右と下にフリック可能なUIとなっている

02ページ全体の構造

02 ページ全体の構造

BOX02をトップ画面として、矢印方向にフリックが可能な構造としている

03フリック操作

03 フリック操作

タッチ開始した座標と、タッチが終了した座標の差の数値で、どの方向にどれくらいフリックしたかを判断する

SECTION1 インターフェイスを静的に作成する

インターフェイスを静的に作成する

ここでは、JavaScriptでフリック機能を実装するための基盤となるHTMLを作成する。今回のUIでは各BOXの高さを画面サイズに固定することが重要となるが、iPhoneとAndroidでは縦横比が異なるため、その対処方法も併せて解説していこう。

STEP1 viewportの設定をする

まずはviewportで表示エリアの設定を行う。今回のページ構造では、各ボックスのサイズを表示エリアと揃える必要があるので、「initial-scale(倍率初期値)」は1としておこう(01)。

01viewportの設定

01 viewportの設定

拡大縮小は必要ないので、「user-scalable」の値をnoとしておく

STEP2 4つのボックスを作成する

次に、フリックでスライドする4つのボックスを作成していく。02のように、「BOX02」がトップページの位置づけとなり、そこから「BOX01」「BOX03」「BOX04」へとフリックできる構造となる。各ボックスはfloatで並べているが、BOX04はトップであるBOX02からの縦フリックでの遷移となるので、positionで右方向にコンテンツ幅分、ずらして配置している(04)。
また、ページアクセス時にBOX02をトップ位置に表示させるため、#flickBox自体をコンテンツ幅分、左にずらしている(05

STEP3 各ボックスの高さを調整する

各ボックス間でのフリックをシームレスに実現するためには、ボックス間を隙間なく隣接させることが必要となる。しかし、Android端末の解像度は、低いタイプの場合では320×240px、高いタイプの場合では1,280×720pxなど、実にさまざまな機種が存在しており、それらに対応するためにJavaScriptでボックスの高さを調整している(06)。

02ページ構造(#flickBox)

02 ページ構造

トップに位置づけるBOX02を基準として、左右と下にフリックできる構造としている

03HTMLの記述例

03 HTMLの記述例

「#flickBox」と命名した大枠のボックスに、BOX01からBOX04までのli要素を並べる

04BOX04の位置指定

04 BOX04の位置指定

今回の構造では、トップページであるBOX02の下にBOX04を配置している

06JavaScript記述例

06 JavaScript記述例

まずは「$(window).height()」でウインドウの高さを取得し、その値を「#flickBox.block」の高さに与えている

05BOX02をトップページに指定

05 BOX02をトップページに指定

#flickBox全体が左右下にスライドする仕組みであるため、#flickBox自体の位置を調整する

SECTION2 指の動きに表示エリアを追従させる

指の動きに表示エリアを追従させる

フリックを実装する前段階として、JavaScriptで指の動きに表示エリアを追従させる機能を実現していこう。

タッチイベントで指の動きを読み取る

スマートフォンの画面をタッチした際には、タッチイベントが発生する。タッチイベントは、「touchstart(指でタッチした時)」「touchmove(タッチしたまま指を動かした時)」「touchend(指を離した時)」で構成されている。
これらの一連の動作をJavaScriptで読み取り、表示エリアを指の動きに追従させる(01)。この部分の基本スクリプトは、02を参照してほしい。なお、PCでの開発検証用に、タッチイベントとともにマウスイベント(mousedown/mousemove/mouseup)も記述している。

01表示エリアを指に追従させる

01 表示エリアを指に追従させる

指の動きに表示エリアが追従してくる。ただし、これだけでは「正しい」フリックとはならない

02タッチイベント基本スクリプト

02 タッチイベント基本スクリプト

「var isTouch」でタッチデバイスか否かの判断をし、タッチイベントとマウスイベントを切り替えている

タッチ開始から終わりまでのスクリプト

最初のイベントであるtouchstartでは、タッチした瞬間の「タッチしたポイント」と「#flickBox」の座標を取得している(03)。
次のtouchmoveでは、指を動かした先の座標を取得し、touchstartで取得した座標との差を計算している(04)。その差分の値だけ「#flickBox」を動かすことによって、指に追従する動きを実現しているわけだ(05)。
最後のtouchendでは、指を離したときに、指を動かした方向に#flickBoxをスライドさせればフリックが完成となる。しかし、指は垂直水平に動いているわけではないので、単純に実装すると「表示エリアがふらつく」ことになってしまう。そこで縦横の動作制限処理などの微調整が必要となるので、次のSECTIONで説明していこう。

03touchstart処理内容

03 touchstart処理内容

this.pageXとthis.pageYにはタッチした位置の座標が、this.leftとthis.topにはタッチした時の#flickBoxの位置の座標が代入される

04touchmove処理内容

04 touchmove処理内容

this.leftとthis.topに、タッチスタートした時からどれだけ指(座標)が移動したかの演算結果が代入される

05cssメソッドで#flickBoxの位置を指定

05 cssメソッドで#flickBoxの位置を指定

指を1px動かすたびに、このメソッドによって#flickBoxの位置が指定される

SECTION3 フリックを実現するスクリプトを追加

フリックを実現するスクリプトを追加

いよいよフリックの実装だ。指の動きが縦なのか横なのかを判別し、それぞれの動きに応じてフリックする方向を決めていこう。

global変数の指定

まずはタッチイベント内で使用される変数を定義しておく(01)。currentNumで現在何番目のボックスが表示されているか、leftFixPosとtopFixPosで各ボックスが表示エリアに表示される時の#flickBoxのX座標とY座標を定義している。

01変数定義

01 変数定義

currentNumは、BOX01が「0」、BOX02(トップ画面)が「1」、BOX03が「2」、BOX04が「3」と定義している。また、Android端末のさまざまな解像度に対応するために、「topFixPos」の4番目の値は「winH*-1」としてウインドウの高さ分、上に移動させている

縦横のどちらに追従するかの判別をする

touchmoveイベント内では、指がX座標に大きく動いていれば横に、Y座標に大きく動いていれば縦にしか動かないように制限している。これにより、「表示エリアがふらつく」ことなく追従する動きを実現できる(02)。

02縦横追従判別処理

02 縦横追従判別処理

SECTION2の05で用いた処理に、さらに縦横の判別処理を加えている

touchendでフリックを制御

touchendイベント内では、指でタッチした時と指を離した時の縦横判別、斜め方向へのフリックの制限、縦フリックはBOX02(トップ)とBOX04の間のみで実行といった制御を行なっている(03)。また、ほんの少し触れただけでフリックが動作してしまうなど、過敏すぎても操作感が悪くなってしまうため、「指が30px以上動いてから指を離した場合(this.pageXdiff>30)にフリックする」という条件で、操作感の向上を図っている。
フリックのアニメーションには、jQueryのanimateメソッドを用いているので(04)、「jQuery Easing」(05)で好きな動きをつけることも可能だ。

03フリック制御スクリプト

03 フリック制御スクリプト

「X座標移動値がY座標移動値よりも大きいか否か」というようにフリック方向の縦横判別を行い、その入れ子内で「指が30px以上動いたかどうか」と「現在、どのBOXが表示されているか」を並列で判別した結果によってcurrentNumの値を処理し、フリック終了後にどのBOXにスライドさせるかを制御している

04フリックアニメーション

04 フリックアニメーション

フリック時のBOXの動き方は、この部分で制御している

05jQuery Easing

05 jQuery Easing

http://gsgd.co.uk/sandbox/jquery/easing/

jQueryのアニメーションの加速・減速を制御するプラグイン。これを用いることで、画面切り替え時の表現が豊かになる

お問い合わせはこちらからどうぞ