Skip to content

Commit f2a2a4b

Browse files
docs: add Docusaurus website (#28)
* docs: add Docusaurus website * chore: remove unused docs assets
1 parent 5194412 commit f2a2a4b

21 files changed

Lines changed: 17040 additions & 7887 deletions

docs/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
node_modules
2+
build
3+
.docusaurus
4+
.cache-loader
5+
.env
6+
.DS_Store

docs/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# React Native Ease docs
2+
3+
Docusaurus website for `react-native-ease`.
4+
5+
## Local development
6+
7+
```bash
8+
yarn
9+
yarn start
10+
```
11+
12+
## Build
13+
14+
```bash
15+
yarn build
16+
```

docs/docs/api-reference.mdx

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
---
2+
id: api-reference
3+
title: API reference
4+
---
5+
6+
## `<EaseView>`
7+
8+
A `View` that animates property changes using native platform APIs.
9+
10+
| Prop | Type | Description |
11+
| ------------------ | ---------------------------- | ----------- |
12+
| `animate` | `AnimateProps` | Target values for animated properties |
13+
| `initialAnimate` | `AnimateProps` | Starting values for enter animations |
14+
| `transition` | `Transition` | Single config or per-property map |
15+
| `onTransitionEnd` | `(event) => void` | Called when all animations complete with `{ finished: boolean }` |
16+
| `transformOrigin` | `{ x?: number; y?: number }` | Pivot point for scale/rotation as 0–1 fractions |
17+
| `useHardwareLayer` | `boolean` | Android only — rasterize to GPU texture during animations |
18+
| `className` | `string` | NativeWind / Uniwind / Tailwind CSS class string |
19+
| `style` | `ViewStyle` | Non-animated styles |
20+
| `children` | `ReactNode` | Child elements |
21+
| `...rest` | `ViewProps` | All other standard View props |
22+
23+
## `AnimateProps`
24+
25+
| Property | Type | Default | Description |
26+
| ----------------- | ------------ | --------------- | ----------- |
27+
| `opacity` | `number` | `1` | View opacity (0–1) |
28+
| `translateX` | `number` | `0` | Horizontal translation in pixels |
29+
| `translateY` | `number` | `0` | Vertical translation in pixels |
30+
| `scale` | `number` | `1` | Uniform scale factor |
31+
| `scaleX` | `number` | `1` | Horizontal scale factor |
32+
| `scaleY` | `number` | `1` | Vertical scale factor |
33+
| `rotate` | `number` | `0` | Z-axis rotation in degrees |
34+
| `rotateX` | `number` | `0` | X-axis rotation in degrees |
35+
| `rotateY` | `number` | `0` | Y-axis rotation in degrees |
36+
| `borderRadius` | `number` | `0` | Border radius in pixels |
37+
| `backgroundColor` | `ColorValue` | `'transparent'` | Background color |
38+
39+
## `TimingTransition`
40+
41+
```tsx
42+
{
43+
type: 'timing';
44+
duration?: number;
45+
easing?: EasingType;
46+
delay?: number;
47+
loop?: 'repeat' | 'reverse';
48+
}
49+
```
50+
51+
## `SpringTransition`
52+
53+
```tsx
54+
{
55+
type: 'spring';
56+
damping?: number;
57+
stiffness?: number;
58+
mass?: number;
59+
delay?: number;
60+
}
61+
```
62+
63+
## `NoneTransition`
64+
65+
```tsx
66+
{
67+
type: 'none';
68+
}
69+
```
70+
71+
Applies values instantly with no animation.
72+
73+
## `TransitionMap`
74+
75+
A per-property map that applies different transition configs to different property categories.
76+
77+
| Key | Properties |
78+
| ----------------- | ---------- |
79+
| `default` | Fallback for categories not explicitly listed |
80+
| `transform` | translateX, translateY, scaleX, scaleY, rotate, rotateX, rotateY |
81+
| `opacity` | opacity |
82+
| `borderRadius` | borderRadius |
83+
| `backgroundColor` | backgroundColor |
84+
85+
## Hardware layers (Android)
86+
87+
Setting `useHardwareLayer` rasterizes the view into a GPU texture for the duration of the animation.
88+
89+
```tsx
90+
<EaseView animate={{ opacity: isVisible ? 1 : 0 }} useHardwareLayer />
91+
```
92+
93+
**Trade-offs:**
94+
95+
- Faster rendering for opacity, scale, and rotation animations.
96+
- Uses additional GPU memory for the off-screen texture.
97+
- Overflowing children are clipped by the texture.

docs/docs/benchmarks.mdx

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
id: benchmarks
3+
title: Benchmarks
4+
---
5+
6+
The example app includes a benchmark that measures per-frame animation overhead across different approaches. All approaches run the same animation (translateX loop, linear, 2s) on a configurable number of views.
7+
8+
## Android
9+
10+
UI thread time per frame: anim + layout + draw (ms). Lower is better.
11+
12+
![Android benchmark](https://github.com/user-attachments/assets/f0e5cf26-76be-4dd3-ae04-e17c6d13b49c)
13+
14+
<details>
15+
<summary>Detailed numbers</summary>
16+
17+
| Views | Metric | Ease | Reanimated SV | Reanimated SV (FF) | Reanimated CSS | Reanimated CSS (FF) | RN Animated |
18+
|-------|--------|------|---------------|---------------------|----------------|----------------------|-------------|
19+
| 10 | Avg | 0.21 | 1.15 | 0.75 | 0.99 | 0.45 | 0.36 |
20+
| 10 | P95 | 0.33 | 1.70 | 1.53 | 1.44 | 0.80 | 0.62 |
21+
| 10 | P99 | 0.48 | 1.94 | 2.26 | 1.62 | 1.35 | 0.98 |
22+
| 100 | Avg | 0.36 | 2.71 | 1.81 | 2.19 | 1.01 | 0.71 |
23+
| 100 | P95 | 0.56 | 3.09 | 2.29 | 2.67 | 1.91 | 1.08 |
24+
| 100 | P99 | 0.71 | 3.20 | 2.63 | 2.97 | 2.25 | 1.36 |
25+
| 500 | Avg | 0.60 | 8.31 | 5.37 | 5.50 | 2.37 | 1.60 |
26+
| 500 | P95 | 0.75 | 9.26 | 6.36 | 6.34 | 2.86 | 1.88 |
27+
| 500 | P99 | 0.87 | 9.59 | 6.89 | 6.88 | 3.22 | 3.84 |
28+
29+
</details>
30+
31+
## iOS
32+
33+
Display link callback time per frame (ms). Lower is better.
34+
35+
![iOS benchmark](https://github.com/user-attachments/assets/c39a7a71-bf21-4276-b02f-b29983989832)
36+
37+
<details>
38+
<summary>Detailed numbers</summary>
39+
40+
| Views | Metric | Ease | Reanimated SV | Reanimated SV (FF) | Reanimated CSS | Reanimated CSS (FF) | RN Animated |
41+
|-------|--------|------|---------------|---------------------|----------------|----------------------|-------------|
42+
| 10 | Avg | 0.01 | 1.33 | 1.08 | 1.06 | 0.63 | 0.83 |
43+
| 10 | P95 | 0.02 | 1.67 | 1.59 | 1.34 | 1.01 | 1.18 |
44+
| 10 | P99 | 0.03 | 1.90 | 1.68 | 1.50 | 1.08 | 1.31 |
45+
| 100 | Avg | 0.01 | 3.72 | 3.33 | 2.71 | 2.48 | 3.32 |
46+
| 100 | P95 | 0.01 | 5.21 | 4.50 | 3.83 | 3.39 | 4.28 |
47+
| 100 | P99 | 0.02 | 5.68 | 4.75 | 4.91 | 3.79 | 4.55 |
48+
| 500 | Avg | 0.01 | 6.84 | 6.54 | 4.16 | 3.70 | 4.91 |
49+
| 500 | P95 | 0.01 | 7.69 | 7.32 | 4.59 | 4.22 | 5.66 |
50+
| 500 | P99 | 0.02 | 8.10 | 7.45 | 4.71 | 4.33 | 5.89 |
51+
52+
</details>
53+
54+
Ease stays near zero because animations run entirely on platform APIs. On iOS, Core Animation runs on a separate render server process off the main thread. On Android, ObjectAnimator runs on the UI thread but is significantly lighter than other approaches.

docs/docs/contributing.mdx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
id: contributing
3+
title: Contributing
4+
---
5+
6+
- [Development workflow](https://github.com/AppAndFlow/react-native-ease/blob/main/CONTRIBUTING.md#development-workflow)
7+
- [Sending a pull request](https://github.com/AppAndFlow/react-native-ease/blob/main/CONTRIBUTING.md#sending-a-pull-request)
8+
- [Code of conduct](https://github.com/AppAndFlow/react-native-ease/blob/main/CODE_OF_CONDUCT.md)
9+
10+
## Local docs development
11+
12+
```bash
13+
cd docs
14+
yarn
15+
yarn start
16+
```

docs/docs/getting-started.mdx

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
---
2+
id: getting-started
3+
title: Getting started
4+
slug: /
5+
---
6+
7+
![react-native-ease hero](https://github.com/user-attachments/assets/8006ed51-d373-4c97-9e80-9937eb9a569e)
8+
9+
Lightweight declarative animations powered by platform APIs. Uses Core Animation on iOS and Animator on Android — zero JS overhead.
10+
11+
## Installation
12+
13+
```bash
14+
npm install react-native-ease
15+
# or
16+
yarn add react-native-ease
17+
```
18+
19+
## Example
20+
21+
```tsx
22+
import { EaseView } from 'react-native-ease';
23+
24+
function FadeCard({ visible, children }) {
25+
return (
26+
<EaseView
27+
animate={{ opacity: visible ? 1 : 0 }}
28+
transition={{ type: 'timing', duration: 300 }}
29+
style={styles.card}
30+
>
31+
{children}
32+
</EaseView>
33+
);
34+
}
35+
```
36+
37+
`EaseView` works like a regular `View` — it accepts children, styles, and all standard view props. When values in `animate` change, it smoothly transitions to the new values using native platform animations.
38+
39+
## Why Ease
40+
41+
### Goals
42+
43+
- **Fast** — Animations run entirely on native platform APIs (CAAnimation, ObjectAnimator/SpringAnimation). No JS animation loop, no worklets, no shared values.
44+
- **Simple** — CSS-transition-like API. Set target values, get smooth animations. One component, a few props.
45+
- **Lightweight** — Minimal native code, no C++ runtime, no custom animation engine. Just a thin declarative wrapper around what the OS already provides.
46+
- **Interruptible** — Changing values mid-animation smoothly redirects to the new target. No jumps.
47+
48+
### Non-goals
49+
50+
- **Complex gesture-driven animations** — If you need pan/pinch-driven animations, animation worklets, or shared values across components, use [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated).
51+
- **Layout animations** — Animating width/height/layout changes is not supported.
52+
- **Shared element transitions** — Use Reanimated or React Navigation's shared element transitions.
53+
- **Old architecture** — Fabric (new architecture) only.
54+
55+
## When to use this vs Reanimated
56+
57+
| Use case | Ease | Reanimated |
58+
| -------------------------------------- | ---- | ---------- |
59+
| Fade/slide/scale on state change || |
60+
| Enter/exit animations || |
61+
| Gesture-driven animations (pan, pinch) | ||
62+
| Layout animations (width, height) | ||
63+
| Complex interpolations & chaining | ||
64+
65+
## Styling integrations
66+
67+
### NativeWind support
68+
69+
If you're using [NativeWind](https://www.nativewind.dev/) (v4+), add this import once in your app's entry point (for example `_layout.tsx` or `App.tsx`):
70+
71+
```tsx
72+
import 'react-native-ease/nativewind';
73+
```
74+
75+
This registers `EaseView` with NativeWind's `cssInterop` so `className` is properly converted to styles:
76+
77+
```tsx
78+
<EaseView
79+
className="flex-1 bg-white rounded-2xl p-4"
80+
animate={{ opacity: visible ? 1 : 0 }}
81+
transition={{ type: 'timing', duration: 300 }}
82+
>
83+
{children}
84+
</EaseView>
85+
```
86+
87+
### Uniwind support
88+
89+
If you're using [Uniwind](https://docs.uniwind.dev/), first follow the [Uniwind quickstart](https://docs.uniwind.dev/quickstart) to install and configure Uniwind in your app.
90+
91+
Once Uniwind is set up, import `EaseView` from the Uniwind entry point:
92+
93+
```tsx
94+
import { EaseView } from 'react-native-ease/uniwind';
95+
```
96+
97+
```tsx
98+
<EaseView
99+
className="flex-1 bg-white rounded-2xl p-4"
100+
animate={{ opacity: visible ? 1 : 0 }}
101+
transition={{ type: 'timing', duration: 300 }}
102+
>
103+
{children}
104+
</EaseView>
105+
```
106+
107+
## Migration skill
108+
109+
If you're already using `react-native-reanimated` or React Native's `Animated` API, this project includes an [Agent Skill](https://agentskills.io) that scans your codebase for animations that can be replaced with `react-native-ease` and migrates them automatically.
110+
111+
```bash
112+
npx skills add appandflow/react-native-ease
113+
```
114+
115+
Then invoke the skill in your agent (for example `/react-native-ease-refactor` in Claude Code).

docs/docs/how-it-works.mdx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
id: how-it-works
3+
title: How it works
4+
---
5+
6+
`EaseView` is a native Fabric component. The JS side flattens your `animate` and `transition` props into flat native props. When those props change, the native view:
7+
8+
1. **Diffs** previous vs new values to find what changed
9+
2. **Reads** the current in-flight value for smooth interruption
10+
3. **Creates** a platform-native animation from the current value to the new target
11+
4. **Sets** the final value immediately on the model layer
12+
13+
On iOS, this uses `CABasicAnimation` and `CASpringAnimation` on `CALayer` key paths. On Android, this uses `ObjectAnimator` and `SpringAnimation` on `View` properties. No JS thread involvement during the animation.
14+
15+
## Requirements
16+
17+
- React Native 0.76+ (new architecture / Fabric)
18+
- iOS 15.1+
19+
- Android minSdk 24+

0 commit comments

Comments
 (0)