🎃
複数のボールが自由落下するアニメーション
HTML:class-itemは自由落下するボールを表しています。現在は6個表示していますが、コピペし任意の数に変更できます。
falldowns.html
<div id="stage">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
falldowns.css
#stage {
position:relative;
border:1px solid #666;
width:100%;
height:450px;
}
/* 移動するアイテム */
.item {
position:absolute;
margin:0 auto;
border-radius:50%;
}
falldowns.js
var gravity = 1.8,
v0 = 0,
y0 = {},
y={},
v={},
x={},
baseY={},
sid={},
b = {},//輝度
size = {},
damping = 0.7, // 反発係数(減衰)
time = 0.03, // 経過時間(秒)
itemElem = document.querySelectorAll('.item'),//動作対象
stageElem = document.getElementById('stage');//監視対象
let options = {threshold:0.1};
for (let i = 0; i < itemElem.length; i++) {
y[i] = Math.random()* 100; //初期位置
x[i] = Math.random()* 300;
y0[i] = y[i];
v[i] =0 ; //初期速度
b[i] = Math.random()*360;//色相
size[i] = Math.random()*15 + 25;
baseY[i] = stageElem.clientHeight - itemElem[i].clientHeight; //着地地点
}
// 位置を算出
var calcPosition = function() {
for (let i = 0; i < itemElem.length; i++) {
v[i] += v0 + (gravity * time); // 速度v
y[i] += v[i]* time ; // 位置y
if (y[i] > baseY[i]) {
y[i] = baseY[i];//着地地点
v[i] *= -damping;//バウンド動作
}}};
var updatePosition = function() {//アイテム要素の位置を更新
for (let i = 0; i < itemElem.length; i++) {
itemElem[i].style.top = y[i] - size[i] + 'px';
itemElem[i].style.left = x[i] + 'px';
}
};
updatePosition();// 初期位置
//監視
const io = new IntersectionObserver(callback,options);
io.observe(stageElem);
// アニメーション
function callback(entries){
if(entries[0].isIntersecting) {
for (let i = 0; i < itemElem.length; i++) {
sid[i] = setInterval(function() {
itemElem[i].style.backgroundColor = "hsl("+b[i]+",45%,70%,0.5)";//色
itemElem[i].style.width = size[i] + "px";
itemElem[i].style.height = size[i] + "px";
calcPosition();
updatePosition();
switch(entries[0].isIntersecting){
case false:
clearInterval(sid[i]);
break;
case true:
if (y[i] === baseY[i] && Math.abs(v[i]) <= gravity / 2){
clearInterval(sid[i]);//条件満たした際に止める
}
}
})}
}else{
for (let i = 0; i < itemElem.length; i++) {
y[i]=y0[i];
v[i]=0;
itemElem[i].style.top =y[i]+size[i] + 'px';
itemElem[i].style.left = x[i] + 'px';
}
}
};
Discussion