マウススクロールで1画面単位で上下にスライドする
発端はASUSのスマートフォンを紹介するサイトでした。
http://www.asus.com/jp/Phones/ZenFone_5_A500KL/
ZenFone 5のライティングページですが、マウスのスクロールボタンを回すとブラウザ全体を一気にスクロールして製品を紹介しています。この動きがちょっと格好良いなぁと思いまして。探せばおそらくはjQueryプラグインなどあるでしょうが、いつものごとく先ずは自分で試行錯誤してみます。
ただ、ASUSUのページはレスポンシブデザインではあるのですが、スマートフォン(タブレットでも)だとこの動きを封じて普通のスクロールになっています。また、キーボードの↑↓では反応しない、スクロールバーを移動しても途中で止まるようです。
これはこういう仕様というか、これが正解なのかもしれませんが、もう少し詰めてみたいと思います。
目指すもの
・ブラウザの縦・横のサイズに合わせてボックスを全画面にする
・キーボードの↑↓で反応させる
・ブラウザのスクロールバーでも反応させる
・タッチパネル対応機種にも対応させる
考え方
先ず、ロード時及びブラウザサイズ変更時に、指定したボックスの縦・横の幅をウインドのサイズに変更します。今回はボックス内のコンテンツは作成していませんが、jQueryなりEdge Animateなりで作成する事になると思います。
次に、スクロール量に関係なく1画面づつ自動でスクロールさせるのが目的なので、スクロールイベントに仕込むのが安易ですが妥当かと思います。スクロールが↑なのか↓なのか、これに応じて次のボックス(前のボックス)の上端をブラウザの上端まで移動させれば良いのでしょう。
とりあえずサンプル
動きは期待したものになっていますが、IEやChromeだとスクロール開始時に少しカクっとなります。Firefox(私はWaterFoxですが)だとスムーズ。
ボックスのHTMLとプラグインの設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | < div id = "container" data-memory = "1" data-mobile = "" data-touch = "" data-move = "" > < div class = "wrap" id = "box1" style = " background: #0064FF" >BOX 1</ div > < div class = "wrap" id = "box2" style = " background: #008000" >BOX 2</ div > < div class = "wrap" id = "box3" style = " background: #ff7d27" >BOX 3</ div > < div class = "wrap" id = "box4" style = " background: #ee0101" >BOX 4</ div > < div class = "wrap" id = "box5" style = " background: #4D4D4D" >BOX 5</ div > </ div > < script type = "text/javascript" > jQuery(function(){ jQuery('.wrap').PresenSlide({ memory: '#container' //jquery dataを指定した場所 ,box: '#box' //ボックスのid名(数値抜) }); }); </ script > |
ボックスはwrapというclass名で、idの方はboxという文字に連番を振ります。それぞれ設定した名前をjQueryへ設定します。また、現在のボックス番号を記録したりするためにjQuery.dataを使いますので、今回はそれをcontainerに設定しました。これもプラグインの方へ設定します。
問題点など
先ず、スクロールイベントだとスマートフォンでは期待した動作をしてくれない事が解り、タッチイベントが発生した場合は、スクロール時の処理をキャンセルし、タッチイベントをトリガーとして処理しました。が・・・がっつりスワイプすると、どうしても1ページづつ移動してくれません。おそらく、スマートフォンブラウザはアドレスバーが見え隠れするので、そのあたりが問題なのかと思います。どうしても処理出来ず、これはここで断念。
パソコンの方ですが、これはスクロールした際に、scrollTop()から上下どちらにスクロールしたかは簡単に判断出来ます。なので、↓なら次の枠に移動すれば良いだけなのですが、スクロールイベントをトリガーとしている以上、1ピクセルでもスクロールすれば次の枠に移動しようとします。つまり、スクロールしている間じゅう、何度も繰り返し発生してしまい、一番↓まで一気に移動してしまいました。
これを回避するためカウントを設定し、スクロール時に加算→ボックスが移動を終える(animate.complete)とカウントを0に戻すようにし、カウントが1以上の場合は次のスライドを発生させないようにしまた。が・・・・completeじゃスライドを終えたというトリガーとは出来ず、setTimeoutで遅延させました。なので、スライドを終えて次のスライドが可能になるまで0.5秒ほどディレイが有ります。
とまぁ問題山積みなのですが、PCだけに限定し、プレゼンのように使うならまぁ使えるかなぁという事で、もし同じような事をされていてお悩みの方は参考までにソースをどうぞ。試行錯誤がモロ解りな酷いソースなのですが。
ASUSのソースは見てませんが、動きがスムーズですのでスクロールイベントじゃない何かで処理してるのかなぁと思います。