
たくさんのアニメーションライブラリの中で今回はAnime.jsの基本的なことをメモします。
Anime.jsとは?
Anime.jsは、軽量かつ柔軟なJavaScriptライブラリで、シンプルな構文で、複雑なアニメーションも比較的簡単に作成できます。SVGやJavaScriptオブジェクトのアニメーションも実現可能です。
Anime.jsを導入する
導入にはいくつかありますが、今回はCDNを使用します。
<script src="https://cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js"></script>
基本的なアニメーションを作成する
オブジェクトを左から右に動かすアニメーションを作ってみます。
anime({
targets: 'h2',
translateX: 400,
duration: 800
});
これだけで左から右にオブジェクトがアニメーションで移動します。
これにrotateを加えると回転しながら移動します。
anime({
targets: 'h2',
translateX: 400,
rotate: '1turn',
duration: 800
});
シンプルですね。
スクロールで表示されたらアニメーションを開始する
2つのオブジェクトをスクロールでアニメーションが発火するようにします。
オブジェクトはX方向とY方向で別の動きを設定します。
const textEl = document.querySelector("h2,h3");
const text = textEl.textContent;
textEl.textContent = "";
const animation = anime({
targets: 'h2',
translateX: 400,
rotate: '1turn',
duration: 800,
opacity: [0, 1],
delay: anime.stagger(100),
autoplay: false // 自動再生しない
});
const animation2 = anime({
targets: 'h3',
translateY: 100,
rotate: '1turn',
duration: 1500,
opacity: [0, 1],
delay: anime.stagger(300),
autoplay: false // 自動再生しない
});
// IntersectionObserver でスクロール監視
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
animation.restart(); // 見えたら再生
animation2.restart(); // 見えたら再生
}
});
}, { threshold: 0.3 }); // 30%見えたら発火
observer.observe(textEl);
IntersectionObserverで要素を監視するコードを追加します。
これにより表示されたら発火する様になります。
一度スクロールで表示されたら次回以降はアニメーションしない
上記の応用で、1回表示され発火したらを2回目以降発火させない様にします。
const textEls = document.querySelectorAll("h2, h3");
textEls.forEach(textEl => {
// アニメーション設定(要素ごとに個別)
let animeOptions = {
targets: textEl,
rotate: '1turn',
opacity: [0,1],
autoplay: false
};
// h2 と h3 で動きを分ける
if (textEl.tagName.toLowerCase() === "h2") {
animeOptions.translateX = 400;
animeOptions.duration = 800;
delay: anime.stagger(100);
} else if (textEl.tagName.toLowerCase() === "h3") {
animeOptions.translateY = 100;
animeOptions.duration = 1500;
delay: anime.stagger(300);
}
const animation = anime(animeOptions);
// IntersectionObserver でスクロール監視(1回だけ)
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
animation.play();
observer.unobserve(textEl); // 2回目以降は発火しない
}
});
}, { threshold: 0.3 });
observer.observe(textEl);
});
別々の動きをする2つのオブジェクトを今回は共通設定と個別設定で分けています。
IntersectionObserverで監視するコードにunobserveを追加しています。
これにより2回目以降発火しないようにしています。
テキストアニメーションを作ってみる
上記を応用してHELLO WORLDというテキストをバウンドするアニメーションにします。
IntersectionObserverを使用して2回目以降発火しないようにします。
const textEls = document.querySelectorAll("h2, h3");
textEls.forEach(textEl => {
const text = textEl.textContent;
textEl.textContent = "";
// span でラップ
text.split("").forEach(char => {
const span = document.createElement("span");
span.textContent = char;
textEl.appendChild(span);
});
// アニメーション定義(要素ごとに作成)
const animation = anime({
targets: textEl.querySelectorAll("span"),
translateY: [
{ value: "-40px", easing: "easeOutExpo", duration: 600 },
{ value: 0, easing: "easeOutBounce", duration: 800 }
],
opacity: [0, 1],
delay: anime.stagger(100),
autoplay: false
});
// IntersectionObserver で監視(要素ごとに)
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
animation.play();
observer.unobserve(textEl); // 1回だけ
}
});
}, { threshold: 0.3 });
observer.observe(textEl);
});
今回は2つのオブジェクトは同じ動きにしています。
h2とh3内のテキスト1文字づつにspanを加え、1文字づつ、ディレイしながら上下にバウンドするよアニメーションになっています。
まとめ
Anime.jsは、複雑なアニメーションも手軽に実装できSVGにも対応可能です。
とにかくバリエーションが豊富でGsapのようなタイムラインやゲームも可能です。
またAnime.jsオフィシャルサイトがイケてます。ぜひアクセスしてみてください。