物体の減速運動 ver.0.0.1
position:absolute とされた div の領域をマウスでドラッグしたときに,Drop 後に慣性の法則で移動させるための JavaScript. 一応,等速度運動では,止まらないので,摩擦による減速を想定する.
とりあえず,ソースはこんな感じ.
function moving() {
vx *= 0.99; vx = intVal(vx); /* 減速処理 */
vy *= 0.99; vy = intVal(vy);
var dx = parseInt(div.style.left) + intVal(vx/10); /* 移動距離計算 */
var dy = parseInt(div.style.top) + intVal(vy/10);
if(dx < 0) {
vx = -vx; dx = 0; /* 移動領域制御 */
} else if (dx > 500) {
vx = -vx; dx = 500;
}
if(dy < 0) {
vy = -vy; dy = 0;
} else if(dy > 500) {
vy = -vy; dy = 500;
}
div.style.left = dx + 'px'; /* 表示位置指定 */
div.style.top = dy + 'px';
div.removeChild(div.lastChild);
div.appendChild(document.createTextNode("x:"+vx+" y:"+vy));
if(Math.abs(vx) > 10 || Math.abs(vy) > 10) { /* 再帰モドキ */
setTimeout("moving()", 10);
}
}
この moving() を Drag&Drop の javascript の mouseup の時の動作の最後に setTimeout("moving()",10); のような形で追加して動作をさせる.同じく初速の計算も, mouseup時に行なう.ここでは,mousedown 時点のマウスの座標から,mouseup での座標の差分を方向ベクトルとして,移動時間でベクトルの大きさを決定している.もしかするともう少し適切な方法があるかもしれない.
このとき,style の left, top には整数値しか利用できないので, 下記のような関数を作成して整数部のみを取り出した.
function intVal(n) {
return (n > 0) ? Math.floor(n) : Math.ceil(n);
}
floor のみだと,負の整数も正の整数として出力され, ceil だと繰り上げなため,最終的な速度が 0 に近い状態になれない場合があるので注意が必要.
ToDo
- マウスの移動速度の取り方の工夫が必要
- 速度が速すぎるときには描画タイミングで対応したほうがよい?