@mihirsarya/manim-scroll-react 0.1.1 → 0.2.0

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.
@@ -7,20 +7,33 @@ import type { ScrollRangeValue } from "@mihirsarya/manim-scroll-runtime";
7
7
  export interface ManimAnimationProps {
8
8
  /** Scene name (default: "TextScene") */
9
9
  scene?: string;
10
- /** Font size for text animations */
10
+ /** Font size for text animations. If not specified in native mode, inherits from parent. */
11
11
  fontSize?: number;
12
12
  /** Color for the animation (hex string) */
13
13
  color?: string;
14
14
  /** Font family for text animations */
15
15
  font?: string;
16
+ /**
17
+ * Enable inline mode for text that flows with surrounding content.
18
+ * When true, renders with transparent background and tight bounds.
19
+ */
20
+ inline?: boolean;
21
+ /** Padding around the text in inline mode (Manim units, default: 0.2) */
22
+ padding?: number;
16
23
  /** Additional custom props for the scene */
17
24
  [key: string]: unknown;
18
25
  }
19
26
  export type ManimScrollProps = ManimAnimationProps & {
20
27
  /** Explicit manifest URL (overrides auto-resolution) */
21
28
  manifestUrl?: string;
22
- /** Playback mode */
23
- mode?: "auto" | "frames" | "video";
29
+ /**
30
+ * Playback mode:
31
+ * - "auto": Uses pre-rendered video or frames
32
+ * - "frames": Forces frame-by-frame playback
33
+ * - "video": Forces video playback
34
+ * - "native": Uses native SVG animation (no pre-rendered assets)
35
+ */
36
+ mode?: "auto" | "frames" | "video" | "native";
24
37
  /** Scroll range configuration (preset, tuple, or legacy object) */
25
38
  scrollRange?: ScrollRangeValue;
26
39
  /** Called when animation is loaded and ready */
@@ -32,6 +45,10 @@ export type ManimScrollProps = ManimAnimationProps & {
32
45
  width?: number;
33
46
  height?: number;
34
47
  };
48
+ /** URL to a font file for native mode (woff, woff2, ttf, otf) */
49
+ fontUrl?: string;
50
+ /** Stroke width for native mode drawing phase */
51
+ strokeWidth?: number;
35
52
  className?: string;
36
53
  style?: React.CSSProperties;
37
54
  children?: React.ReactNode;
@@ -41,6 +58,7 @@ export type ManimScrollProps = ManimAnimationProps & {
41
58
  *
42
59
  * Automatically resolves pre-rendered animation assets based on props,
43
60
  * or use an explicit `manifestUrl` for manual control.
61
+ * Use `mode="native"` for native SVG animation without pre-rendered assets.
44
62
  *
45
63
  * @example
46
64
  * ```tsx
@@ -53,6 +71,11 @@ export type ManimScrollProps = ManimAnimationProps & {
53
71
  * <ManimScroll manifestUrl="/assets/scene/manifest.json">
54
72
  * Scroll-driven text
55
73
  * </ManimScroll>
74
+ *
75
+ * // Native mode (no pre-rendered assets)
76
+ * <ManimScroll mode="native" fontSize={48} color="#ffffff">
77
+ * Animate this text
78
+ * </ManimScroll>
56
79
  * ```
57
80
  */
58
- export declare function ManimScroll({ className, style, children, canvas, manifestUrl, mode, scrollRange, onReady, onProgress, scene, fontSize, color, font, ...customProps }: ManimScrollProps): JSX.Element;
81
+ export declare function ManimScroll({ className, style, children, canvas, manifestUrl, mode, scrollRange, onReady, onProgress, fontUrl, strokeWidth, scene, fontSize, color, font, inline, padding, ...customProps }: ManimScrollProps): JSX.Element;
@@ -1,12 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useRef, useMemo, useEffect } from "react";
3
- import { useManimScroll } from "./hooks";
3
+ import { useManimScroll, useNativeAnimation } from "./hooks";
4
4
  import { extractChildrenText } from "./hash";
5
5
  /**
6
6
  * Scroll-driven Manim animation component.
7
7
  *
8
8
  * Automatically resolves pre-rendered animation assets based on props,
9
9
  * or use an explicit `manifestUrl` for manual control.
10
+ * Use `mode="native"` for native SVG animation without pre-rendered assets.
10
11
  *
11
12
  * @example
12
13
  * ```tsx
@@ -19,15 +20,22 @@ import { extractChildrenText } from "./hash";
19
20
  * <ManimScroll manifestUrl="/assets/scene/manifest.json">
20
21
  * Scroll-driven text
21
22
  * </ManimScroll>
23
+ *
24
+ * // Native mode (no pre-rendered assets)
25
+ * <ManimScroll mode="native" fontSize={48} color="#ffffff">
26
+ * Animate this text
27
+ * </ManimScroll>
22
28
  * ```
23
29
  */
24
- export function ManimScroll({ className, style, children, canvas, manifestUrl, mode, scrollRange, onReady, onProgress,
30
+ export function ManimScroll({ className, style, children, canvas, manifestUrl, mode, scrollRange, onReady, onProgress, fontUrl, strokeWidth,
25
31
  // Animation props
26
- scene = "TextScene", fontSize, color, font, ...customProps }) {
32
+ scene = "TextScene", fontSize, color, font, inline, padding, ...customProps }) {
27
33
  const containerRef = useRef(null);
28
34
  // Extract text from children
29
35
  const childrenText = useMemo(() => extractChildrenText(children), [children]);
30
- // Build animation props for hashing
36
+ // Determine if we're using native mode
37
+ const isNativeMode = mode === "native";
38
+ // Build animation props for hashing (used for pre-rendered mode)
31
39
  const animationProps = useMemo(() => {
32
40
  const props = { ...customProps };
33
41
  if (childrenText)
@@ -38,18 +46,36 @@ scene = "TextScene", fontSize, color, font, ...customProps }) {
38
46
  props.color = color;
39
47
  if (font !== undefined)
40
48
  props.font = font;
49
+ if (inline !== undefined)
50
+ props.inline = inline;
51
+ if (padding !== undefined)
52
+ props.padding = padding;
41
53
  return props;
42
- }, [childrenText, fontSize, color, font, customProps]);
43
- // Use the hook for all animation logic
44
- const { isReady, error, progress } = useManimScroll({
54
+ }, [childrenText, fontSize, color, font, inline, padding, customProps]);
55
+ // Use appropriate hook based on mode
56
+ // Only one hook will be active at a time based on the enabled flag
57
+ const preRenderedResult = useManimScroll({
45
58
  ref: containerRef,
46
59
  manifestUrl,
47
60
  scene,
48
61
  animationProps,
49
- mode,
62
+ mode: isNativeMode ? undefined : mode,
50
63
  scrollRange,
51
64
  canvasDimensions: canvas,
65
+ enabled: !isNativeMode,
66
+ });
67
+ const nativeResult = useNativeAnimation({
68
+ ref: containerRef,
69
+ text: childrenText || "",
70
+ fontSize, // undefined means inherit from parent
71
+ color: color !== null && color !== void 0 ? color : "#ffffff",
72
+ fontUrl,
73
+ strokeWidth,
74
+ scrollRange,
75
+ enabled: isNativeMode,
52
76
  });
77
+ // Select the appropriate result based on mode
78
+ const { isReady, error, progress } = isNativeMode ? nativeResult : preRenderedResult;
53
79
  // Forward callbacks
54
80
  useEffect(() => {
55
81
  if (isReady) {
@@ -59,7 +85,32 @@ scene = "TextScene", fontSize, color, font, ...customProps }) {
59
85
  useEffect(() => {
60
86
  onProgress === null || onProgress === void 0 ? void 0 : onProgress(progress);
61
87
  }, [progress, onProgress]);
62
- return (_jsxs("div", { className: className, style: { position: "relative", ...style }, ref: containerRef, children: [_jsx("span", { style: { position: "absolute", opacity: 0 }, children: children }), error && process.env.NODE_ENV === "development" && (_jsx("div", { style: {
88
+ // Compute container styles based on inline mode and native mode
89
+ const containerStyle = useMemo(() => {
90
+ const baseStyle = {
91
+ position: "relative",
92
+ ...style,
93
+ };
94
+ if (inline || isNativeMode) {
95
+ return {
96
+ ...baseStyle,
97
+ // Use inline display for natural text flow
98
+ display: "inline",
99
+ // Align with surrounding text baseline for seamless integration
100
+ verticalAlign: "baseline",
101
+ // Ensure background is transparent for inline mode
102
+ background: "transparent",
103
+ // Inherit font properties for seamless text flow
104
+ fontFamily: "inherit",
105
+ lineHeight: "inherit",
106
+ };
107
+ }
108
+ return baseStyle;
109
+ }, [inline, isNativeMode, style]);
110
+ // Use span for inline mode or native mode to avoid invalid HTML (div inside p)
111
+ // Native mode typically flows inline with text, so use span for proper semantics
112
+ const Container = inline || isNativeMode ? "span" : "div";
113
+ return (_jsxs(Container, { className: className, style: containerStyle, ref: containerRef, children: [!isNativeMode && (_jsx("span", { style: { position: "absolute", opacity: 0 }, children: children })), error && process.env.NODE_ENV === "development" && (_jsx("span", { style: {
63
114
  position: "absolute",
64
115
  inset: 0,
65
116
  display: "flex",
package/dist/hooks.d.ts CHANGED
@@ -5,12 +5,14 @@ interface CacheManifest {
5
5
  }
6
6
  /**
7
7
  * Load the cache manifest from the public directory.
8
+ * In dev mode, refreshes the manifest periodically to pick up newly rendered animations.
8
9
  */
9
- declare function loadCacheManifest(): Promise<CacheManifest | null>;
10
+ declare function loadCacheManifest(forceRefresh?: boolean): Promise<CacheManifest | null>;
10
11
  /**
11
12
  * Resolve the manifest URL for the given animation props.
13
+ * In dev mode, retries with manifest refresh if animation not found.
12
14
  */
13
- declare function resolveManifestUrl(scene: string, props: Record<string, unknown>): Promise<string | null>;
15
+ declare function resolveManifestUrl(scene: string, props: Record<string, unknown>, retryCount?: number): Promise<string | null>;
14
16
  /**
15
17
  * Options for the useManimScroll hook.
16
18
  */
@@ -32,6 +34,8 @@ export interface UseManimScrollOptions {
32
34
  width?: number;
33
35
  height?: number;
34
36
  };
37
+ /** Whether the hook is enabled (default: true) */
38
+ enabled?: boolean;
35
39
  }
36
40
  /**
37
41
  * Result returned by the useManimScroll hook.
@@ -80,3 +84,68 @@ export interface UseManimScrollResult {
80
84
  */
81
85
  export declare function useManimScroll(options: UseManimScrollOptions): UseManimScrollResult;
82
86
  export { loadCacheManifest, resolveManifestUrl };
87
+ /**
88
+ * Options for the useNativeAnimation hook.
89
+ */
90
+ export interface UseNativeAnimationOptions {
91
+ /** Ref to the container element */
92
+ ref: React.RefObject<HTMLElement | null>;
93
+ /** The text to animate */
94
+ text: string;
95
+ /** Font size in pixels. If not specified, inherits from parent element. */
96
+ fontSize?: number;
97
+ /** Text color (hex or CSS color) */
98
+ color?: string;
99
+ /** URL to a font file (woff, woff2, ttf, otf) for opentype.js */
100
+ fontUrl?: string;
101
+ /** Stroke width for the drawing phase */
102
+ strokeWidth?: number;
103
+ /** Scroll range configuration */
104
+ scrollRange?: ScrollRangeValue;
105
+ /** Whether the hook is enabled (default: true) */
106
+ enabled?: boolean;
107
+ }
108
+ /**
109
+ * Result returned by the useNativeAnimation hook.
110
+ */
111
+ export interface UseNativeAnimationResult {
112
+ /** Current scroll progress (0 to 1) */
113
+ progress: number;
114
+ /** Whether the animation is loaded and ready */
115
+ isReady: boolean;
116
+ /** Error if initialization failed */
117
+ error: Error | null;
118
+ /** Pause scroll-driven updates */
119
+ pause: () => void;
120
+ /** Resume scroll-driven updates */
121
+ resume: () => void;
122
+ /** Whether scroll updates are paused */
123
+ isPaused: boolean;
124
+ }
125
+ /**
126
+ * Hook for native text animation that renders directly in the browser
127
+ * using SVG, replicating Manim's Write/DrawBorderThenFill effect.
128
+ *
129
+ * This hook bypasses the manifest resolution and pre-rendered assets,
130
+ * instead animating text natively using opentype.js and SVG.
131
+ *
132
+ * @example
133
+ * ```tsx
134
+ * function NativeTextAnimation() {
135
+ * const containerRef = useRef<HTMLDivElement>(null);
136
+ * const { progress, isReady } = useNativeAnimation({
137
+ * ref: containerRef,
138
+ * text: "Hello World",
139
+ * fontSize: 48,
140
+ * color: "#ffffff",
141
+ * });
142
+ *
143
+ * return (
144
+ * <div ref={containerRef} style={{ height: "100vh" }}>
145
+ * {!isReady && <div>Loading...</div>}
146
+ * </div>
147
+ * );
148
+ * }
149
+ * ```
150
+ */
151
+ export declare function useNativeAnimation(options: UseNativeAnimationOptions): UseNativeAnimationResult;
package/dist/hooks.js CHANGED
@@ -1,36 +1,68 @@
1
1
  import { useEffect, useRef, useState, useMemo, useCallback } from "react";
2
- import { registerScrollAnimation } from "@mihirsarya/manim-scroll-runtime";
2
+ import { registerScrollAnimation, registerNativeAnimation } from "@mihirsarya/manim-scroll-runtime";
3
3
  import { computePropsHash } from "./hash";
4
- // Global cache manifest (loaded once)
5
- let cacheManifestPromise = null;
4
+ // Global cache manifest state
5
+ let cachedManifest = null;
6
+ let manifestFetchPromise = null;
7
+ let lastFetchTime = 0;
8
+ // In dev mode, allow manifest to be refreshed every 2 seconds
9
+ const MANIFEST_CACHE_TTL = process.env.NODE_ENV === "development" ? 2000 : Infinity;
6
10
  /**
7
11
  * Load the cache manifest from the public directory.
12
+ * In dev mode, refreshes the manifest periodically to pick up newly rendered animations.
8
13
  */
9
- async function loadCacheManifest() {
10
- if (cacheManifestPromise) {
11
- return cacheManifestPromise;
14
+ async function loadCacheManifest(forceRefresh = false) {
15
+ const now = Date.now();
16
+ const isStale = now - lastFetchTime > MANIFEST_CACHE_TTL;
17
+ // Return cached manifest if fresh
18
+ if (cachedManifest && !isStale && !forceRefresh) {
19
+ return cachedManifest;
12
20
  }
13
- cacheManifestPromise = fetch("/manim-assets/cache-manifest.json")
21
+ // If already fetching, wait for that
22
+ if (manifestFetchPromise && !forceRefresh) {
23
+ return manifestFetchPromise;
24
+ }
25
+ lastFetchTime = now;
26
+ manifestFetchPromise = fetch("/manim-assets/cache-manifest.json", {
27
+ cache: forceRefresh ? "no-store" : "default",
28
+ })
14
29
  .then((response) => {
15
30
  if (!response.ok) {
16
31
  return null;
17
32
  }
18
33
  return response.json();
19
34
  })
20
- .catch(() => null);
21
- return cacheManifestPromise;
35
+ .then((manifest) => {
36
+ cachedManifest = manifest;
37
+ manifestFetchPromise = null;
38
+ return manifest;
39
+ })
40
+ .catch(() => {
41
+ manifestFetchPromise = null;
42
+ return null;
43
+ });
44
+ return manifestFetchPromise;
22
45
  }
23
46
  /**
24
47
  * Resolve the manifest URL for the given animation props.
48
+ * In dev mode, retries with manifest refresh if animation not found.
25
49
  */
26
- async function resolveManifestUrl(scene, props) {
27
- var _a;
28
- const manifest = await loadCacheManifest();
50
+ async function resolveManifestUrl(scene, props, retryCount = 0) {
51
+ const manifest = await loadCacheManifest(retryCount > 0);
29
52
  if (!manifest) {
30
53
  return null;
31
54
  }
32
55
  const hash = computePropsHash(scene, props);
33
- return (_a = manifest.animations[hash]) !== null && _a !== void 0 ? _a : null;
56
+ const url = manifest.animations[hash];
57
+ if (url) {
58
+ return url;
59
+ }
60
+ // In dev mode, retry a few times as animations might still be rendering
61
+ if (process.env.NODE_ENV === "development" && retryCount < 5) {
62
+ await new Promise((resolve) => setTimeout(resolve, 1000 * (retryCount + 1)));
63
+ return resolveManifestUrl(scene, props, retryCount + 1);
64
+ }
65
+ return null;
34
66
  }
35
67
  /**
36
68
  * Hook for advanced scroll-driven Manim animation control.
@@ -57,7 +89,7 @@ async function resolveManifestUrl(scene, props) {
57
89
  * ```
58
90
  */
59
91
  export function useManimScroll(options) {
60
- const { ref, manifestUrl: explicitManifestUrl, scene = "TextScene", animationProps = {}, mode, scrollRange, canvasDimensions, } = options;
92
+ const { ref, manifestUrl: explicitManifestUrl, scene = "TextScene", animationProps = {}, mode, scrollRange, canvasDimensions, enabled = true, } = options;
61
93
  const [progress, setProgress] = useState(0);
62
94
  const [isReady, setIsReady] = useState(false);
63
95
  const [error, setError] = useState(null);
@@ -76,6 +108,8 @@ export function useManimScroll(options) {
76
108
  [JSON.stringify(animationProps)]);
77
109
  // Resolve manifest URL if not explicitly provided
78
110
  useEffect(() => {
111
+ if (!enabled)
112
+ return;
79
113
  if (explicitManifestUrl) {
80
114
  setResolvedManifestUrl(explicitManifestUrl);
81
115
  setError(null);
@@ -91,7 +125,7 @@ export function useManimScroll(options) {
91
125
  `Make sure to run the build with @mihirsarya/manim-scroll-next.`));
92
126
  }
93
127
  });
94
- }, [explicitManifestUrl, scene, memoizedAnimationProps]);
128
+ }, [enabled, explicitManifestUrl, scene, memoizedAnimationProps]);
95
129
  // Handle progress updates (respects pause state)
96
130
  const handleProgress = useCallback((p) => {
97
131
  if (!pausedRef.current) {
@@ -105,6 +139,8 @@ export function useManimScroll(options) {
105
139
  // Register scroll animation
106
140
  useEffect(() => {
107
141
  var _a;
142
+ if (!enabled)
143
+ return;
108
144
  const container = ref.current;
109
145
  if (!container || !resolvedManifestUrl)
110
146
  return;
@@ -115,8 +151,18 @@ export function useManimScroll(options) {
115
151
  canvasEl.width = canvasDimensions.width;
116
152
  if (canvasDimensions === null || canvasDimensions === void 0 ? void 0 : canvasDimensions.height)
117
153
  canvasEl.height = canvasDimensions.height;
154
+ // Check if inline mode
155
+ const isInline = animationProps.inline === true;
118
156
  // Only append if we created the canvas
119
157
  if (!canvasRef.current) {
158
+ if (!isInline) {
159
+ // Block mode: fill container
160
+ canvasEl.style.width = "100%";
161
+ canvasEl.style.height = "100%";
162
+ canvasEl.style.objectFit = "contain";
163
+ canvasEl.style.display = "block";
164
+ }
165
+ // For inline mode, let the player set styles based on manifest data
120
166
  container.appendChild(canvasEl);
121
167
  }
122
168
  registerScrollAnimation({
@@ -145,6 +191,7 @@ export function useManimScroll(options) {
145
191
  setIsReady(false);
146
192
  };
147
193
  }, [
194
+ enabled,
148
195
  ref,
149
196
  resolvedManifestUrl,
150
197
  mode,
@@ -180,3 +227,107 @@ export function useManimScroll(options) {
180
227
  }
181
228
  // Re-export helper functions for use by the component
182
229
  export { loadCacheManifest, resolveManifestUrl };
230
+ /**
231
+ * Hook for native text animation that renders directly in the browser
232
+ * using SVG, replicating Manim's Write/DrawBorderThenFill effect.
233
+ *
234
+ * This hook bypasses the manifest resolution and pre-rendered assets,
235
+ * instead animating text natively using opentype.js and SVG.
236
+ *
237
+ * @example
238
+ * ```tsx
239
+ * function NativeTextAnimation() {
240
+ * const containerRef = useRef<HTMLDivElement>(null);
241
+ * const { progress, isReady } = useNativeAnimation({
242
+ * ref: containerRef,
243
+ * text: "Hello World",
244
+ * fontSize: 48,
245
+ * color: "#ffffff",
246
+ * });
247
+ *
248
+ * return (
249
+ * <div ref={containerRef} style={{ height: "100vh" }}>
250
+ * {!isReady && <div>Loading...</div>}
251
+ * </div>
252
+ * );
253
+ * }
254
+ * ```
255
+ */
256
+ export function useNativeAnimation(options) {
257
+ const { ref, text, fontSize, // undefined means inherit from parent
258
+ color = "#ffffff", fontUrl, strokeWidth = 2, // Manim's DrawBorderThenFill default
259
+ scrollRange, enabled = true, } = options;
260
+ const [progress, setProgress] = useState(0);
261
+ const [isReady, setIsReady] = useState(false);
262
+ const [error, setError] = useState(null);
263
+ const [isPaused, setIsPaused] = useState(false);
264
+ const cleanupRef = useRef(null);
265
+ const pausedRef = useRef(isPaused);
266
+ // Keep pausedRef in sync
267
+ useEffect(() => {
268
+ pausedRef.current = isPaused;
269
+ }, [isPaused]);
270
+ // Handle progress updates (respects pause state)
271
+ const handleProgress = useCallback((p) => {
272
+ if (!pausedRef.current) {
273
+ setProgress(p);
274
+ }
275
+ }, []);
276
+ // Handle ready callback
277
+ const handleReady = useCallback(() => {
278
+ setIsReady(true);
279
+ }, []);
280
+ // Register native animation
281
+ useEffect(() => {
282
+ if (!enabled)
283
+ return;
284
+ const container = ref.current;
285
+ if (!container || !text)
286
+ return;
287
+ let isMounted = true;
288
+ const nativeOptions = {
289
+ container,
290
+ text,
291
+ fontSize,
292
+ color,
293
+ fontUrl,
294
+ strokeWidth,
295
+ scrollRange,
296
+ onReady: handleReady,
297
+ onProgress: handleProgress,
298
+ };
299
+ registerNativeAnimation(nativeOptions)
300
+ .then((dispose) => {
301
+ if (!isMounted) {
302
+ dispose();
303
+ return;
304
+ }
305
+ cleanupRef.current = dispose;
306
+ })
307
+ .catch((err) => {
308
+ if (isMounted) {
309
+ setError(err instanceof Error ? err : new Error(String(err)));
310
+ }
311
+ });
312
+ return () => {
313
+ var _a;
314
+ isMounted = false;
315
+ (_a = cleanupRef.current) === null || _a === void 0 ? void 0 : _a.call(cleanupRef);
316
+ setIsReady(false);
317
+ };
318
+ }, [enabled, ref, text, fontSize, color, fontUrl, strokeWidth, scrollRange, handleProgress, handleReady]);
319
+ const pause = useCallback(() => {
320
+ setIsPaused(true);
321
+ }, []);
322
+ const resume = useCallback(() => {
323
+ setIsPaused(false);
324
+ }, []);
325
+ return {
326
+ progress,
327
+ isReady,
328
+ error,
329
+ pause,
330
+ resume,
331
+ isPaused,
332
+ };
333
+ }
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { ManimScroll } from "./ManimScroll";
2
2
  export type { ManimScrollProps, ManimAnimationProps } from "./ManimScroll";
3
- export { useManimScroll } from "./hooks";
4
- export type { UseManimScrollOptions, UseManimScrollResult } from "./hooks";
3
+ export { useManimScroll, useNativeAnimation } from "./hooks";
4
+ export type { UseManimScrollOptions, UseManimScrollResult, UseNativeAnimationOptions, UseNativeAnimationResult, } from "./hooks";
5
5
  export { computePropsHash, extractChildrenText } from "./hash";
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export { ManimScroll } from "./ManimScroll";
2
- export { useManimScroll } from "./hooks";
2
+ export { useManimScroll, useNativeAnimation } from "./hooks";
3
3
  export { computePropsHash, extractChildrenText } from "./hash";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mihirsarya/manim-scroll-react",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "React wrapper for scroll-driven Manim animations.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -12,7 +12,7 @@
12
12
  "react-dom": ">=18.0.0"
13
13
  },
14
14
  "dependencies": {
15
- "@mihirsarya/manim-scroll-runtime": "0.1.1"
15
+ "@mihirsarya/manim-scroll-runtime": "0.2.0"
16
16
  },
17
17
  "devDependencies": {
18
18
  "@types/react": "^18.2.61",