Skip to content

Instantly share code, notes, and snippets.

@kobitoDevelopment
Last active April 23, 2022 13:35
Show Gist options
  • Save kobitoDevelopment/449a8a18659b8aa0dc2a02e38db1a5cc to your computer and use it in GitHub Desktop.
Save kobitoDevelopment/449a8a18659b8aa0dc2a02e38db1a5cc to your computer and use it in GitHub Desktop.
<div id="icon-catch" class="stage">
<div class="center">
<div class="icon">
</div>
</div>
</div>
const iconCatch = document.querySelector("#icon-catch");
const center = iconCatch.querySelector(".center");
const icon = iconCatch.querySelector(".icon");
//関数宣言前に「async」を記述すると、その関数はPromiseを返す
const popCenterStar = async function () {
// asyncの中にawaitを記述すると、asyncはawaitの結果が返ってくるまで実行を一時停止する
await icon.animate([{ transform: `scale(1)` }, { transform: `scale(0.6)` }], {
duration: 150,
}).finished; // WebAnimationsApiでの.finishedは終了を検知させるためのPromiseを返す
// このアニメーションは完了を待たずに次の処理に移る
icon.animate([{ transform: `scale(0.6)` }, { transform: `scale(1)` }], {
duration: 500,
easing: "ease-out",
});
};
// クリック時のアニメーション
const emitParticles = async function () {
await popCenterStar();
// div.dotをCOUNT個作成
const COUNT = 20;
for (let i = 0; i < COUNT; i++) {
center.insertAdjacentHTML("beforeend", "<div class='dot'></div>");
}
const dots = document.querySelectorAll(".dot");
const animations = [...dots].map(function (dot) {
//querySelectorAllは配列ではなくNodeListを返すため、スプレッド構文等で配列に変換する(mapを使用するには配列である必要あり)
const angle = 360 * Math.random();
const dist = 100 + Math.random() * 50;
const size = 0.5 + Math.random() * 2;
const hue = 30 + Math.random() * 25;
dot.style.backgroundColor = `hsl(${hue}, 90%, 60%)`;
return dot.animate(
[
{
transform: `rotate(${angle}deg) translateX(0px) scale(${size})`,
opacity: 1,
},
{
transform: `rotate(${angle}deg) translateX(${dist}px) scale(${size})`,
opacity: 1,
offset: 0.8,
},
{
transform: `rotate(${angle}deg) translateX(${dist}px) scale(${size})`,
opacity: 0,
},
],
{
duration: 700 * Math.random(),
}
);
});
// 全てのアニメーションが終わるまで待つ
await Promise.all(
animations.map(function (anim) {
return anim.finished;
})
);
//アニメーション終了後の挙動を記述
dots.forEach(function (elem, index) {
elem.remove();
});
};
// クリックでアニメーションを実行
iconCatch.addEventListener("click", emitParticles);
.stage {
width: 400px;
height: 400px;
position: relative;
.center {
position: relative;
width: 0;
height: 0;
left: 50%;
top: 50%;
}
.icon {
position: absolute;
z-index: 1;
&::after {
content: "";
position: absolute;
width: 50px;
height: 50px;
left: -25px;
top: -25px;
background-image: url(../images/star.svg);
background-size: 50px;
background-repeat: no-repeat;
}
}
.dot {
position: absolute;
width: 10px;
height: 10px;
left: -5px;
top: -5px;
border-radius: 10px;
transition: all 0.5s;
opacity: 1;
background-color: gold;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment