Skip to main content

react-native-ease-refactor

Scan for Animated/Reanimated code and migrate to EaseView

الانتقال إلى التثبيت

معلومات المصدر

المستودع
AppAndFlow/react-native-ease
آخر نشاط في المصدر
٣ أغسطس ٢٠٢٦ في ١٨:٢٢
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٩٧٣
التفرعات
١٣

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
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 | |---|---|---|---|
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub