落下と跳ね返り

デモ

計算式

物体が重力によって落下していく計算は次のような計算式を用います。

落下速度

v=v0+a×t

v  ...  落下速度
v0  ...  初速度
a  ...  加速度
t  ...  経過時間(秒)
  • ※ 加速度(a)は自由落下なので重力加速度(g)に置き換わります。

落下距離

y = vt

y  ...  落下位置
v0  ...  初速度
v  ...  落下速度
t  ...  経過時間(秒)
  • ※ 自由落下としての計算式は y=v0t+二分の一×g×t二乗ですが、プログラム上の自然な動きはy = vtのほうが自由に制御できます。

サンプルコード

  • ※ (地球の)重力加速度は9.8(m/s²)です。
  • ※ 空気抵抗摩擦は考慮していません。

HTML

<div id="stage">
	<div id="item"></div>
</div>

CSS

/* 範囲 */
#stage {
	position:relative;
	border-bottom:2px solid #666;
	width:300px;
	height:300px;
}

/* 移動するアイテム */
#item {
	position:absolute;
	left:0;
	right:0;
	margin:0 auto;
	border-radius:50%;
	width:20px;
	height:20px;
	background-color:#d00;
}

JavaScript

var gravity = 9.8,  // 重力加速度
	v0      = 0,    // 初速度
    damping = 0.8,  // 反発係数(減衰)
    time    = 0.15; // 瞬間経過時間(秒)

// 要素を取得
var stageElem = document.getElementById('stage'),
    itemElem  = document.getElementById('item');

// 着地地点(落下距離)を取得
var baseY = stageElem.clientHeight - itemElem.clientHeight;

// 初期化
var v = 0, y = 0;

/**
 * 位置を算出
 */
var calcPosition = function() {
	// 瞬間速度を算出
	v += v0 + (gravity * time);

	// 次の落下位置を算出
	y += v * time;

	// 着地地点を超えたら跳ねて上げるための処理
	if (y > baseY) {
		// 位置を着地地点に設定
		y = baseY;

		// 反発係数(減衰)をマイナスで速度に当てて上方向に移動するようにする
		v *= -damping;
	}
};

/**
 * アイテム要素の位置を更新
 */
var updatePosition = function() {
	itemElem.style.top = y + 'px';
};

// 初期位置を設定
updatePosition();

// 落下をアニメーション
var sid = setInterval(function() {
	calcPosition();
	updatePosition();

	// 着地地点に到達したらアニメーションを停止
	if (y === baseY && Math.abs(v) <= gravity / 2) {
		clearInterval(sid);
	}
});

ポイント

反発係数(減衰)は0から1の間で指定します。
0に近づくほど反発が強くなります。

瞬間経過時間は現在の位置から次の位置までの間の時間です。
短いほどゆっくり動きます。

着地地点(落下距離)を取得する際は、CSSのtopプロパティを制御しますので、動かす物体の高さ分を削る必要があります。

setInterval関数でミリ秒毎に次の物体の位置を計算して設定します。

瞬間速度は現在の位置から次の位置までの間の速度です。

落下時に次の位置が着地地点に到達していたら、瞬間速度に反発係数(減衰)をマイナス値で計算して与えることで、上方向に跳ね上げます。
跳ね上げの際に瞬間速度はマイナス値になりますが、瞬間速度の計算でプラス値を与え続けていきますので、いずれ落下するようになります。

JavaScript逆引きリファレンス一覧へ戻る