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
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ All properties are set in the `animate` prop as flat values (no transform array)

`scale` is a shorthand that sets both `scaleX` and `scaleY`. When `scaleX` or `scaleY` is also specified, it overrides the `scale` value for that axis.

You can animate any combination of properties simultaneously. All properties share the same transition config.
You can animate any combination of properties simultaneously. Use a single transition config for all properties, or a [per-property map](#per-property-transitions) for different configs per category.

### Looping Animations

Expand Down Expand Up @@ -415,10 +415,11 @@ A `View` that animates property changes using native platform APIs.
| ------------------ | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `animate` | `AnimateProps` | Target values for animated properties |
| `initialAnimate` | `AnimateProps` | Starting values for enter animations (animates to `animate` on mount) |
| `transition` | `Transition` | Animation configuration (timing, spring, or none) |
| `transition` | `Transition` | Animation configuration — a single config (timing, spring, or none) or a [per-property map](#per-property-transitions) |
| `onTransitionEnd` | `(event) => void` | Called when all animations complete with `{ finished: boolean }` |
| `transformOrigin` | `{ x?: number; y?: number }` | Pivot point for scale/rotation as 0–1 fractions. Default: `{ x: 0.5, y: 0.5 }` (center) |
| `useHardwareLayer` | `boolean` | Android only — rasterize to GPU texture during animations. See [Hardware Layers](#hardware-layers-android). Default: `false` |
| `className` | `string` | NativeWind / Tailwind CSS class string. Requires NativeWind in your project. |
| `style` | `ViewStyle` | Non-animated styles (layout, colors, borders, etc.) |
| `children` | `ReactNode` | Child elements |
| ...rest | `ViewProps` | All other standard View props |
Expand Down Expand Up @@ -475,6 +476,18 @@ Properties not specified in `animate` default to their identity values.

Applies values instantly with no animation. `onTransitionEnd` fires immediately with `{ finished: true }`.

### `TransitionMap`

A per-property map that applies different transition configs to different property categories. See [Per-Property Transitions](#per-property-transitions).

| Key | Properties |
| ----------------- | ---------------------------------------------------------------- |
| `default` | Fallback for categories not explicitly listed |
| `transform` | translateX, translateY, scaleX, scaleY, rotate, rotateX, rotateY |
| `opacity` | opacity |
| `borderRadius` | borderRadius |
| `backgroundColor` | backgroundColor |

## Hardware Layers (Android)

Setting `useHardwareLayer` rasterizes the view into a GPU texture for the duration of the animation. This means animated property changes (opacity, scale, rotation) are composited on the RenderThread without redrawing the view hierarchy — useful for complex views with many children.
Expand Down
8 changes: 5 additions & 3 deletions skills/react-native-ease-refactor/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Apply these checks in order. The first match determines the result:
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>`"
9. **Uses different transition configs per property?** (e.g., opacity uses 200ms timing, scale uses spring) → NOT migratable — "Per-property transition configs"
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`, `default`)
10. **Not driven by state?** (animation triggered by gesture/scroll value, not React state) → NOT migratable — "Not state-driven"
11. **Otherwise** → MIGRATABLE

Expand Down Expand Up @@ -87,6 +87,7 @@ Use this table to convert Reanimated/Animated patterns to EaseView:
| `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

Expand Down Expand Up @@ -391,15 +392,16 @@ transition={{ type: 'none' }}

- `animate` — target values for animated properties
- `initialAnimate` — starting values (animates to `animate` on mount)
- `transition` — animation config (timing or spring)
- `transition` — animation config: a single `SingleTransition` (timing/spring/none) OR a `TransitionMap` with category keys (`default`, `transform`, `opacity`, `borderRadius`, `backgroundColor`)
- `onTransitionEnd` — callback with `{ finished: boolean }`
- `transformOrigin` — pivot point as `{ x: 0-1, y: 0-1 }`, default center
- `useHardwareLayer` — Android GPU optimization (boolean, default false)
- `className` — NativeWind / Tailwind CSS class string (requires NativeWind in the project)

### Important Constraints

- **Loop requires timing** (not spring) and `initialAnimate` must define the start value
- **No per-property transitions** — one transition config applies to all animated properties
- **Per-property transitions supported** — pass a `TransitionMap` with category keys (`default`, `transform`, `opacity`, `borderRadius`, `backgroundColor`) to use different configs per property group
- **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