mcpField
P
popmotion

popmotion

github.com/dylantarreデザイン・UI132493 回インストール43 週間前に更新
リポジトリ

popmotion について

Popmotionの合成可能なアニメーション関数で、ディズニーの12のアニメーション原則を実装するスキルです。インターフェースなどの動きを作る開発者向けです。

主な機能

  1. 0112のアニメーション原則の例
  2. 02トゥイーン、スプリング、キーフレーム
  3. 03減衰とイージング関数
  4. 04合成可能でフレームワーク非依存の関数

活用シーン

  1. 01スクワッシュとストレッチの動き
  2. 02複数段階のアニメーション作成
  3. 03慣性やスプリング運動の追加

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/dylantarre/animation-principles --skill popmotion

インストール後、Claude Code で/popmotionを入力して読み込まれたか確認します。

詳細

Popmotion のアニメーション原則

Popmotion の合成可能なアニメーション関数を使って、ディズニーのアニメーション12原則をすべて実装します。

1. 伸縮

import { animate } from "popmotion";

animate({
  from: { scaleX: 1, scaleY: 1 },
  to: { scaleX: 1.2, scaleY: 0.8 },
  duration: 150,
  onUpdate: ({ scaleX, scaleY }) => {
    element.style.transform = `scaleX(${scaleX}) scaleY(${scaleY})`;
  }
});

2. 予備動作

// Wind up then action
animate({
  from: 0,
  to: 10,
  duration: 200,
  onUpdate: v => element.style.transform = `translateY(${v}px) scaleY(0.9)`,
  onComplete: () => {
    animate({
      from: 10,
      to: -200,
      duration: 400,
      ease: easeOut,
      onUpdate: v => element.style.transform = `translateY(${v}px)`
    });
  }
});

3. 演出

animate({
  from: 1,
  to: 0.6,
  onUpdate: v => bg.style.opacity = v
});
animate({
  from: 1,
  to: 1.1,
  onUpdate: v => hero.style.transform = `scale(${v})`
});

4. ストレート・アヘッドとポーズ・トゥ・ポーズ

import { keyframes } from "popmotion";

keyframes({
  values: [
    { x: 0, y: 0 },
    { x: 100, y: -50 },
    { x: 200, y: 0 },
    { x: 300, y: -30 }
  ],
  duration: 1000,
  onUpdate: ({ x, y }) => {
    element.style.transform = `translate(${x}px, ${y}px)`;
  }
});

5. フォロースルーとオーバーラッピング・アクション

animate({ from: 0, to: 200, duration: 500,
  onUpdate: v => body.style.transform = `translateX(${v}px)` });

animate({ from: 0, to: 200, duration: 500, elapsed: -50, // delay
  onUpdate: v => hair.style.transform = `translateX(${v}px)` });

animate({ from: 0, to: 200, duration: 600, elapsed: -100,
  onUpdate: v => cape.style.transform = `translateX(${v}px)` });

6. スローインとスローアウト

import { animate, easeInOut, easeIn, easeOut } from "popmotion";

animate({
  from: 0,
  to: 300,
  duration: 600,
  ease: easeInOut,
  onUpdate: v => element.style.transform = `translateX(${v}px)`
});

7. アーク

keyframes({
  values: [
    { x: 0, y: 0 },
    { x: 100, y: -100 },
    { x: 200, y: 0 }
  ],
  duration: 1000,
  ease: easeInOut,
  onUpdate: ({ x, y }) => {
    element.style.transform = `translate(${x}px, ${y}px)`;
  }
});

8. 副次動作

// Primary action triggers secondary
animate({
  from: 1, to: 1.1, duration: 200,
  onUpdate: v => button.style.transform = `scale(${v})`,
  onComplete: () => {
    animate({
      from: 0, to: 15, duration: 150,
      onUpdate: v => icon.style.transform = `rotate(${v}deg)`
    });
  }
});

9. タイミング

import { spring } from "popmotion";

// Fast
animate({ from: 0, to: 100, duration: 150 });

// Spring physics
spring({
  from: 0,
  to: 100,
  stiffness: 300,
  damping: 20,
  onUpdate: v => element.style.transform = `translateX(${v}px)`
});

// Slow
animate({ from: 0, to: 100, duration: 800, ease: easeOut });

10. 誇張

spring({
  from: { scale: 1, rotate: 0 },
  to: { scale: 1.5, rotate: 720 },
  stiffness: 200,
  damping: 10, // low = overshoot
  onUpdate: ({ scale, rotate }) => {
    element.style.transform = `scale(${scale}) rotate(${rotate}deg)`;
  }
});

11. 立体感のある描画

animate({
  from: { rotateX: 0, rotateY: 0 },
  to: { rotateX: 45, rotateY: 30 },
  duration: 500,
  onUpdate: ({ rotateX, rotateY }) => {
    box.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
  }
});

12. 魅力

animate({
  from: 1,
  to: 1.02,
  duration: 300,
  ease: easeOut,
  onUpdate: v => {
    card.style.transform = `scale(${v})`;
    card.style.boxShadow = `0 ${20*v}px 40px rgba(0,0,0,${0.2*v})`;
  }
});

Popmotion の主な機能

  • animate() - トゥイーンアニメーション
  • spring() - 物理ベースのスプリング
  • keyframes() - 複数段階のアニメーション
  • decay() - 運動量/慣性
  • easeIn、easeOut、easeInOut - イージング関数
  • 合成可能な関数 - ミックスやパイプが可能
  • フレームワークに依存しません
  • 内部で Framer Motion を支えています

コメント