要素アニメーション

個々のDOM要素にアニメーションを適用

トランジションの例

様々なトランジション効果の使用方法:

import { transition } from '@ssgoi/react';
import { fade, scale, blur, slide, fly, rotate, bounce } from '@ssgoi/react/transitions';

// Fadeトランジション
<div ref={transition({
  key: "fade-element",
  ...fade({ spring: { stiffness: 300, damping: 30 } })
})}>
  Fade効果
</div>

// Scaleトランジション
<div ref={transition({
  key: "scale-element",
  ...scale({ spring: { stiffness: 300, damping: 30 } })
})}>
  Scale効果
</div>

// Blurトランジション
<div ref={transition({
  key: "blur-element",
  ...blur({ amount: 10, spring: { stiffness: 300, damping: 30 } })
})}>
  Blur効果
</div>

// Slideトランジション(方向指定)
<div ref={transition({
  key: "slide-element",
  ...slide({ direction: 'left', spring: { stiffness: 300, damping: 30 } })
})}>
  Slide効果
</div>

// Flyトランジション(カスタム位置)
<div ref={transition({
  key: "fly-element",
  ...fly({ x: 200, y: -50, spring: { stiffness: 300, damping: 30 } })
})}>
  Fly効果
</div>

// Rotateトランジション
<div ref={transition({
  key: "rotate-element",
  ...rotate({ spring: { stiffness: 300, damping: 30 } })
})}>
  Rotate効果
</div>

// Bounceトランジション
<div ref={transition({
  key: "bounce-element",
  ...bounce({ spring: { stiffness: 300, damping: 30 } })
})}>
  Bounce効果
</div>

基本構造

TransitionConfigインターフェース

interface TransitionConfig {
  spring?: {
    stiffness: number; // スプリングの硅さ (デフォルト: 300)
    damping: number; // 減衰係数 (デフォルト: 30)
  };
  tick?: (progress: number) => void; // in: 0→1, out: 1→0
  prepare?: (element: HTMLElement) => void; // アニメーション開始前の初期設定
  onStart?: () => void;
  onEnd?: () => void;
}

トランジションの定義

interface Transition {
  in?: (element: HTMLElement) => TransitionConfig;
  out?: (element: HTMLElement) => TransitionConfig;
}

動作の仕組み

  1. マウント時: 要素がDOMに追加されたときin関数を実行
  2. アンマウント時: 要素が削除される前にout関数を実行
  3. アニメーション: スプリング物理エンジンがprogressを生成
    • in: 0 → 1
    • out: 1 → 0
  4. tickコールバック: 毎フレーム呼び出されてスタイルを更新

トランジションプリセット

import { fade, scale /** etc */ } from "@ssgoi/react/transitions";

フレームワーク別の使用方法

import { transition } from "@ssgoi/react";

<div
  ref={transition({
    key: "unique-key",
    in: (element) => ({
      tick: (progress) => {
        element.style.opacity = progress;
        element.style.transform = `translateY(${20 * (1 - progress)}px)`;
      },
    }),
    out: (element) => ({
      tick: (progress) => {
        element.style.opacity = 1 - progress;
      },
    }),
  })}
>
  コンテンツ
</div>

Progressの動作

key

  • keyはページ内で一意である必要があります(DOMが作成された後削除されたり、削除された後作成されたりしてもアニメーション状態を追跡できるようにするため)
  • keyを設定しない場合、デフォルトで呼び出し位置に基づいた自動キーが生成されます

inアニメーション

  • progress: 0 → 1
  • 要素が表示されるときに実行
  • 不透明度が0から1へ、小さいサイズから元のサイズへ

outアニメーション

  • progress: 1 → 0
  • 要素が消えるときに実行
  • 不透明度が1から0へ、元のサイズから小さいサイズへ
// 例: inとoutの違い
{
  in: (element) => ({
    tick: (progress) => {
      // progress: 0 → 1
      element.style.opacity = progress;  // 0 → 1
    }
  }),
  out: (element) => ({
    tick: (progress) => {
      // progress: 1 → 0
      element.style.opacity = progress;  // 1 → 0
    }
  })
}

prepareコールバック

アニメーション開始前にDOM要素を準備する段階:

{
  in: {
    prepare: (element) => {
      // tick実行前に初期状態を設定
      element.style.willChange = 'opacity, transform';
    },
    tick: (progress) => ({
      opacity: progress,
      transform: `translateY(${20 * (1 - progress)}px)`
    })
  }
}