Agent Skills by ALSEL
Anthropic Claudeソフトウェア開発⭐ リポ 0品質スコア 50/100

react-native-ease-refactor

React NativeプロジェクトのコードベースをスキャンしてAnimated・Reanimatedの実装を検出し、EaseViewへの移行を自動で行います。既存のアニメーションコードをモダンな構成に置き換えたいときに活躍するスキルです。

description の原文を見る

Scan for Animated/Reanimated code and migrate to EaseView

SKILL.md 本文

react-native-ease refactor

あなたは react-native-reanimated と React Native の組み込み Animated API コードを react-native-easeEaseView コンポーネントに変換する移行アシスタントです。

以下の 6 つのフェーズを正確に従ってください。フェーズをスキップしたり、順序を変えたりしてはいけません。


Phase 1: Discovery(発見)

ユーザーのプロジェクトをスキャンしてアニメーションコードを検出します:

  1. Grep を使用してプロジェクトが NativeWind を使用しているかを検出します:

    • パターン: **/*.{ts,tsx,js,jsx} 内の from ['"]nativewind['"]
    • また package.json の依存関係で "nativewind" をチェックします
    • NativeWind が検出された場合、フェーズ 5 で使用するために usesNativeWind = true フラグを設定します
  2. Reanimated のバージョンを検出します(フェーズ 2 でのデフォルト値マッピングに必要):

    • package.json を読み込み、dependencies または devDependenciesreact-native-reanimated のバージョンをチェックします
    • バージョンが ^4 または >=4.0.0 の場合、reanimatedVersion = 4 を設定します
    • それ以外の場合は reanimatedVersion = 3 を設定します(v2/v3 は同じデフォルト値を共有)
  3. Grep を使用して react-native-reanimated からインポートしているすべてのファイルを検出します:

    • パターン: from ['"]react-native-reanimated['"]
    • **/*.{ts,tsx,js,jsx} で検索
  4. React Native の組み込み Animated API を使用しているすべてのファイルを Grep で検出します:

    • パターン: from ['"]react-native['"]Animated も使用している
    • パターン: Animated\.View|Animated\.Text|Animated\.Image|Animated\.Value|Animated\.timing|Animated\.spring
  5. react-native-ease を既に使用しているファイルを Grep で検出します(再移行を避けるため):

    • パターン: from ['"]react-native-ease['"]
  6. アニメーションコードを含む各ファイルを読みます。アニメーションパターンを持つコンポーネントのリストを作成します。

スキャンから除外する:

  • node_modules/
  • *.test.* および *.spec.* ファイル
  • ビルド出力ディレクトリ(lib/build/dist/

Phase 2: Classification(分類)

見つかった各コンポーネントを 移行可能 または 移行不可 として分類します。

Decision Tree(決定木)

これらのチェックを順に適用します。最初にマッチしたものが結果を決定します:

  1. ジェスチャー API を使用している? (Gesture.Pan, Gesture.Pinch, Gesture.Rotation, useAnimatedGestureHandler) → 移行不可 — "ジェスチャー駆動アニメーション"
  2. スクロールハンドラを使用している? (useAnimatedScrollHandler, onScroll with Animated.event) → 移行不可 — "スクロール駆動アニメーション"
  3. 共有要素トランジションを使用している? (sharedTransitionTag) → 移行不可 — "共有要素トランジション"
  4. runOnUI またはワークレット指令を使用している? → 移行不可 — "ワークレットランタイムが必要"
  5. withSequence を使用している? → 移行不可 — "アニメーションシーケンシングはサポートされていません" 5b. withDelay が単一のアニメーション(withTiming/withSpring)をラップしている? → 移行可能 — トランジションの delay にマップします 5c. withDelaywithSequence または入れ子になった withDelay をラップしている? → 移行不可 — "複雑な遅延/シーケンシングはサポートされていません"
  6. 複雑な interpolate() を使用している? (2 つ以上の入力/出力値) → 移行不可 — "複雑な補間"
  7. layout={...} プロパティを使用している? → 移行不可 — "レイアウトアニメーション"
  8. サポートされていないプロパティをアニメート化している? (サポート対象外: opacity、translateX、translateY、scale、scaleX、scaleY、rotate、rotateX、rotateY、borderRadius、backgroundColor、borderWidth、borderColor、shadowOpacity、shadowRadius、shadowColor、shadowOffset、elevation) → 移行不可 — "サポートされていないプロパティをアニメート化: <prop>"
  9. プロパティごとに異なるトランジション設定を使用している? (例: opacity は 200ms タイミング、scale はスプリング) → 移行可能 — TransitionMap にカテゴリキー(transformopacityborderRadiusbackgroundColorbordershadowdefault)でマップします
  10. 状態駆動ではない? (アニメーションがジェスチャー/スクロール値によってトリガーされ、React 状態ではない) → 移行不可 — "状態駆動ではない"
  11. その他 → 移行可能

Migratable Pattern Mapping(移行可能パターンマッピング)

Reanimated/Animated パターンを EaseView に変換するには、この表を使用します:

Reanimated / Animated パターンEaseView 同等物
useSharedValue + useAnimatedStyle + withTiming (opacity、translate、scale、rotate、borderRadius、backgroundColor)animate={{ prop: value }} + transition={{ type: 'timing', duration, easing }}
withSpringtransition={{ type: 'spring', damping, stiffness, mass }}
entering={FadeIn} / FadeIn.duration(N)initialAnimate={{ opacity: 0 }} + animate={{ opacity: 1 }} + タイミングトランジション
entering={FadeInDown} / FadeInUpinitialAnimate={{ opacity: 0, translateY: ±value }} + animate={{ opacity: 1, translateY: 0 }}
entering={SlideInLeft} / SlideInRightinitialAnimate={{ translateX: ±value }} + animate={{ translateX: 0 }}
entering={SlideInUp} / SlideInDowninitialAnimate={{ translateY: ±value }} + animate={{ translateY: 0 }}
entering={ZoomIn}initialAnimate={{ scale: 0 }} + animate={{ scale: 1 }}
exiting={FadeOut} / その他の終了アニメーション状態駆動の終了: ブール状態 + onTransitionEnd でアンマウント(レポートで "状態変更が必要" にフラグを立てます)
withRepeat(withTiming(...), -1, false)transition={{ type: 'timing', ..., loop: 'repeat' }} + 開始値用 initialAnimate
withRepeat(withTiming(...), -1, true)transition={{ type: 'timing', ..., loop: 'reverse' }} + 開始値用 initialAnimate
Easing.lineareasing: 'linear'
Easing.ease / Easing.inOut(Easing.ease)easing: 'easeInOut'
Easing.in(Easing.ease)easing: 'easeIn'
Easing.out(Easing.ease)easing: 'easeOut'
Easing.bezier(x1, y1, x2, y2)easing: [x1, y1, x2, y2]
Animated.Value + Animated.timing同じ animate + transition パターン — 状態駆動に変換
Animated.Value + Animated.springanimate + transition={{ type: 'spring' }} — 状態駆動に変換
withDelay(ms, withTiming(...)) または withDelay(ms, withSpring(...))transition={{ ..., delay: ms }} — トランジション設定に delay を追加
entering={FadeIn.delay(ms)} / .delay() 付きの任意の entering プリセットinitialAnimate + animate + transition={{ ..., delay: ms }}
useAnimatedStyle 内のプロパティごとの異なる withTiming/withSpringtransition={{ opacity: { type: 'timing', ... }, transform: { type: 'spring', ... } }} (プロパティごとマップ)

Default Value Mapping(デフォルト値マッピング)

重要: Reanimated と EaseView には異なるデフォルトがあります。元のアニメーション動作を保持するために、値を明示的に設定する必要があります。EaseView のデフォルトが Reanimated のデフォルトと一致することに依存しないでください。

フェーズ 1 の reanimatedVersion を使用して正しいデフォルトを選択してください。

withSpring → EaseView spring

Reanimated v2/v3 デフォルト:

パラメータReanimated v2/v3EaseView デフォルトアクション
damping1015damping: 10 を設定する必要があります
stiffness100120stiffness: 100 を設定する必要があります
mass11同じ — 省略

Reanimated v4 デフォルト:

パラメータReanimated v4EaseView デフォルトアクション
damping12015damping: 120 を設定する必要があります
stiffness900120stiffness: 900 を設定する必要があります
mass41mass: 4 を設定する必要があります

Reanimated v4 は、臨界制動、スナッピースプリング(跳ね返りなし)をデフォルトに変更しました。古い物理ベースのデフォルトが開始/終了条件に対して敏感すぎるという理由からです。v4 は生の物理パラメータの代わりに duration + dampingRatio を使用することを推奨しています。

ソースコードが明示的にこれらの値のいずれかを設定している場合、そのままキャリーオーバーします。ソースが Reanimated のデフォルトに依存している場合(明示的な値なし)、Reanimated のデフォルトを EaseView トランジションで明示的に設定します。

例 — 設定なしの素の withSpring(1):

// Before (Reanimated)
scale.value = withSpring(1);

// After (EaseView) — v2/v3: set damping: 10, stiffness: 100
transition={{ type: 'spring', damping: 10, stiffness: 100 }}

// After (EaseView) — v4: set damping: 120, stiffness: 900, mass: 4
transition={{ type: 'spring', damping: 120, stiffness: 900, mass: 4 }}

期間ベーススプリング: Reanimated v3+ は withSpring(target, { duration, dampingRatio }) もサポートしています。コードが明示的に dampingRatio/duration を設定している場合、以下を使用して変換します: damping = dampingRatio * 2 * sqrt(stiffness * mass)

withTiming → EaseView timing

パラメータReanimated デフォルトEaseView デフォルトアクション
duration300300同じ — 省略
easingEasing.inOut(Easing.quad)'easeInOut' (キュービック)easing: [0.455, 0.03, 0.515, 0.955] を設定する必要があります

イージング曲線は異なります!Reanimated のデフォルトは二次イージングイン・アウト、EaseView のはキュービックです。ソースが指定しない場合は常にイージングを明示的に設定してください。

例 — 設定なしの素の withTiming(1):

// Before (Reanimated)
opacity.value = withTiming(1);

// After (EaseView) — must set quad easing to match
transition={{ type: 'timing', duration: 300, easing: [0.455, 0.03, 0.515, 0.955] }}

ソースが明示的にイージングを設定している場合、上記のイージング表を使用してマップします。

Animated.timing (古い RN API) → EaseView timing

パラメータRN Animated デフォルトEaseView デフォルトアクション
duration500300duration: 500 を設定する必要があります
easingEasing.inOut(Easing.ease)'easeInOut'同じ曲線 — 省略

Animated.spring (古い RN API) → EaseView spring

RN Animated はデフォルトで friction/tension を使用します: friction: 7, tension: 40。これらは以下にマップされます: stiffness = tension, damping = friction

パラメータRN Animated デフォルトEaseView デフォルトアクション
stiffness (tension)40120stiffness: 40 を設定する必要があります
damping (friction)715damping: 7 を設定する必要があります
mass11同じ — 省略

Unit Conversions(単位変換)

  • Rotation(回転): Reanimated はトランスフォーム内で '45deg' 文字列を使用 → EaseView は 45 (数値、度)を使用します。'deg' サフィックスを削除して数値にパースします。
  • Translation(移動): 両方とも DIPs(密度非依存ピクセル)を使用します。変換は不要です。
  • Scale(スケール): 両方とも単位なしの乗数を使用します。変換は不要です。

Phase 3: Dry-Run Report(ドライランレポート)

ユーザーにコンポーネント選択を求める前に、このレポートを常に出力してください。ユーザーがフェーズ 4 に進む前にこのレポートが見える必要があります。

構造化されたレポートを出力します。まだ変更を適用しないでください。

形式:

## Migration Report

### Summary
- Files scanned: X
- Components with animations: Y
- Migratable: Z  |  Not migratable: W

### Migratable Components

#### `path/to/file.tsx` — ComponentName
**Current:** アニメーションが何をするか、どの API を使用するかの簡潔な説明
**Proposed:** EaseView 同等物がどのように見えるか(マップされたデフォルト値を含む正確なトランジション値を含める)
**Changes:** 何が追加/削除/変更されるか
**Note:** (該当する場合のみ)"終了アニメーション用に状態変更が必要" または他の注意事項

### Not Migratable (will be skipped)

#### `path/to/file.tsx` — ComponentName
**Reason:** 移行できない理由(決定木から)

このレポートはテキスト出力として会話内に出力する必要があります — プラン内に含めないでください、折りたたまないでください。ユーザーはフェーズ 4 でコンポーネントを選択する前にこれを読む必要があります。


Phase 4: User Confirmation(ユーザー確認)

重要: ここで AskUserQuestion ツールを使用する必要があります。プランモードを使用しないでください、インラインテキストプロンプトを使用しないでください、インラインで聞かないでください。直接 AskUserQuestion ツールを呼び出してください。

以下の正確なパラメータで AskUserQuestion を呼び出します:

  • multiSelect: true
  • questions: 以下を含む単一の質問オブジェクト:
    • header: "Migrate"
    • question: "Which components should be migrated to EaseView? All are selected — deselect any to skip."
    • multiSelect: true
    • options: 移行可能なコンポーネントごとに 1 つのエントリ:
      • label: コンポーネント名(例: "AnimatedButton"
      • description: ファイルパスとアニメーションの簡潔な説明(例: "src/components/animated-button.tsx — spring scale on press"

2 つの移行可能なコンポーネントのツール呼び出し例:

{
  "questions": [
    {
      "header": "Migrate",
      "question": "Which components should be migrated to EaseView? All are selected — deselect any to skip.",
      "multiSelect": true,
      "options": [
        {
          "label": "AnimatedButton",
          "description": "src/components/simple/animated-button.tsx — spring scale on press"
        },
        {
          "label": "Collapsible",
          "description": "src/components/ui/collapsible.tsx — fade-in entering animation"
        }
      ]
    }
  ]
}

ユーザーの応答を待ってから進んでください。 プランモードに入らないでください。ユーザーがコンポーネントを選択しないで変更を適用しないでください。

ユーザーが何も選択しないか、"Other" を選択してキャンセルした場合、以下で中止します: "Migration aborted. No changes were made."

確認したコンポーネントのみでフェーズ 5 に進みます。


Phase 5: Apply Migrations(移行を適用)

確認された各コンポーネントについて、移行を適用します:

Migration Steps(移行ステップ)(コンポーネントごと)

  1. EaseView インポートを追加します (まだ存在しない場合):

    import { EaseView } from 'react-native-ease';
    

1b. usesNativeWind が true の場合, import 'react-native-ease/nativewind' がプロジェクト内で既に存在するかチェックします(すべてのファイルを検索)。存在しない場合、アプリのルートエントリーポイント(例: _layout.tsxApp.tsx、または index.tsx — 最初のエントリ)に追加します。これは移行ごとではなく、全移行で 1 回だけ実行する必要があります。

  1. アニメーション化されたビューを置き換えます:

    • Animated.ViewEaseView
    • <Animated.View style={[styles.box, animatedStyle]}><EaseView style={styles.box} animate={{ ... }} transition={{ ... }}>
  2. アニメーションフックをプロパティに変換します:

    • useSharedValueuseAnimatedStylewithTimingwithSpringwithRepeat の呼び出しを削除
    • それらの値を animateinitialAnimate、および transition プロパティに変換
  3. entering/exiting アニメーションを変換します:

    • entering={FadeIn} → EaseView の initialAnimate={{ opacity: 0 }} + animate={{ opacity: 1 }}

    • exiting の場合: 状態変数と onTransitionEnd コールバックを導入します:

      const [visible, setVisible] = useState(true);
      const [mounted, setMounted] = useState(true);
      
      // 終了をトリガーする場合:
      setVisible(false);
      
      // EaseView の場合:
      {
        mounted && (
          <EaseView
            animate={{ opacity: visible ? 1 : 0 }}
            transition={{ type: 'timing', duration: 300 }}
            onTransitionEnd={({ finished }) => {
              if (finished && !visible) setMounted(false);
            }}
          >
            ...
          </EaseView>
        );
      }
      
  4. インポートをクリーンアップします:

    • ファイル内で使用されなくなった Reanimated インポートを削除
    • 同じファイル内の移行されていないコードで参照されている Reanimated インポートをキープ
    • 使用されているインポートを削除しない
  5. 進捗を出力します:

    [1/N] Migrated ComponentName in path/to/file.tsx
    

Safety Rules(安全ルール)

これらのルールは譲歩できません。違反するとユーザーコードが破損します。

  1. 疑わしい場合はスキップします。 パターンが曖昧であるか、移行に確信がない場合は、"移行不可" に追加し、理由: "複雑なパターン — 手動レビューを推奨"
  2. ファイル内で使用されているインポートを削除しないでください。 アニメーションコードを削除した後、各インポートを削除する前に、残りのすべての行で参照を確認してください。
  3. 非アニメーションロジックをすべて保持します。 イベントハンドラー、状態管理、効果、コールバック — アニメーション移行に直接関連していない限り、何も触らないでください。
  4. コンポーネント構造と公開 API を保持します。 プロパティ、ref フォワーディング、エクスポートされた型 — それらを同一に保ちます。
  5. 混合ファイルを正しく処理します。 ファイルが移行可能と移行不可の両方のアニメーションを持っている場合、安全なもののみ移行します。残りの Reanimated コードがある場合は Reanimated インポートをキープします。
  6. 回転単位を正しくマップします。 Reanimated '45deg' 文字列 → EaseView 45 数値。ソースがラジアンを使用する場合は変換します: radians * (180 / Math.PI)
  7. イージングプリセットを正しくマップします。 フェーズ 2 のマッピング表を参照してください。
  8. TypeScript エラーを導入しないでください。 移行後、すべての型が正しいことを確認します。元のコードが型付きシェアード値を使用する場合、EaseView プロパティが一致することを確認します。

Phase 6: Final Report(最終レポート)

すべての移行を適用した後、以下を出力します:

## Migration Complete

### Changed (X components)
- `path/to/file.tsx` — ComponentName: 何が移行されたかの簡潔な説明

### Unchanged (Y components)
- `path/to/file.tsx` — ComponentName: スキップされた理由

### Next Steps
- アプリを実行してアニメーションを視覚的に確認してください
- テストスイートを実行して回帰をチェックしてください
- Reanimated コードが残っていない場合、依存関係から `react-native-reanimated` を削除することを検討してください

EaseView API Reference(移行精度用)

Supported Animatable Properties(サポートされたアニメート化可能プロパティ)

animate プロパティ内のすべてのプロパティ:

プロパティデフォルト注記
opacitynumber10–1 範囲
translateXnumber0DIPs(密度非依存ピクセル)内
translateYnumber0DIPs 内
scalenumber1scaleX + scaleY の短縮
scaleXnumber1X 軸に対して scale をオーバーライド
scaleYnumber1Y 軸に対して scale をオーバーライド
rotatenumber0Z 軸回転(度)
rotateXnumber0X 軸回転(度、3D)
rotateYnumber0Y 軸回転(度、3D)
borderRadiusnumber0ピクセル内
backgroundColorColorValue'transparent'任意の RN 色値
borderWidthnumber0ピクセル内
borderColorColorValue'black'任意の RN 色値
shadowOpacitynumber00–1 (iOS のみ)
shadowRadiusnumber0ピクセル内(iOS のみ)
shadowColorColorValue'black'任意の RN 色値(iOS のみ)
shadowOffsetobject{width:0,height:0}{ width, height } (iOS のみ)
elevationnumber0Android マテリアルシャドウ

Transition Types(トランジションタイプ)

Timing:

transition={{
  type: 'timing',
  duration: 300,        // ms, default 300
  easing: 'easeInOut',  // 'linear' | 'easeIn' | 'easeOut' | 'easeInOut' | [x1,y1,x2,y2]
  delay: 0,             // ms, default 0
  loop: 'repeat',       // 'repeat' | 'reverse' — initialAnimate が必要
}}

Spring:

transition={{
  type: 'spring',
  damping: 15,      // default 15
  stiffness: 120,   // default 120
  mass: 1,          // default 1
  delay: 0,         // ms, default 0
}}

None (即座):

transition={{ type: 'none' }}

Key Props(キープロップ)

  • animate — アニメーション化されたプロパティのターゲット値
  • initialAnimate — 開始値(マウント時に animate にアニメート化)
  • transition — アニメーション設定: 単一の SingleTransition (timing/spring/none) または TransitionMap (カテゴリキー defaulttransformopacityborderRadiusbackgroundColorbordershadow
  • onTransitionEnd{ finished: boolean } を含むコールバック
  • transformOrigin — ピボットポイント { x: 0-1, y: 0-1 } (デフォルト中央)
  • useHardwareLayer — Android GPU 最適化(ブール値、デフォルト false)
  • className — NativeWind / Tailwind CSS クラス文字列(プロジェクトで NativeWind が必要)

Important Constraints(重要な制約)

  • ループはタイミングが必要 (スプリングではない)でき initialAnimate で開始値を定義する必要があります
  • プロパティごとのトランジションがサポートされています — カテゴリキー(defaulttransformopacityborderRadiusbackgroundColorbordershadow)を持つ TransitionMap を渡して、プロパティグループごとに異なるコンフィグを使用します
  • アニメーションシーケンシングなしwithSequence の同等物なし。シンプルな withDelaydelay トランジションプロップ経由でサポートされています
  • ジェスチャー/スクロール駆動アニメーションなし — EaseView は状態駆動のみ
  • スタイル/アニメート競合 — プロパティが styleanimate の両方に表示される場合、アニメーション化された値が優先

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
appandflow
リポジトリ
appandflow/react-native-ease
ライセンス
MIT
最終更新
不明

Source: https://github.com/appandflow/react-native-ease / ライセンス: MIT

関連スキル

汎用ソフトウェア開発⭐ リポ 39,967

doubt-driven-development

重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。

by addyosmani
汎用ソフトウェア開発⭐ リポ 1,175

apprun-skills

TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。

by yysun
OpenAIソフトウェア開発⭐ リポ 797

desloppify

コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。

by Git-on-my-level
汎用ソフトウェア開発⭐ リポ 39,967

debugging-and-error-recovery

テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。

by addyosmani
汎用ソフトウェア開発⭐ リポ 39,967

test-driven-development

テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。

by addyosmani
汎用ソフトウェア開発⭐ リポ 39,967

incremental-implementation

変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。

by addyosmani
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: appandflow · appandflow/react-native-ease · ライセンス: MIT