Skip to main content

react-native-ease-refactor

Scan for Animated/Reanimated code and migrate to EaseView

Ir para a instalação

Informações da origem

Repositório
AppAndFlow/react-native-ease
Última atividade na origem
3 de agosto de 2026 às 18:22
Idioma detectado do SKILL.md
inglês
Estrelas
973
Forks
13

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
react-native-ease-refactor
description
Scan for Animated/Reanimated code and migrate to EaseView
user-invocable
true
# react-native-ease refactor You are a migration assistant that converts `react-native-reanimated` and React Native's built-in `Animated` API code to `react-native-ease` `EaseView` components. Follow these 6 phases exactly. Do not skip phases or reorder them. --- ## Phase 1: Discovery Scan the user's project for animation code: 1. Use Grep to detect if the project uses NativeWind: - Pattern: `from ['"]nativewind['"]` in `**/*.{ts,tsx,js,jsx}` - Also check `package.json` for `"nativewind"` in dependencies - If NativeWind is detected, set a flag `usesNativeWind = true` for use in Phase 5 2. Detect the Reanimated version (needed for default value mapping in Phase 2): - Read `package.json` and check the `react-native-reanimated` version in `dependencies` or `devDependencies` - If the version is `^4` or `>=4.0.0`, set `reanimatedVersion = 4` - Otherwise set `reanimatedVersion = 3` (covers v2/v3 which share the same defaults) 3. Use Grep to find all files importing from `react-native-reanimated`: - Pattern: `from ['"]react-native-reanimated['"]` - Search in `**/*.{ts,tsx,js,jsx}` 4. Use Grep to find all files using React Native's built-in `Animated` API: - Pattern: `from ['"]react-native['"]` that also use `Animated` - Pattern: `Animated\.View|Animated\.Text|Animated\.Image|Animated\.Value|Animated\.timing|Animated\.spring` 3. Use Grep to find files already using `react-native-ease` (to avoid re-migrating): - Pattern: `from ['"]react-native-ease['"]` 4. Read each file that contains animation code. Build a list of components with their animation patterns. **Exclude** from scanning: - `node_modules/` - `*.test.*` and `*.spec.*` files - Build output directories (`lib/`, `build/`, `dist/`) --- ## Phase 2: Classification For each component found, classify as **migratable** or **not migratable**. ### Decision Tree Apply these checks in order. The first match determines the result: 1. **Uses gesture APIs?** (`Gesture.Pan`, `Gesture.Pinch`, `Gesture.Rotation`, `useAnimatedGestureHandler`) → NOT migratable — "Gesture-driven animation" 2. **Uses scroll handler?** (`useAnimatedScrollHandler`, `onScroll` with `Animated.event`) → NOT migratable — "Scroll-driven animation" 3. **Uses shared element transitions?** (`sharedTransitionTag`) → NOT migratable — "Shared element transition" 4. **Uses `runOnUI` or worklet directives?** → NOT migratable — "Requires worklet runtime" 5. **Uses `withSequence`?** → NOT migratable — "Animation sequencing not supported" 5b. **Uses `withDelay` wrapping a single animation (`withTiming`/`withSpring`)?** → MIGRATABLE — map to `delay` on the transition 5c. **Uses `withDelay` wrapping `withSequence` or nested `withDelay`?** → NOT migratable — "Complex delay/sequencing not supported" 6. **Uses complex `interpolate()`?** (more than 2 input/output values) → NOT migratable — "Complex interpolation" 7. **Uses `layout={...}` prop?** → NOT migratable — "Layout animation" 8. **Animates unsupported properties?** (anything besides: opacity, translateX, translateY, scale, scaleX, scaleY, rotate, rotateX, rotateY, borderRadius, backgroundColor, borderWidth, borderColor, shadowOpacity, shadowRadius, shadowColor, shadowOffset, elevation) → NOT migratable — "Animates unsupported property: `<prop>`" 9. **Uses different transition configs per property?** (e.g., opacity uses 200ms timing, scale uses spring) → MIGRATABLE — map to `TransitionMap` with category keys (`transform`, `opacity`, `borderRadius`, `backgroundColor`, `border`, `shadow`, `default`) 10. **Not driven by state?** (animation triggered by gesture/scroll value, not React state) → NOT migratable — "Not state-driven" 11. **Otherwise** → MIGRATABLE ### Migratable Pattern Mapping Use this table to convert Reanimated/Animated patterns to EaseView: | Reanimated / Animated Pattern | EaseView Equivalent | | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | | `useSharedValue` + `useAnimatedStyle` + `withTiming` for opacity, translate, scale, rotate, borderRadius, backgroundColor | `animate={{ prop: value }}` + `transition={{ type: 'timing', duration, easing }}` | | `withSpring` | `transition={{ type: 'spring', damping, stiffness, mass, velocity }}` | | `entering={FadeIn}` / `FadeIn.duration(N)` | `initialAnimate={{ opacity: 0 }}` + `animate={{ opacity: 1 }}` + timing transition | | `entering={FadeInDown}` / `FadeInUp` | `initialAnimate={{ opacity: 0, translateY: ±value }}` + `animate={{ opacity: 1, translateY: 0 }}` | | `entering={SlideInLeft}` / `SlideInRight` | `initialAnimate={{ translateX: ±value }}` + `animate={{ translateX: 0 }}` | | `entering={SlideInUp}` / `SlideInDown` | `initialAnimate={{ translateY: ±value }}` + `animate={{ translateY: 0 }}` | | `entering={ZoomIn}` | `initialAnimate={{ scale: 0 }}` + `animate={{ scale: 1 }}` | | `exiting={FadeOut}` / other exit animations | State-driven exit: boolean state + `onTransitionEnd` to unmount (flag as "requires state changes" in report) | | `withRepeat(withTiming(...), -1, false)` | `transition={{ type: 'timing', ..., loop: 'repeat' }}` + `initialAnimate` for start value | | `withRepeat(withTiming(...), -1, true)` | `transition={{ type: 'timing', ..., loop: 'reverse' }}` + `initialAnimate` for start value | | `Easing.linear` | `easing: '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` | Same `animate` + `transition` pattern — convert to state-driven | | `Animated.Value` + `Animated.spring` | `animate` + `transition={{ type: 'spring' }}` — convert to state-driven | | `withDelay(ms, withTiming(...))` or `withDelay(ms, withSpring(...))` | `transition={{ ..., delay: ms }}` — add `delay` to the transition config | | `entering={FadeIn.delay(ms)}` / any entering preset with `.delay()` | `initialAnimate` + `animate` + `transition={{ ..., delay: ms }}` | | Different `withTiming`/`withSpring` per property in `useAnimatedStyle` | `transition={{ opacity: { type: 'timing', ... }, transform: { type: 'spring', ... } }}` (per-property map) | ### Default Value Mapping **CRITICAL: Reanimated and EaseView have different defaults. You MUST explicitly set values to preserve the original animation behavior. Do not rely on EaseView defaults matching Reanimated defaults.** **Use `reanimatedVersion` from Phase 1 to select the correct defaults.** #### `withSpring` → EaseView spring **Reanimated v2/v3 defaults:** | Parameter | Reanimated v2/v3 | EaseView default | Action | |---|---|---|---| | `damping` | `10` | `15` | **Must set `damping: 10`** | | `stiffness` | `100` | `120` | **Must set `stiffness: 100`** | | `mass` | `1` | `1` | Same — omit | | `velocity` | `0` | `0` | Same — carry over only when set | **Reanimated v4 defaults:** | Parameter | Reanimated v4 | EaseView default | Action | |---|---|---|---| | `damping` | `120` | `15` | **Must set `damping: 120`** | | `stiffness` | `900` | `120` | **Must set `stiffness: 900`** | | `mass` | `4` | `1` | **Must set `mass: 4`** | | `velocity` | `0` | `0` | Same — carry over only when set | Reanimated v4 changed to a critically damped, snappy spring (no bounce) as the default. The rationale was that the old physics-based defaults were too sensitive to start/end conditions. v4 recommends using `duration` + `dampingRatio` instead of raw physics params. If the source code explicitly sets any of these values, carry them over as-is. If the source relies on Reanimated defaults (no explicit value), set the Reanimated default explicitly on the EaseView transition. Example — bare `withSpring(1)` with no config: ```typescript // 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 }} ``` **Duration-based spring:** Reanimated v3+ also supports `withSpring(target, { duration, dampingRatio })`. If the code explicitly sets `dampingRatio`/`duration`, convert using: `damping = dampingRatio * 2 * sqrt(stiffness * mass)`. #### `withTiming` → EaseView timing | Parameter | Reanimated default | EaseView default | Action | |---|---|---|---| | `duration` | `300` | `300` | Same — omit | | `easing` | `Easing.inOut(Easing.quad)` | `'easeInOut'` (cubic) | **Must set `easing: [0.455, 0.03, 0.515, 0.955]`** | The easing curves are different! Reanimated's default is quadratic ease-in-out, EaseView's is cubic. Always set the easing explicitly when the source doesn't specify one. Example — bare `withTiming(1)` with no config: ```typescript // 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] }} ``` If the source explicitly sets an easing, map it using the easing table above. #### `Animated.timing` (old RN API) → EaseView timing | Parameter | RN Animated default | EaseView default | Action | |---|---|---|---| | `duration` | `500` | `300` | **Must set `duration: 500`** | | `easing` | `Easing.inOut(Easing.ease)` | `'easeInOut'` | Same curve — omit | #### `Animated.spring` (old RN API) → EaseView spring RN Animated uses `friction`/`tension` by default: `friction: 7, tension: 40`. These map to: `stiffness = tension`, `damping = friction`. | Parameter | RN Animated default | EaseView default | Action | |---|---|---|---|
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub