0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ReactBits.devから学ぶ:ADALabサイトに27個のアニメーションコンポーネントを追加してUI大改善

0
Posted at

はじめに

ADALabのWebサイトをさらに魅力的にするため、ReactBits.devという素晴らしいコンポーネントライブラリから学び、UI改善を行いました。この記事では、追加した8つの新しいコンポーネントと、コードレビューでの学びを共有します。

ReactBits.devとは?

ReactBits.devは、110以上の高品質でアニメーション化されたReactコンポーネントを提供するオープンソースライブラリです。

ReactBitsの特徴

  • 豊富なバリエーション:110+のアニメーションコンポーネント
  • 高度なカスタマイズ性:propsを通じた柔軟な設定
  • TypeScript対応:型安全性の確保
  • 最小限の依存関係:シンプルな実装
  • 明確な分類:テキスト、ボタン、カード、背景の4カテゴリ

追加した8つの新しいコンポーネント

1. テキストアニメーション(4個)

ShimmerText - 光沢エフェクト

光が流れるようなシマーエフェクトを持つテキストコンポーネント。

interface ShimmerTextProps {
  children: React.ReactNode;
  className?: string;
  shimmerColor?: string;      // シマーの色
  duration?: number;           // アニメーション時間
  spread?: number;             // 光の広がり
}

使用例

<ShimmerText
  shimmerColor="rgba(0, 245, 255, 0.6)"
  duration={2}
>
  重要なお知らせ
</ShimmerText>

GradientText - グラデーションアニメーション

カラフルなグラデーションが動くテキストエフェクト。

interface GradientTextProps {
  children: React.ReactNode;
  className?: string;
  colors?: string[];           // グラデーションカラー配列
  animationDuration?: number;  // アニメーション時間
  animate?: boolean;           // アニメーションのON/OFF
}

実装例(Heroセクション)

<GradientText
  colors={['#00f5ff', '#ffffff', '#ff00ff', '#00f5ff']}
  animationDuration={4}
>
  Build. Ship. Scale.
</GradientText>

RevealText - リビールエフェクト

文字が順番に現れるアニメーション。

interface RevealTextProps {
  children: string;
  className?: string;
  delay?: number;              // 開始遅延
  duration?: number;           // 各文字の表示時間
  revealDirection?: 'up' | 'down' | 'left' | 'right';
  stagger?: number;            // 文字間の遅延
}

TextScramble - スクランブルエフェクト

ランダムな文字からテキストが形成されるエフェクト。

interface TextScrambleProps {
  children: string;
  className?: string;
  scrambleSpeed?: number;      // スクランブル速度
  characters?: string;         // 使用する文字セット
  startDelay?: number;         // 開始遅延
}

2. ボタンエフェクト(1個)

ShinyButton - 光沢ボタン

ホバー時に光が流れるボタンエフェクト。

interface ShinyButtonProps {
  children: React.ReactNode;
  className?: string;
  shineColor?: string;         // 光の色
  shineDuration?: number;      // 光の流れる速度
  shineWidth?: number;         // 光の幅
  onClick?: () => void;
}

3. カードエフェクト(1個)

SpotlightCard - スポットライトエフェクト

マウスに追従するスポットライトエフェクト付きカード。

interface SpotlightCardProps {
  children: React.ReactNode;
  className?: string;
  spotlightColor?: string;     // スポットライトの色
  spotlightSize?: number;      // スポットライトのサイズ
  borderRadius?: string;       // カードの角丸
}

4. 背景エフェクト(2個)

DotPattern - ドットパターン

カスタマイズ可能なドットパターン背景。

interface DotPatternProps {
  className?: string;
  dotSize?: number;            // ドットサイズ
  dotColor?: string;           // ドットの色
  gap?: number;                // ドット間隔
  animate?: boolean;           // アニメーションON/OFF
  fadeEdges?: boolean;         // 端のフェード効果
}

実装例(Heroセクション)

<DotPattern
  dotSize={1.5}
  gap={25}
  dotColor="#00f5ff"
  fadeEdges={true}
  animate={showParticles}
/>

WaveBackground - 波背景

波のようなアニメーション背景。

interface WaveBackgroundProps {
  className?: string;
  waveColor?: string;          // 波の色
  waveOpacity?: number;        // 波の透明度
  waveCount?: number;          // 波の数
  animationDuration?: number;  // アニメーション時間
}

コードレビューでの学び

GitHub Advanced Securityとcoderabbitaiからのレビューで、重要な問題が見つかりました。

1. 未使用インポートの削除

問題

import { RevealText } from '../effects/RevealText'; // 未使用

学び:未使用のインポートはバンドルサイズを増やし、コードを読みにくくします。

2. SpotlightCard - Opacity問題

問題

