Titaniumで、いい感じのカルーセルUIを作る方法
Titanium™ Advent Calendar 2013の10日目です。
いい感じにスライドするカルーセルを作るためのTips
ScrollViewとScrollableViewって似てて紛らわしいですよね。
で、ここで突然問題です。
勢い良くスワイプしたらその分、ススーってスライドするけど、最後止まるときは、どれかのviewが画面に収まる形でパッと止めるには、どうすればいいのか?
ScrollableView
ScrollableViewを使うと、一枚一枚のviewが紙芝居のようにスクロールします。ですが、勢い良くスワイプしても1つとなりのViewに移動するだけで、パッと止まってしまいます。
ScrollView
ScrollViewを使うと、勢い良くスワイプしたらその分の距離スライドしてくれますが、そのまま慣性の法則で動くだけで、キリのいいところで止まってくれません。
うまくミックスしてイケてるカルーセルができないかな?
いいとこ取りするんだ!
色々と考えたところ、以下の方法で進めました。
まず、ベースとしては、ScrollViewを作って、そこにView1,View2,View3…を乗せて行きます。
これでは、ViewNにぴたりと止まる部分がないため、慣性の法則のまま、止まってしまいます。
ここを以下にクリアするかぁぁ!!!!!!が、今回の話しのメインです。
ススーっと動いて、ぴたっと止める処理
ソースコードで説明します。
var carousel = Ti.createScrollView();
// スクロールイベント
carousel.addEventListener('scroll',function(e){
scrollStatus(e);
});
scrollイベントに、scrollStatus()という関数を仕込みます。
function scrollStatus(e){
// 今の位置からページ算出
var currentPage = parseInt((e.x + pageSize/2) / pageSize);
// 減速中に位置調整
if(e.decelerating){
adjustPosition(e.x, pre_x);
}
// 前の座標を保存
pre_x = e.x;
}
scrollイベントのプロパティにdeceleratingというのがあります。これは減速中かどうかを表すパラメータです。減速してない間(勢いよくスライドしている間)は位置調整しません。
// スクロール位置調整
function adjustPosition(x,pre_x){
// スクロール速度
var dx = Math.abs(x - pre_x);
// 速度が落ちたら
if(dx < 5){
// 移動
carousel.scrollTo((currentPage * pageSize),0);
}
}
位置調整処理の中身です。scrollToで表示したいページに移動します。
ポイント
苦労した点は、どうやったら滑らかに動いて止まってくれるか?でした。
最初作ったときは、完全に止まったときにscrollToさせていたのですが、ものすごく不自然な動きになったので、じゃあ、どういうタイミングでscrollToさせれば自然になるのか?
その答えが スライドの速度が遅くなった時 でした。
前の座標(pre_x)と現在地(x)から速度(dx)を算出して、規定値より少なくなれば、scrollToする、という処理にすることで、かなり滑らかになりました。
実際の動き
ソースコードだけじゃイメージ分からなーい!ですよね?
なんと「Petap」というアプリで実装しております。
一度DLして動き見てみてくださいー!