Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ Timing animations transition from one value to another over a fixed duration wit
| ---------- | ------------ | ------------- | ------------------------------------------------------------------------ |
| `duration` | `number` | `300` | Duration in milliseconds |
| `easing` | `EasingType` | `'easeInOut'` | Easing curve (preset name or `[x1, y1, x2, y2]` cubic bezier) |
| `delay` | `number` | `0` | Delay in milliseconds before the animation starts |
| `loop` | `string` | — | `'repeat'` restarts from the beginning, `'reverse'` alternates direction |

Available easing curves:
Expand Down Expand Up @@ -146,6 +147,7 @@ Spring animations use a physics-based model for natural-feeling motion. Great fo
| `damping` | `number` | `15` | Friction — higher values reduce oscillation |
| `stiffness` | `number` | `120` | Spring constant — higher values mean faster animation |
| `mass` | `number` | `1` | Mass of the object — higher values mean slower, more momentum |
| `delay` | `number` | `0` | Delay in milliseconds before the animation starts |

Spring presets for common feels:

Expand Down Expand Up @@ -276,6 +278,26 @@ Use `initialAnimate` to set starting values. On mount, the view starts at `initi

Without `initialAnimate`, the view renders at the `animate` values immediately with no animation on mount.

### Delay

Use `delay` to postpone the start of an animation. This is useful for staggering enter animations across multiple elements.

```tsx
// Staggered fade-in list
{items.map((item, i) => (
<EaseView
key={item.id}
initialAnimate={{ opacity: 0, translateY: 20 }}
animate={{ opacity: 1, translateY: 0 }}
transition={{ type: 'timing', duration: 300, delay: i * 100 }}
>
<Text>{item.label}</Text>
</EaseView>
))}
```

`delay` works with both timing and spring transitions.

### Interruption

Animations are interruptible by default. If you change `animate` values while an animation is running, it smoothly redirects to the new target from wherever it currently is — no jumping or restarting.
Expand Down Expand Up @@ -386,6 +408,7 @@ Properties not specified in `animate` default to their identity values.
type: 'timing';
duration?: number; // default: 300 (ms)
easing?: EasingType; // default: 'easeInOut' — preset name or [x1, y1, x2, y2]
delay?: number; // default: 0 (ms)
loop?: 'repeat' | 'reverse'; // default: none
}
```
Expand All @@ -398,6 +421,7 @@ Properties not specified in `animate` default to their identity values.
damping?: number; // default: 15
stiffness?: number; // default: 120
mass?: number; // default: 1
delay?: number; // default: 0 (ms)
}
```

Expand Down
10 changes: 8 additions & 2 deletions skills/react-native-ease-refactor/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ Apply these checks in order. The first match determines the result:
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` or `withDelay`?** → NOT migratable — "Animation sequencing not supported"
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) → NOT migratable — "Animates unsupported property: `<prop>`"
Expand Down Expand Up @@ -83,6 +85,8 @@ Use this table to convert Reanimated/Animated patterns to EaseView:
| `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 }}` |

### Default Value Mapping

Expand Down Expand Up @@ -360,6 +364,7 @@ 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' — requires initialAnimate
}}
```
Expand All @@ -372,6 +377,7 @@ transition={{
damping: 15, // default 15
stiffness: 120, // default 120
mass: 1, // default 1
delay: 0, // ms, default 0
}}
```

Expand All @@ -394,6 +400,6 @@ transition={{ type: 'none' }}

- **Loop requires timing** (not spring) and `initialAnimate` must define the start value
- **No per-property transitions** — one transition config applies to all animated properties
- **No animation sequencing** — no equivalent to `withSequence`/`withDelay`
- **No animation sequencing** — no equivalent to `withSequence`. Simple `withDelay` IS supported via the `delay` transition prop
- **No gesture/scroll-driven animations** — EaseView is state-driven only
- **Style/animate conflict** — if a property appears in both `style` and `animate`, the animated value wins
Loading