<div className="opacity-0 hover:opacity-100 pointer-events-none" />

pointer-events-noneにより、hoverが効かない。

修正

<motion.div
  initial={{ opacity: 0 }}
  animate={{ opacity: 1 }}
  exit={{ opacity: 0 }}
  transition={{ duration: 0.3 }}
/>

学び:CSSクラスとFramer Motionを組み合わせる際は、競合に注意。

3. WaveBackground - 負のOpacity問題

問題

opacity: waveOpacity - wave * 0.02  // 負の値になる可能性

waveCountが大きいと、opacityが負の値になる。

修正

opacity: Math.max(0, waveOpacity - wave * 0.02)

学び:計算結果が想定外の値にならないよう、バリデーションを追加。

4. WaveBackground - Transform競合

問題

animate={{ y: [-20, 20, -20] }}
style={{ transform: `scale(${1 + wave * 0.1})` }}

インラインtransformがFramer Motionのアニメーションと競合。

修正

initial={{ y: 0, scale: 1 + wave * 0.1 }}
animate={{ y: [-20, 20, -20], scale: 1 + wave * 0.1 }}

学び:Framer Motionを使う場合、すべてのtransformをFramer Motionで管理。

5. TextScramble - メモリリーク問題 🔴

問題

const startTimeout = setTimeout(() => {
  const intervalId = setInterval(() => { /* ... */ });

  return () => clearInterval(intervalId);  // ❌ 実行されない!
}, startDelay);

setTimeoutのコールバック内のreturnは、クリーンアップ関数として機能しない。

修正

useEffect(() => {
  let intervalId: NodeJS.Timeout | undefined;

  const startTimeout = setTimeout(() => {
    intervalId = setInterval(() => { /* ... */ });
  }, startDelay);

  return () => {
    clearTimeout(startTimeout);
    if (intervalId) clearInterval(intervalId);
  };
}, [dependencies]);

学び

  • useEffectのクリーンアップ関数は、useEffect自体のreturnでのみ定義
  • タイマーIDをスコープ変数で管理
  • メモリリークを防ぐため、すべてのタイマーを確実にクリア

改善の成果

コンポーネント数の増加

改善前: 19個
改善後: 27個以上(+42%)

カテゴリ分類

ReactBitsから学び、明確に分類:

  • 📝 テキストアニメーション:6個
  • 🎯 ボタンエフェクト:2個
  • 🃏 カードエフェクト:1個
  • 🌊 背景エフェクト:7個
  • その他のエフェクト:11個

品質向上

  • ✅ すべてのコンポーネントがpropsでカスタマイズ可能
  • ✅ TypeScriptによる完全な型定義
  • ✅ メモリリークなし
  • ✅ パフォーマンス最適化済み

実装のベストプラクティス

1. Propsによる高度なカスタマイズ

すべてのコンポーネントで、色、速度、サイズなどをカスタマイズ可能に。

export function ShimmerText({
  children,
  className = '',
  shimmerColor = 'rgba(0, 245, 255, 0.6)',  // デフォルト値を提供
  duration = 2,
  spread = 100,
}: ShimmerTextProps) {
  // ...
}

2. TypeScriptでの型安全性

インターフェースを明確に定義。

interface GradientTextProps {
  children: React.ReactNode;
  className?: string;
  colors?: string[];
  animationDuration?: number;
  animate?: boolean;
}

3. パフォーマンス最適化

動的インポートで初期ロードを軽量化。

const DotPattern = dynamic(
  () => import('@/components/effects/DotPattern'),
  { ssr: false }
);

4. クリーンアップの徹底

メモリリークを防ぐため、すべてのタイマーをクリア。

useEffect(() => {
  const timerId = setTimeout(() => { /* ... */ });
  return () => clearTimeout(timerId);
}, [dependencies]);

今後の展開

これらのコンポーネントを活用して:

  • ✨ ブログ記事タイトルにTextScramble
  • ✨ プロジェクトカードにSpotlightCard
  • ✨ CTAボタンにShinyButton
  • ✨ セクションタイトルにGradientText

など、サイト全体をさらに魅力的にしていきます。

まとめ

ReactBits.devから学んだベストプラクティスを活かして、ADALabサイトに27個以上の高品質なアニメーションコンポーネントを追加しました。

重要な学び

  1. 豊富なバリエーション:ユーザーに多様な選択肢を提供
  2. 高度なカスタマイズ性:propsでの柔軟な設定
  3. 型安全性:TypeScriptでのバグ防止
  4. メモリ管理:クリーンアップの徹底
  5. コードレビュー:自動化ツールでの品質向上

これらの改善により、ADALabサイトはより現代的で魅力的なUIを持つサイトに進化しました。

参考リンク


この記事が、あなたのプロジェクトのUI改善の参考になれば幸いです!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?