anime-js について
Anime.js と JavaScript による Web アニメーションの制作ガイドスキルです。シーケンス、パフォーマンス、アクセシビリティを扱い、インタラクションや React のアニメーション実装に役立ちます。
主な機能
- 01タイムラインとスタガーアニメーション
- 02SVG パスアニメーションとモーフィング
- 03イージングと動的な値
- 04React 連携ガイド
- 05パフォーマンスとモーション低減への対応
活用シーン
- 01複数要素のアニメーションを順序付ける
- 02SVG パスをアニメーション化する
- 03React コンポーネントに動きを加える
- 04モーション低減設定に対応する
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mindrally/ skills --skill anime-jsインストール後、Claude Code で/anime-jsを入力して読み込まれたか確認します。
詳細
Anime.js アニメーションガイドライン
Anime.js、JavaScript、Web アニメーションのパフォーマンスに精通していることを前提としています。アニメーションを作成するときは、以下のガイドラインに従ってください。
基本原則
インストールとインポート
npm install animejs
// Full import
import anime from "animejs";
// Modular import for smaller bundle size
import { animate, timeline, stagger } from "animejs";
基本的なアニメーション
anime({
targets: ".element",
translateX: 250,
rotate: "1turn",
duration: 800,
easing: "easeInOutQuad"
});
パフォーマンスの最適化
フレームレートの制御
// Adjust global frame rate for lower-end devices
anime.suspendWhenDocumentHidden = true;
// Control FPS for specific animations
anime({
targets: ".element",
translateX: 250,
update: function(anim) {
// Custom frame rate limiting if needed
}
});
レイアウトプロパティよりトランスフォームを使う
// Good - uses GPU-accelerated transforms
anime({
targets: ".element",
translateX: 100, // Good
translateY: 50, // Good
scale: 1.2, // Good
rotate: 45, // Good
opacity: 0.5 // Good
});
// Avoid - causes layout recalculation
anime({
targets: ".element",
left: 100, // Avoid
top: 50, // Avoid
width: 200, // Avoid
height: 150 // Avoid
});
高頻度の更新には Animatable を使う
import { Animatable } from "animejs";
// Optimized for continuous updates (mouse tracking, etc.)
const animatable = new Animatable(".cursor", {
x: 0,
y: 0
});
document.addEventListener("mousemove", (e) => {
animatable.x = e.clientX;
animatable.y = e.clientY;
});
タイムラインアニメーション
基本的なタイムライン
const tl = anime.timeline({
easing: "easeOutExpo",
duration: 750
});
tl.add({
targets: ".header",
translateY: [-50, 0],
opacity: [0, 1]
})
.add({
targets: ".content",
translateY: [30, 0],
opacity: [0, 1]
}, "-=500") // Overlap by 500ms
.add({
targets: ".footer",
translateY: [30, 0],
opacity: [0, 1]
}, "-=500");
タイムラインの制御
const tl = anime.timeline({
autoplay: false
});
// Control methods
tl.play();
tl.pause();
tl.restart();
tl.reverse();
tl.seek(1000); // Go to 1 second
スタガーアニメーション
基本的なスタガー
anime({
targets: ".grid-item",
translateY: [50, 0],
opacity: [0, 1],
delay: anime.stagger(100) // 100ms delay between each
});
高度なスタガーオプション
// Stagger from center
anime({
targets: ".grid-item",
scale: [0, 1],
delay: anime.stagger(100, { from: "center" })
});
// Grid stagger
anime({
targets: ".grid-item",
scale: [0, 1],
delay: anime.stagger(50, {
grid: [14, 5],
from: "center"
})
});
// Stagger with easing
anime({
targets: ".item",
translateX: 250,
delay: anime.stagger(100, { easing: "easeOutQuad" })
});
イージング関数
組み込みのイージング
// Common easings
anime({
targets: ".element",
translateX: 250,
easing: "easeOutExpo" // Fast start, slow end
// easing: "easeInOutQuad" // Smooth both ends
// easing: "easeOutElastic(1, .5)" // Bouncy
// easing: "easeOutBounce" // Bounce effect
// easing: "spring(1, 80, 10, 0)" // Physics-based
});
カスタムイージング
anime({
targets: ".element",
translateX: 250,
easing: "cubicBezier(0.25, 0.1, 0.25, 1)"
});
SVG アニメーション
パスアニメーション
const path = anime.path(".motion-path");
anime({
targets: ".element",
translateX: path("x"),
translateY: path("y"),
rotate: path("angle"),
easing: "linear",
duration: 2000,
loop: true
});
線の描画
anime({
targets: "path",
strokeDashoffset: [anime.setDashoffset, 0],
easing: "easeInOutSine",
duration: 1500,
delay: anime.stagger(250)
});
モーフィング
anime({
targets: "path",
d: [
{ value: "M10 10 L90 10 L90 90 L10 90 Z" },
{ value: "M10 50 Q50 10 90 50 Q50 90 10 50 Z" }
],
easing: "easeInOutQuad",
duration: 1000,
loop: true,
direction: "alternate"
});
関数ベースの値
動的な値
anime({
targets: ".element",
translateX: function(el, i) {
return i * 100; // Each element moves further
},
rotate: function(el, i, total) {
return (360 / total) * i; // Distribute rotation
},
delay: function(el, i) {
return i * 50;
}
});
コールバックとイベント
アニメーションイベント
anime({
targets: ".element",
translateX: 250,
begin: function(anim) {
console.log("Animation started");
},
update: function(anim) {
console.log(Math.round(anim.progress) + "%");
},
complete: function(anim) {
console.log("Animation completed");
}
});
ループ
anime({
targets: ".element",
translateX: 250,
direction: "alternate",
loop: true,
loopComplete: function(anim) {
console.log("Loop completed");
}
});
React との統合
React の基本的な使い方
import { useEffect, useRef } from "react";
import anime from "animejs";
function AnimatedComponent() {
const elementRef = useRef(null);
useEffect(() => {
const animation = anime({
targets: elementRef.current,
translateX: 250,
duration: 800
});
return () => {
animation.pause(); // Cleanup
};
}, []);
return <div ref={elementRef}>Animated</div>;
}
制御に useCallback を使う
function ControlledAnimation() {
const elementRef = useRef(null);
const animationRef = useRef(null);
const playAnimation = useCallback(() => {
animationRef.current = anime({
targets: elementRef.current,
translateX: [0, 250],
duration: 800
});
}, []);
useEffect(() => {
return () => {
animationRef.current?.pause();
};
}, []);
return (
<>
<div ref={elementRef}>Animated</div>
<button onClick={playAnimation}>Play</button>
</>
);
}
Web Animations API ブリッジ
ネイティブパフォーマンスのために WAAPI を使う
import { wapiAnimate } from "animejs";
// Uses browser's native Web Animations API
wapiAnimate(".element", {
translateX: 250,
duration: 800
});
アクセシビリティ
モーション低減設定に従う
const prefersReducedMotion = window.matchMedia(
"(prefers-reduced-motion: reduce)"
).matches;
anime({
targets: ".element",
translateX: 250,
duration: prefersReducedMotion ? 0 : 800,
easing: prefersReducedMotion ? "linear" : "easeOutExpo"
});
ベストプラクティスのまとめ
- レイアウトプロパティよりトランスフォーム(translate、scale、rotate)を使います
- バンドルサイズを小さくするため、必要なモジュールだけをインポートします
- 複数の要素をアニメーションさせるにはスタガーを使います
- コンポーネントのアンマウント時にアニメーションをクリーンアップします
- 高頻度の更新には Animatable を使います
- 複雑なシーケンスにはタイムラインを活用します
- 動的なアニメーションには関数ベースの値を使います
- モーション低減設定を尊重します
- ネイティブパフォーマンスのため、WAAPI ブリッジを検討します
- 低性能のデバイスでテストします
コメント
Markdown 対応