マウスホイールで減速するイージングを試してみた
ちょっとjavascriptとjqueryを使って、マウスホイールのイベント(mousewheel)でイージングをやってみたいと思ったのでメモ。
jqueryのイージングのプラグインを使えばすぐ出来そうですが今回は使わないでおきます。
目次
やってみたいこと
マウスホイールの操作でdiv要素で作ったボックスを左右に移動するアニメーションをさせて、ホイールをやめてもいきなり停止せずに余韻で減速するイージングを表現させる。
今回の記事の内容とは関係ないが、ウィンドウの幅を超えたら反対側から出てくる処理をしています。(笑)
とりあえず全部のプログラムを載せておきます。
$(document).ready(function(){
var velocity=0; //移動の方向と加速度
var friction=0.9; //摩擦 減速させるための数値
var timer = null;
var box=$("#box");
var w_width=$(window).width();
var leftwall=0-box.width(); //ウィンドウの左側の壁
var pos_left=0; //ボックスの横の位置
$("#res").text("変数velocity(速度の方向と加速度)"+velocity);
$("#res").text("移動量"+velocity);
$("#res2").text("ボックスの座標:"+pos_left);
window.addEventListener("mousewheel",mouseWheelFunc,false);
//マウスホイールのイベント
function mouseWheelFunc(e){
//デフォルトのスクロール動作を止める
e.preventDefault();
//マウスのホイールの移動量
var delta=e.wheelDelta;
//マウスホイールの移動量(上下操作)で加速度の方向を左か右かに分ける
if(delta < 0){
velocity+=1.5;
}else if(delta > 0){
velocity-=1.5;
}
//マウスホイールのイベント発生時はアニメーションを実行
startAnime();
}
//setIntervalを実行する処理
function startAnime(){
if(!timer){
//1/60秒ごとに更新
timer=setInterval(easingFunc,33);
}
}
//clearIntervalでアニメーションを止める
function stopAnime(){
clearInterval(timer);
timer=null;
}
//イージングで減速させる為の処理
function easingFunc(){
//0.9の摩擦をかけることで減速をさせる処理
velocity*=friction;
//現在のボックスの位置を取得
pos_left=box.offset().left;
//現在の位置に加速度を足すとイージングになる
box.css("left",pos_left+velocity);
$("#res").text("変数velocity(速度の方向と加速度)"+velocity);
$("#res2").text("ボックスの座標:"+pos_left);
//ウィンドウの端っこにいったら反対側から出す
if(pos_left -0.09){
stopAnime();
}
}
//ウィンドウのリサイズが変わった時のイベント
$(window).resize(function(){
//ウィンドウのサイズを再度、取得
w_width=$(window).width();
$("#res3").text("ウィンドウサイズは:"+w_width);
});
});
全部を説明すると長くなるので、よいしょよいしょ説明していこうかと思います。
マウスホイールのイベント時の処理
マウスホイールさせたときに発生するイベント「mousewheel」のt時の処理を説明してみます。
マウスホイールの移動量を取得する
まずマウスホイールが上に回されてたのか、下に回されたのかのマウスホイールの移動量を判別する必要があるのですが、それはマウスホイールイベントのイベントオブジェクトの「wheelDelta」プロパティで確認できます。
//マウスのホイールの移動量
var delta=e.wheelDelta;
ちなみに、google chromeだと上に回すと「120」で下に回すと「-120」という数値になります。
移動の方向と加速度を決める
マウスホイールの移動量を調べたら、その数値を元にどの方向に移動されるか?といった速度の方向と加速度を設定します。
//マウスホイールの移動量(上下操作)で加速度の方向を左か右かに分ける
if(delta < 0){
velocity+=1.5;
}else if(delta > 0){
velocity-=1.5;
}
if文を使って、移動量が0以下の場合は「1.5」の数値分を変数velocityに加算させていき、0以上の場合は、減算させていきます。
ここの数値によって加速度が決まるので、もっとスピードを早くしたい場合は、ここの数値をもう少し上げるといいです。
setIntervalでアニメーションをさせる
マウスホイールのイベント発生時にボックスを移動するためのアニメーションを設定しないといけないので、startAnimeという関数をマウスホイール時に発生させます。
startAnime();
//setIntervalを実行する処理
function startAnime(){
if(!timer){
//1/60秒ごとに更新
timer=setInterval(easingFunc,33);
}
}
startAnime関数は、変数timerがnull以外のときにsetinterval関数でeasingFunc関数を1/60秒ごとに実行する仕組みを設定しています。
アニメーションさせる関数の処理
easingFunc関数でボックスのアニメーションと減速させたり、ボックスをアニメーションさせる処理などを記述する。
摩擦をかけることで減速させる
最初のマウスホイールのmousewheelイベント時に変数velocityに加算と減算をさせましたが、それと同時にsetIntevalでアニメーションが実行されているので、変数velocityに変数frictionで0.9の摩擦をかけつづけることにより減速する仕組みなります。
//0.9の摩擦をかけることで減速をさせる処理
velocity*=friction;
ボックスの位置を取得してcssで移動させる
ボックスをアニメーションさせるには、リアルタイムにボックスの位置を取得する必要があるのでjQueryのoffset関数のleftプロパティで位置を取得します。
//現在のボックスの位置を取得
pos_left=box.offset().left;
現在のボックスの位置を取得したら、jQueryのCSSの設定で現在の位置に加算させた変数velocityを足すことでボックスがアニメーションします。
//現在の位置に加速度を足す
box.css("left",pos_left+velocity);
この設定により、setIntervalでボックスの位置が常に更新されアニメーションしつつ、変数frictionで摩擦をかけてるので減速していくようになる。
アニメーションを止める
ボックスのアニメーションでイージングで減速させていくと必ずボックスは止まるので、setIntervalも止めないといけないのでstopAnime関数を実行します。
//下記の数値になったらアニメーションを止める
if(velocity < 0.09 && velocity > -0.09){
stopAnime();
}
//clearIntervalでアニメーションを止める
function stopAnime(){
clearInterval(timer);
timer=null;
}
stopAnime関数自体はclearIntervalでアニメーションを解除している処理のみになります。
この処理をどのタイミングで実行するかなんですが、変数velocityの数値で、0.09以下になったときと-0.09以上になった時に実行させます。この数値はあくまで目安です。
サンプルでは、確認用に変数velocityの値を表示させているので、それを目安に数値を決めてもいいと思いますが、0.09でも0.07でもあまり替わらないと思います。(笑)
ウィンドウの幅を超えたら反対側から出てくる処理
これも、よくある処理だと思いますが、いたって簡単です。
両再度の幅の位置を取得
まずは、右側の位置ですが、これはウィンドウの幅になるので、width()で取得できます。左側の位置ですが、左端はもちろん位置は0になるのですが、0を基準とるすと急にボックスが移動することになってしまうので、基準を0からボックスの幅を引いた値を基準とします。これは、ボックスの位置の基準点が左上が基準値となっているためです。
var w_width=$(window).width();
var leftwall=0-box.width(); //ウィンドウの左側の壁
反対側から表示させる仕組み
両再度の反対側から表示させる仕組みは、常にボックスの位置を監視していないといけないので、setIntervalで実行しているeasingFunc関数内に記述します。
//ウィンドウの端っこにいったら反対側から出す
if(pos_left
if文を使って、両サイドの壁を越えたら、jQueryのCSSで反対側の位置へ移動させればいいだけです。まぁここら辺は、単純なので特に難しいこともないと思います。
まとめ
最近は、jQueryが普通に遣われているので、jQueryでも実現できると思います。下記のサイトも参考になると思います。