@mihirsarya/manim-scroll-next 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +265 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# @mihirsarya/manim-scroll-next
|
|
2
|
+
|
|
3
|
+
Next.js plugin for build-time Manim scroll animation rendering. Automatically scans your source files, extracts `<ManimScroll>` components, and renders animations with smart caching.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @mihirsarya/manim-scroll-next
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or use the unified package (recommended):
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @mihirsarya/manim-scroll
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
- Next.js 13+
|
|
20
|
+
- Python 3.8+ with [Manim](https://www.manim.community/) installed
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
### 1. Configure Next.js
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
// next.config.js
|
|
28
|
+
const { withManimScroll } = require("@mihirsarya/manim-scroll-next");
|
|
29
|
+
// Or: const { withManimScroll } = require("@mihirsarya/manim-scroll/next");
|
|
30
|
+
|
|
31
|
+
module.exports = withManimScroll({
|
|
32
|
+
manimScroll: {
|
|
33
|
+
pythonPath: "python3",
|
|
34
|
+
quality: "h",
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 2. Use ManimScroll Components
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
// app/page.tsx
|
|
43
|
+
import { ManimScroll } from "@mihirsarya/manim-scroll-react";
|
|
44
|
+
// Or: import { ManimScroll } from "@mihirsarya/manim-scroll";
|
|
45
|
+
|
|
46
|
+
export default function Home() {
|
|
47
|
+
return (
|
|
48
|
+
<ManimScroll
|
|
49
|
+
scene="TextScene"
|
|
50
|
+
fontSize={72}
|
|
51
|
+
color="#ffffff"
|
|
52
|
+
>
|
|
53
|
+
Welcome to my site
|
|
54
|
+
</ManimScroll>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 3. Build
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
next build
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The plugin:
|
|
66
|
+
1. Scans your source files for `<ManimScroll>` components
|
|
67
|
+
2. Extracts props and children text
|
|
68
|
+
3. Computes a hash for each unique animation
|
|
69
|
+
4. Renders only new/changed animations (cached by hash)
|
|
70
|
+
5. Outputs assets to `public/manim-assets/`
|
|
71
|
+
|
|
72
|
+
## Configuration
|
|
73
|
+
|
|
74
|
+
### Combined Config (Recommended)
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
module.exports = withManimScroll({
|
|
78
|
+
// Next.js config
|
|
79
|
+
reactStrictMode: true,
|
|
80
|
+
|
|
81
|
+
// Manim Scroll config
|
|
82
|
+
manimScroll: {
|
|
83
|
+
pythonPath: "python3",
|
|
84
|
+
quality: "h",
|
|
85
|
+
fps: 30,
|
|
86
|
+
resolution: "1920x1080",
|
|
87
|
+
verbose: true,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Separate Configs
|
|
93
|
+
|
|
94
|
+
```js
|
|
95
|
+
const nextConfig = {
|
|
96
|
+
reactStrictMode: true,
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
module.exports = withManimScroll(nextConfig, {
|
|
100
|
+
pythonPath: "python3",
|
|
101
|
+
quality: "h",
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Options
|
|
106
|
+
|
|
107
|
+
| Option | Type | Default | Description |
|
|
108
|
+
|--------|------|---------|-------------|
|
|
109
|
+
| `pythonPath` | `string` | `"python3"` | Path to Python executable |
|
|
110
|
+
| `cliPath` | `string` | Built-in | Path to render CLI script |
|
|
111
|
+
| `templatesDir` | `string` | Built-in | Path to scene templates |
|
|
112
|
+
| `quality` | `string` | `"h"` | Manim quality preset (`l`, `m`, `h`, `k`) |
|
|
113
|
+
| `fps` | `number` | `30` | Frames per second |
|
|
114
|
+
| `resolution` | `string` | `"1920x1080"` | Output resolution (`WIDTHxHEIGHT`) |
|
|
115
|
+
| `format` | `string` | `"both"` | Output format (`frames`, `video`, `both`) |
|
|
116
|
+
| `concurrency` | `number` | CPU count - 1 | Max parallel renders |
|
|
117
|
+
| `include` | `string[]` | `["**/*.tsx", "**/*.jsx"]` | Glob patterns to scan |
|
|
118
|
+
| `exclude` | `string[]` | `["node_modules/**", ".next/**"]` | Glob patterns to exclude |
|
|
119
|
+
| `cleanOrphans` | `boolean` | `true` | Remove unused cached assets |
|
|
120
|
+
| `verbose` | `boolean` | `false` | Enable verbose logging |
|
|
121
|
+
|
|
122
|
+
## Exports
|
|
123
|
+
|
|
124
|
+
### Main Export
|
|
125
|
+
|
|
126
|
+
- **`withManimScroll(config, manimConfig?)`** - Next.js config wrapper
|
|
127
|
+
|
|
128
|
+
### Types
|
|
129
|
+
|
|
130
|
+
- `ManimScrollConfig` - Plugin configuration type
|
|
131
|
+
- `NextConfigWithManimScroll` - Extended Next.js config type
|
|
132
|
+
|
|
133
|
+
### Utilities (Advanced)
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
import {
|
|
137
|
+
extractAnimations,
|
|
138
|
+
renderAnimations,
|
|
139
|
+
computePropsHash,
|
|
140
|
+
isCached,
|
|
141
|
+
getCacheEntry,
|
|
142
|
+
getAnimationsToRender,
|
|
143
|
+
writeCacheManifest,
|
|
144
|
+
readCacheManifest,
|
|
145
|
+
cleanOrphanedCache,
|
|
146
|
+
processManimScroll,
|
|
147
|
+
} from "@mihirsarya/manim-scroll-next";
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## How It Works
|
|
151
|
+
|
|
152
|
+
### 1. Extraction
|
|
153
|
+
|
|
154
|
+
The plugin uses Babel to parse your source files and extract `<ManimScroll>` component usages:
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
<ManimScroll scene="TextScene" fontSize={72} color="#fff">
|
|
158
|
+
Hello World
|
|
159
|
+
</ManimScroll>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Becomes:
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
{
|
|
166
|
+
id: "app/page.tsx:ManimScroll:1",
|
|
167
|
+
scene: "TextScene",
|
|
168
|
+
props: { text: "Hello World", fontSize: 72, color: "#fff" }
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### 2. Caching
|
|
173
|
+
|
|
174
|
+
Each animation is hashed based on `scene + props`. The cache manifest at `public/manim-assets/cache-manifest.json` maps hashes to rendered asset directories:
|
|
175
|
+
|
|
176
|
+
```json
|
|
177
|
+
{
|
|
178
|
+
"version": 1,
|
|
179
|
+
"animations": {
|
|
180
|
+
"abc123...": "/manim-assets/abc123.../manifest.json"
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### 3. Rendering
|
|
186
|
+
|
|
187
|
+
New animations are rendered using the bundled Python CLI:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
python render/cli.py \
|
|
191
|
+
--scene-file render/templates/text_scene.py \
|
|
192
|
+
--scene-name TextScene \
|
|
193
|
+
--props '{"text": "Hello World", "fontSize": 72}' \
|
|
194
|
+
--output-dir public/manim-assets/abc123...
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### 4. Asset Structure
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
public/manim-assets/
|
|
201
|
+
├── cache-manifest.json
|
|
202
|
+
├── abc123.../
|
|
203
|
+
│ ├── manifest.json
|
|
204
|
+
│ ├── media/
|
|
205
|
+
│ │ ├── videos/...
|
|
206
|
+
│ │ └── images/...
|
|
207
|
+
└── def456.../
|
|
208
|
+
└── ...
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Development Mode
|
|
212
|
+
|
|
213
|
+
In dev mode (`next dev`), the plugin:
|
|
214
|
+
- Creates an empty cache manifest immediately to prevent 404s
|
|
215
|
+
- Processes animations asynchronously in the background
|
|
216
|
+
- Retries manifest resolution if animations are still rendering
|
|
217
|
+
|
|
218
|
+
## Custom Build Scripts
|
|
219
|
+
|
|
220
|
+
For advanced workflows, use the exported utilities:
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
import { extractAnimations, renderAnimations } from "@mihirsarya/manim-scroll-next";
|
|
224
|
+
|
|
225
|
+
async function customBuild() {
|
|
226
|
+
const animations = await extractAnimations({
|
|
227
|
+
rootDir: process.cwd(),
|
|
228
|
+
include: ["src/**/*.tsx"],
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
const results = await renderAnimations(animations, "./public", {
|
|
232
|
+
pythonPath: "python3",
|
|
233
|
+
quality: "h",
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
console.log(`Rendered ${results.filter(r => r.success).length} animations`);
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Troubleshooting
|
|
241
|
+
|
|
242
|
+
### Manim not found
|
|
243
|
+
|
|
244
|
+
Ensure Manim is installed and accessible:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
python3 -c "import manim; print(manim.__version__)"
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Animations not updating
|
|
251
|
+
|
|
252
|
+
The cache is based on props hash. To force re-render:
|
|
253
|
+
|
|
254
|
+
1. Delete `public/manim-assets/`
|
|
255
|
+
2. Or change a prop value
|
|
256
|
+
|
|
257
|
+
### Slow builds
|
|
258
|
+
|
|
259
|
+
- Reduce `quality` (use `"l"` or `"m"` for development)
|
|
260
|
+
- Increase `concurrency` if you have more CPU cores
|
|
261
|
+
- Use `format: "frames"` to skip video encoding
|
|
262
|
+
|
|
263
|
+
## License
|
|
264
|
+
|
|
265
|
+
MIT
|