@it-compiles/anima 0.1.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.
package/dist/react.js ADDED
@@ -0,0 +1,425 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { forwardRef, useRef, useState, useImperativeHandle, useEffect, useCallback } from "react";
3
+ import { m as makePlayer } from "./player-MRRNy8I9.js";
4
+ const DEFAULT_WIDTH = 1280;
5
+ const DEFAULT_HEIGHT = 720;
6
+ function formatTime(ms) {
7
+ const seconds = ms / 1e3;
8
+ return seconds.toFixed(2) + "s";
9
+ }
10
+ const AnimaPlayer = forwardRef(
11
+ function AnimaPlayer2({
12
+ animation,
13
+ width = DEFAULT_WIDTH,
14
+ height = DEFAULT_HEIGHT,
15
+ autoPlay = false,
16
+ loop = false,
17
+ controls = true,
18
+ debug = false,
19
+ showCoordinates = false,
20
+ onTimeUpdate,
21
+ onComplete,
22
+ onError,
23
+ className,
24
+ style
25
+ }, ref) {
26
+ const containerRef = useRef(null);
27
+ const canvasRef = useRef(null);
28
+ const playerRef = useRef(null);
29
+ const preservedTimeRef = useRef(0);
30
+ const [isPlaying, setIsPlaying] = useState(false);
31
+ const [currentTime, setCurrentTime] = useState(0);
32
+ const [duration, setDuration] = useState(0);
33
+ const [displaySize, setDisplaySize] = useState({ width, height });
34
+ const [debugMode, setDebugMode] = useState(debug);
35
+ const [mousePos, setMousePos] = useState(null);
36
+ const [error, setError] = useState(null);
37
+ const aspectRatio = width / height;
38
+ useImperativeHandle(ref, () => ({
39
+ play() {
40
+ playerRef.current?.play();
41
+ setIsPlaying(true);
42
+ },
43
+ pause() {
44
+ playerRef.current?.pause();
45
+ setIsPlaying(false);
46
+ },
47
+ stop() {
48
+ playerRef.current?.stop();
49
+ setIsPlaying(false);
50
+ setCurrentTime(0);
51
+ },
52
+ seek(timeMs) {
53
+ playerRef.current?.seek(timeMs);
54
+ setCurrentTime(timeMs);
55
+ },
56
+ get isPlaying() {
57
+ return playerRef.current?.isPlaying ?? false;
58
+ },
59
+ get currentTime() {
60
+ return playerRef.current?.currentTime ?? 0;
61
+ },
62
+ get duration() {
63
+ return playerRef.current?.duration ?? 0;
64
+ }
65
+ }));
66
+ useEffect(() => {
67
+ const canvas = canvasRef.current;
68
+ if (!canvas) return;
69
+ const dpr = window.devicePixelRatio || 1;
70
+ canvas.width = width * dpr;
71
+ canvas.height = height * dpr;
72
+ }, [width, height]);
73
+ useEffect(() => {
74
+ const container = containerRef.current;
75
+ if (!container) return;
76
+ const updateSize = () => {
77
+ const rect = container.getBoundingClientRect();
78
+ const padding = 0;
79
+ const availableWidth = rect.width - padding;
80
+ const availableHeight = rect.height - padding;
81
+ let w = availableWidth;
82
+ let h = w / aspectRatio;
83
+ if (h > availableHeight) {
84
+ h = availableHeight;
85
+ w = h * aspectRatio;
86
+ }
87
+ setDisplaySize({ width: Math.floor(w), height: Math.floor(h) });
88
+ };
89
+ const observer = new ResizeObserver(updateSize);
90
+ observer.observe(container);
91
+ updateSize();
92
+ return () => observer.disconnect();
93
+ }, [aspectRatio]);
94
+ useEffect(() => {
95
+ if (!canvasRef.current || !animation) {
96
+ if (playerRef.current) {
97
+ preservedTimeRef.current = playerRef.current.currentTime;
98
+ }
99
+ playerRef.current?.dispose();
100
+ playerRef.current = null;
101
+ setIsPlaying(false);
102
+ return;
103
+ }
104
+ const previousTime = playerRef.current?.currentTime ?? preservedTimeRef.current;
105
+ playerRef.current?.dispose();
106
+ try {
107
+ const player = makePlayer(canvasRef.current, {
108
+ scene: animation.scene,
109
+ timeline: animation.timeline
110
+ });
111
+ player.onTimeUpdate = (time) => {
112
+ setCurrentTime(time);
113
+ setIsPlaying(player.isPlaying);
114
+ onTimeUpdate?.(time);
115
+ if (time >= player.duration && !player.isPlaying) {
116
+ if (loop) {
117
+ player.seek(0);
118
+ player.play();
119
+ } else {
120
+ onComplete?.();
121
+ }
122
+ }
123
+ };
124
+ player.onError = (err) => {
125
+ setError(err.message);
126
+ setIsPlaying(false);
127
+ onError?.(err);
128
+ };
129
+ playerRef.current = player;
130
+ player.debug = debugMode;
131
+ setDuration(player.duration);
132
+ setError(null);
133
+ const preservedTime = Math.min(previousTime, player.duration);
134
+ player.seek(preservedTime);
135
+ setCurrentTime(preservedTime);
136
+ if (autoPlay) {
137
+ player.play();
138
+ setIsPlaying(true);
139
+ } else {
140
+ setIsPlaying(false);
141
+ }
142
+ return () => {
143
+ player.dispose();
144
+ };
145
+ } catch (e) {
146
+ const err = e instanceof Error ? e : new Error(String(e));
147
+ setError(err.message);
148
+ onError?.(err);
149
+ }
150
+ }, [animation, autoPlay, loop, onTimeUpdate, onComplete, onError, debugMode]);
151
+ useEffect(() => {
152
+ if (playerRef.current) {
153
+ playerRef.current.debug = debugMode;
154
+ }
155
+ }, [debugMode]);
156
+ const handlePlayPause = useCallback(() => {
157
+ const player = playerRef.current;
158
+ if (!player) return;
159
+ if (player.isPlaying) {
160
+ player.pause();
161
+ setIsPlaying(false);
162
+ } else {
163
+ player.play();
164
+ setIsPlaying(true);
165
+ }
166
+ }, []);
167
+ const handleSeek = useCallback((timeMs) => {
168
+ const player = playerRef.current;
169
+ if (!player) return;
170
+ player.seek(timeMs);
171
+ setCurrentTime(timeMs);
172
+ }, []);
173
+ const handleReset = useCallback(() => {
174
+ const player = playerRef.current;
175
+ if (!player) return;
176
+ player.stop();
177
+ setIsPlaying(false);
178
+ setCurrentTime(0);
179
+ }, []);
180
+ const handleDebugToggle = useCallback(() => {
181
+ setDebugMode((prev) => !prev);
182
+ }, []);
183
+ const handleMouseMove = useCallback(
184
+ (e) => {
185
+ if (!showCoordinates) return;
186
+ const canvas = canvasRef.current;
187
+ if (!canvas) return;
188
+ const rect = canvas.getBoundingClientRect();
189
+ const scaleX = width / rect.width;
190
+ const scaleY = height / rect.height;
191
+ const x = Math.round((e.clientX - rect.left) * scaleX);
192
+ const y = Math.round((e.clientY - rect.top) * scaleY);
193
+ setMousePos({ x, y });
194
+ },
195
+ [width, height, showCoordinates]
196
+ );
197
+ const handleMouseLeave = useCallback(() => {
198
+ setMousePos(null);
199
+ }, []);
200
+ const progress = duration > 0 ? currentTime / duration * 100 : 0;
201
+ return /* @__PURE__ */ jsxs(
202
+ "div",
203
+ {
204
+ className,
205
+ style: {
206
+ display: "flex",
207
+ flexDirection: "column",
208
+ backgroundColor: "#171717",
209
+ ...style
210
+ },
211
+ children: [
212
+ /* @__PURE__ */ jsx(
213
+ "div",
214
+ {
215
+ ref: containerRef,
216
+ style: {
217
+ flex: 1,
218
+ display: "flex",
219
+ alignItems: "center",
220
+ justifyContent: "center",
221
+ padding: "16px",
222
+ overflow: "hidden"
223
+ },
224
+ children: /* @__PURE__ */ jsxs("div", { style: { position: "relative", backgroundColor: "#fff", borderRadius: "4px", boxShadow: "0 4px 6px rgba(0,0,0,0.3)" }, children: [
225
+ /* @__PURE__ */ jsx(
226
+ "canvas",
227
+ {
228
+ ref: canvasRef,
229
+ style: {
230
+ display: "block",
231
+ width: displaySize.width,
232
+ height: displaySize.height
233
+ },
234
+ onMouseMove: handleMouseMove,
235
+ onMouseLeave: handleMouseLeave
236
+ }
237
+ ),
238
+ mousePos && showCoordinates && /* @__PURE__ */ jsxs(
239
+ "div",
240
+ {
241
+ style: {
242
+ position: "absolute",
243
+ top: "8px",
244
+ right: "8px",
245
+ backgroundColor: "rgba(0,0,0,0.7)",
246
+ color: "#fff",
247
+ fontSize: "12px",
248
+ fontFamily: "monospace",
249
+ padding: "4px 8px",
250
+ borderRadius: "4px",
251
+ pointerEvents: "none"
252
+ },
253
+ children: [
254
+ "[",
255
+ mousePos.x,
256
+ ", ",
257
+ mousePos.y,
258
+ "]"
259
+ ]
260
+ }
261
+ ),
262
+ error && /* @__PURE__ */ jsx(
263
+ "div",
264
+ {
265
+ style: {
266
+ position: "absolute",
267
+ inset: 0,
268
+ backgroundColor: "rgba(127, 29, 29, 0.9)",
269
+ display: "flex",
270
+ alignItems: "center",
271
+ justifyContent: "center",
272
+ padding: "16px"
273
+ },
274
+ children: /* @__PURE__ */ jsx(
275
+ "pre",
276
+ {
277
+ style: {
278
+ color: "#fecaca",
279
+ fontSize: "14px",
280
+ fontFamily: "monospace",
281
+ whiteSpace: "pre-wrap",
282
+ maxWidth: "100%",
283
+ overflow: "auto"
284
+ },
285
+ children: error
286
+ }
287
+ )
288
+ }
289
+ ),
290
+ !animation && !error && /* @__PURE__ */ jsx(
291
+ "div",
292
+ {
293
+ style: {
294
+ position: "absolute",
295
+ inset: 0,
296
+ backgroundColor: "rgba(38, 38, 38, 0.9)",
297
+ display: "flex",
298
+ alignItems: "center",
299
+ justifyContent: "center"
300
+ },
301
+ children: /* @__PURE__ */ jsx("p", { style: { color: "#a3a3a3" }, children: "No animation" })
302
+ }
303
+ )
304
+ ] })
305
+ }
306
+ ),
307
+ controls && /* @__PURE__ */ jsxs(
308
+ "div",
309
+ {
310
+ style: {
311
+ display: "flex",
312
+ alignItems: "center",
313
+ gap: "12px",
314
+ padding: "12px",
315
+ backgroundColor: "#262626",
316
+ borderTop: "1px solid #404040"
317
+ },
318
+ children: [
319
+ /* @__PURE__ */ jsx(
320
+ "button",
321
+ {
322
+ onClick: handleReset,
323
+ style: {
324
+ padding: "8px",
325
+ borderRadius: "4px",
326
+ border: "none",
327
+ background: "transparent",
328
+ color: "#d4d4d4",
329
+ cursor: "pointer"
330
+ },
331
+ title: "Reset",
332
+ children: /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
333
+ /* @__PURE__ */ jsx("path", { d: "M1 4v6h6M23 20v-6h-6" }),
334
+ /* @__PURE__ */ jsx("path", { d: "M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4-4.64 4.36A9 9 0 0 1 3.51 15" })
335
+ ] })
336
+ }
337
+ ),
338
+ /* @__PURE__ */ jsx(
339
+ "button",
340
+ {
341
+ onClick: handlePlayPause,
342
+ style: {
343
+ padding: "8px",
344
+ borderRadius: "4px",
345
+ border: "none",
346
+ background: "transparent",
347
+ color: "#d4d4d4",
348
+ cursor: "pointer"
349
+ },
350
+ title: isPlaying ? "Pause" : "Play",
351
+ children: isPlaying ? /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
352
+ /* @__PURE__ */ jsx("rect", { x: "6", y: "4", width: "4", height: "16" }),
353
+ /* @__PURE__ */ jsx("rect", { x: "14", y: "4", width: "4", height: "16" })
354
+ ] }) : /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("polygon", { points: "5 3 19 12 5 21 5 3" }) })
355
+ }
356
+ ),
357
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, display: "flex", alignItems: "center", gap: "12px" }, children: [
358
+ /* @__PURE__ */ jsx(
359
+ "input",
360
+ {
361
+ type: "range",
362
+ min: 0,
363
+ max: duration,
364
+ value: currentTime,
365
+ onChange: (e) => handleSeek(Number(e.target.value)),
366
+ style: {
367
+ flex: 1,
368
+ height: "4px",
369
+ borderRadius: "4px",
370
+ appearance: "none",
371
+ cursor: "pointer",
372
+ background: `linear-gradient(to right, #3b82f6 0%, #3b82f6 ${progress}%, #525252 ${progress}%, #525252 100%)`
373
+ }
374
+ }
375
+ ),
376
+ /* @__PURE__ */ jsxs(
377
+ "span",
378
+ {
379
+ style: {
380
+ color: "#a3a3a3",
381
+ fontSize: "14px",
382
+ fontFamily: "monospace",
383
+ minWidth: "100px",
384
+ textAlign: "right"
385
+ },
386
+ children: [
387
+ formatTime(currentTime),
388
+ " / ",
389
+ formatTime(duration)
390
+ ]
391
+ }
392
+ )
393
+ ] }),
394
+ /* @__PURE__ */ jsx(
395
+ "button",
396
+ {
397
+ onClick: handleDebugToggle,
398
+ style: {
399
+ padding: "8px",
400
+ borderRadius: "4px",
401
+ border: "none",
402
+ background: debugMode ? "#0891b2" : "transparent",
403
+ color: debugMode ? "#fff" : "#d4d4d4",
404
+ cursor: "pointer"
405
+ },
406
+ title: "Toggle debug overlay",
407
+ children: /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
408
+ /* @__PURE__ */ jsx("path", { d: "M12 2a10 10 0 0 1 10 10 10 10 0 0 1-10 10A10 10 0 0 1 2 12 10 10 0 0 1 12 2z" }),
409
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "4" }),
410
+ /* @__PURE__ */ jsx("path", { d: "M12 2v4M12 18v4M2 12h4M18 12h4" })
411
+ ] })
412
+ }
413
+ )
414
+ ]
415
+ }
416
+ )
417
+ ]
418
+ }
419
+ );
420
+ }
421
+ );
422
+ export {
423
+ AnimaPlayer
424
+ };
425
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","sources":["../src/react/AnimaPlayer.tsx"],"sourcesContent":["import {\n useEffect,\n useRef,\n useState,\n useCallback,\n forwardRef,\n useImperativeHandle,\n type CSSProperties,\n} from 'react';\nimport { makePlayer, type Player } from '../core/player';\nimport type { AnimationModule } from '../core/define-animation';\n\nconst DEFAULT_WIDTH = 1280;\nconst DEFAULT_HEIGHT = 720;\n\nexport interface AnimaPlayerProps {\n /** The animation module from defineAnimation() */\n animation: AnimationModule | null;\n /** Canvas width in pixels (default: 1280) */\n width?: number;\n /** Canvas height in pixels (default: 720) */\n height?: number;\n /** Start playing automatically */\n autoPlay?: boolean;\n /** Loop the animation */\n loop?: boolean;\n /** Show playback controls */\n controls?: boolean;\n /** Show debug overlay */\n debug?: boolean;\n /** Show coordinate overlay on hover */\n showCoordinates?: boolean;\n /** Called when playback time updates */\n onTimeUpdate?: (time: number) => void;\n /** Called when animation completes */\n onComplete?: () => void;\n /** Called when an error occurs */\n onError?: (error: Error) => void;\n /** Additional class name for the container */\n className?: string;\n /** Additional styles for the container */\n style?: CSSProperties;\n}\n\nexport interface AnimaPlayerHandle {\n play(): void;\n pause(): void;\n stop(): void;\n seek(timeMs: number): void;\n readonly isPlaying: boolean;\n readonly currentTime: number;\n readonly duration: number;\n}\n\nfunction formatTime(ms: number): string {\n const seconds = ms / 1000;\n return seconds.toFixed(2) + 's';\n}\n\nexport const AnimaPlayer = forwardRef<AnimaPlayerHandle, AnimaPlayerProps>(\n function AnimaPlayer(\n {\n animation,\n width = DEFAULT_WIDTH,\n height = DEFAULT_HEIGHT,\n autoPlay = false,\n loop = false,\n controls = true,\n debug = false,\n showCoordinates = false,\n onTimeUpdate,\n onComplete,\n onError,\n className,\n style,\n },\n ref\n ) {\n const containerRef = useRef<HTMLDivElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const playerRef = useRef<Player | null>(null);\n const preservedTimeRef = useRef(0);\n\n const [isPlaying, setIsPlaying] = useState(false);\n const [currentTime, setCurrentTime] = useState(0);\n const [duration, setDuration] = useState(0);\n const [displaySize, setDisplaySize] = useState({ width, height });\n const [debugMode, setDebugMode] = useState(debug);\n const [mousePos, setMousePos] = useState<{ x: number; y: number } | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const aspectRatio = width / height;\n\n // Expose player methods via ref\n useImperativeHandle(ref, () => ({\n play() {\n playerRef.current?.play();\n setIsPlaying(true);\n },\n pause() {\n playerRef.current?.pause();\n setIsPlaying(false);\n },\n stop() {\n playerRef.current?.stop();\n setIsPlaying(false);\n setCurrentTime(0);\n },\n seek(timeMs: number) {\n playerRef.current?.seek(timeMs);\n setCurrentTime(timeMs);\n },\n get isPlaying() {\n return playerRef.current?.isPlaying ?? false;\n },\n get currentTime() {\n return playerRef.current?.currentTime ?? 0;\n },\n get duration() {\n return playerRef.current?.duration ?? 0;\n },\n }));\n\n // Set up canvas backing store for retina displays\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const dpr = window.devicePixelRatio || 1;\n canvas.width = width * dpr;\n canvas.height = height * dpr;\n }, [width, height]);\n\n // Observe container size and scale canvas to fit\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const updateSize = () => {\n const rect = container.getBoundingClientRect();\n const padding = 0;\n const availableWidth = rect.width - padding;\n const availableHeight = rect.height - padding;\n\n let w = availableWidth;\n let h = w / aspectRatio;\n\n if (h > availableHeight) {\n h = availableHeight;\n w = h * aspectRatio;\n }\n\n setDisplaySize({ width: Math.floor(w), height: Math.floor(h) });\n };\n\n const observer = new ResizeObserver(updateSize);\n observer.observe(container);\n updateSize();\n\n return () => observer.disconnect();\n }, [aspectRatio]);\n\n // Create/recreate player when animation changes\n useEffect(() => {\n if (!canvasRef.current || !animation) {\n if (playerRef.current) {\n preservedTimeRef.current = playerRef.current.currentTime;\n }\n playerRef.current?.dispose();\n playerRef.current = null;\n setIsPlaying(false);\n return;\n }\n\n const previousTime = playerRef.current?.currentTime ?? preservedTimeRef.current;\n playerRef.current?.dispose();\n\n try {\n const player = makePlayer(canvasRef.current, {\n scene: animation.scene,\n timeline: animation.timeline,\n });\n\n player.onTimeUpdate = (time) => {\n setCurrentTime(time);\n setIsPlaying(player.isPlaying);\n onTimeUpdate?.(time);\n\n // Check for completion\n if (time >= player.duration && !player.isPlaying) {\n if (loop) {\n player.seek(0);\n player.play();\n } else {\n onComplete?.();\n }\n }\n };\n\n player.onError = (err) => {\n setError(err.message);\n setIsPlaying(false);\n onError?.(err);\n };\n\n playerRef.current = player;\n player.debug = debugMode;\n setDuration(player.duration);\n setError(null);\n\n const preservedTime = Math.min(previousTime, player.duration);\n player.seek(preservedTime);\n setCurrentTime(preservedTime);\n\n if (autoPlay) {\n player.play();\n setIsPlaying(true);\n } else {\n setIsPlaying(false);\n }\n\n return () => {\n player.dispose();\n };\n } catch (e) {\n const err = e instanceof Error ? e : new Error(String(e));\n setError(err.message);\n onError?.(err);\n }\n }, [animation, autoPlay, loop, onTimeUpdate, onComplete, onError, debugMode]);\n\n // Update debug mode\n useEffect(() => {\n if (playerRef.current) {\n playerRef.current.debug = debugMode;\n }\n }, [debugMode]);\n\n const handlePlayPause = useCallback(() => {\n const player = playerRef.current;\n if (!player) return;\n\n if (player.isPlaying) {\n player.pause();\n setIsPlaying(false);\n } else {\n player.play();\n setIsPlaying(true);\n }\n }, []);\n\n const handleSeek = useCallback((timeMs: number) => {\n const player = playerRef.current;\n if (!player) return;\n\n player.seek(timeMs);\n setCurrentTime(timeMs);\n }, []);\n\n const handleReset = useCallback(() => {\n const player = playerRef.current;\n if (!player) return;\n\n player.stop();\n setIsPlaying(false);\n setCurrentTime(0);\n }, []);\n\n const handleDebugToggle = useCallback(() => {\n setDebugMode((prev) => !prev);\n }, []);\n\n const handleMouseMove = useCallback(\n (e: React.MouseEvent<HTMLCanvasElement>) => {\n if (!showCoordinates) return;\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const rect = canvas.getBoundingClientRect();\n const scaleX = width / rect.width;\n const scaleY = height / rect.height;\n\n const x = Math.round((e.clientX - rect.left) * scaleX);\n const y = Math.round((e.clientY - rect.top) * scaleY);\n\n setMousePos({ x, y });\n },\n [width, height, showCoordinates]\n );\n\n const handleMouseLeave = useCallback(() => {\n setMousePos(null);\n }, []);\n\n const progress = duration > 0 ? (currentTime / duration) * 100 : 0;\n\n return (\n <div\n className={className}\n style={{\n display: 'flex',\n flexDirection: 'column',\n backgroundColor: '#171717',\n ...style,\n }}\n >\n <div\n ref={containerRef}\n style={{\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '16px',\n overflow: 'hidden',\n }}\n >\n <div style={{ position: 'relative', backgroundColor: '#fff', borderRadius: '4px', boxShadow: '0 4px 6px rgba(0,0,0,0.3)' }}>\n <canvas\n ref={canvasRef}\n style={{\n display: 'block',\n width: displaySize.width,\n height: displaySize.height,\n }}\n onMouseMove={handleMouseMove}\n onMouseLeave={handleMouseLeave}\n />\n {mousePos && showCoordinates && (\n <div\n style={{\n position: 'absolute',\n top: '8px',\n right: '8px',\n backgroundColor: 'rgba(0,0,0,0.7)',\n color: '#fff',\n fontSize: '12px',\n fontFamily: 'monospace',\n padding: '4px 8px',\n borderRadius: '4px',\n pointerEvents: 'none',\n }}\n >\n [{mousePos.x}, {mousePos.y}]\n </div>\n )}\n {error && (\n <div\n style={{\n position: 'absolute',\n inset: 0,\n backgroundColor: 'rgba(127, 29, 29, 0.9)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '16px',\n }}\n >\n <pre\n style={{\n color: '#fecaca',\n fontSize: '14px',\n fontFamily: 'monospace',\n whiteSpace: 'pre-wrap',\n maxWidth: '100%',\n overflow: 'auto',\n }}\n >\n {error}\n </pre>\n </div>\n )}\n {!animation && !error && (\n <div\n style={{\n position: 'absolute',\n inset: 0,\n backgroundColor: 'rgba(38, 38, 38, 0.9)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <p style={{ color: '#a3a3a3' }}>No animation</p>\n </div>\n )}\n </div>\n </div>\n\n {controls && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n padding: '12px',\n backgroundColor: '#262626',\n borderTop: '1px solid #404040',\n }}\n >\n <button\n onClick={handleReset}\n style={{\n padding: '8px',\n borderRadius: '4px',\n border: 'none',\n background: 'transparent',\n color: '#d4d4d4',\n cursor: 'pointer',\n }}\n title=\"Reset\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M1 4v6h6M23 20v-6h-6\" />\n <path d=\"M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4-4.64 4.36A9 9 0 0 1 3.51 15\" />\n </svg>\n </button>\n\n <button\n onClick={handlePlayPause}\n style={{\n padding: '8px',\n borderRadius: '4px',\n border: 'none',\n background: 'transparent',\n color: '#d4d4d4',\n cursor: 'pointer',\n }}\n title={isPlaying ? 'Pause' : 'Play'}\n >\n {isPlaying ? (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" />\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" />\n </svg>\n ) : (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polygon points=\"5 3 19 12 5 21 5 3\" />\n </svg>\n )}\n </button>\n\n <div style={{ flex: 1, display: 'flex', alignItems: 'center', gap: '12px' }}>\n <input\n type=\"range\"\n min={0}\n max={duration}\n value={currentTime}\n onChange={(e) => handleSeek(Number(e.target.value))}\n style={{\n flex: 1,\n height: '4px',\n borderRadius: '4px',\n appearance: 'none',\n cursor: 'pointer',\n background: `linear-gradient(to right, #3b82f6 0%, #3b82f6 ${progress}%, #525252 ${progress}%, #525252 100%)`,\n }}\n />\n <span\n style={{\n color: '#a3a3a3',\n fontSize: '14px',\n fontFamily: 'monospace',\n minWidth: '100px',\n textAlign: 'right',\n }}\n >\n {formatTime(currentTime)} / {formatTime(duration)}\n </span>\n </div>\n\n <button\n onClick={handleDebugToggle}\n style={{\n padding: '8px',\n borderRadius: '4px',\n border: 'none',\n background: debugMode ? '#0891b2' : 'transparent',\n color: debugMode ? '#fff' : '#d4d4d4',\n cursor: 'pointer',\n }}\n title=\"Toggle debug overlay\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M12 2a10 10 0 0 1 10 10 10 10 0 0 1-10 10A10 10 0 0 1 2 12 10 10 0 0 1 12 2z\" />\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <path d=\"M12 2v4M12 18v4M2 12h4M18 12h4\" />\n </svg>\n </button>\n </div>\n )}\n </div>\n );\n }\n);\n"],"names":["AnimaPlayer"],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { Plugin } from 'vite';
2
+ export interface AnimaPluginOptions {
3
+ /**
4
+ * Glob patterns for animation files that should get HMR support
5
+ * @default ['**\/*.animation.ts', '**\/*.animation.tsx']
6
+ */
7
+ include?: string[];
8
+ }
9
+ /**
10
+ * Vite plugin for Anima animations.
11
+ * Provides HMR support that preserves playback time when animation files change.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * // vite.config.ts
16
+ * import { defineConfig } from 'vite';
17
+ * import react from '@vitejs/plugin-react';
18
+ * import { animaPlugin } from '@syma/anima/vite';
19
+ *
20
+ * export default defineConfig({
21
+ * plugins: [react(), animaPlugin()],
22
+ * });
23
+ * ```
24
+ */
25
+ export declare function animaPlugin(options?: AnimaPluginOptions): Plugin;
26
+ export default animaPlugin;
package/dist/vite.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { animaPlugin, default } from './vite/plugin';
2
+ export type { AnimaPluginOptions } from './vite/plugin';
package/dist/vite.js ADDED
@@ -0,0 +1,25 @@
1
+ function animaPlugin(options = {}) {
2
+ const {
3
+ include = ["**/*.animation.ts", "**/*.animation.tsx"]
4
+ } = options;
5
+ const isAnimationFile = (id) => {
6
+ return include.some((pattern) => {
7
+ const regex = pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*").replace(/\./g, "\\.");
8
+ return new RegExp(regex).test(id);
9
+ });
10
+ };
11
+ return {
12
+ name: "vite-plugin-anima",
13
+ // Handle HMR for animation files
14
+ handleHotUpdate({ file, modules }) {
15
+ if (isAnimationFile(file)) {
16
+ return modules;
17
+ }
18
+ }
19
+ };
20
+ }
21
+ export {
22
+ animaPlugin,
23
+ animaPlugin as default
24
+ };
25
+ //# sourceMappingURL=vite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite.js","sources":["../src/vite/plugin.ts"],"sourcesContent":["import type { Plugin } from 'vite';\n\nexport interface AnimaPluginOptions {\n /**\n * Glob patterns for animation files that should get HMR support\n * @default ['**\\/*.animation.ts', '**\\/*.animation.tsx']\n */\n include?: string[];\n}\n\n/**\n * Vite plugin for Anima animations.\n * Provides HMR support that preserves playback time when animation files change.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import react from '@vitejs/plugin-react';\n * import { animaPlugin } from '@syma/anima/vite';\n *\n * export default defineConfig({\n * plugins: [react(), animaPlugin()],\n * });\n * ```\n */\nexport function animaPlugin(options: AnimaPluginOptions = {}): Plugin {\n const {\n include = ['**/*.animation.ts', '**/*.animation.tsx'],\n } = options;\n\n const isAnimationFile = (id: string): boolean => {\n return include.some((pattern) => {\n // Simple glob matching for common patterns\n const regex = pattern\n .replace(/\\*\\*/g, '.*')\n .replace(/\\*/g, '[^/]*')\n .replace(/\\./g, '\\\\.');\n return new RegExp(regex).test(id);\n });\n };\n\n return {\n name: 'vite-plugin-anima',\n\n // Handle HMR for animation files\n handleHotUpdate({ file, modules }) {\n if (isAnimationFile(file)) {\n // Let Vite handle the HMR normally\n // The AnimaPlayer component will preserve time automatically\n // because it stores currentTime in a ref before recreating the player\n return modules;\n }\n },\n };\n}\n\nexport default animaPlugin;\n"],"names":[],"mappings":"AA0BO,SAAS,YAAY,UAA8B,IAAY;AAClE,QAAM;AAAA,IACF,UAAU,CAAC,qBAAqB,oBAAoB;AAAA,EAAA,IACpD;AAEJ,QAAM,kBAAkB,CAAC,OAAwB;AAC7C,WAAO,QAAQ,KAAK,CAAC,YAAY;AAE7B,YAAM,QAAQ,QACT,QAAQ,SAAS,IAAI,EACrB,QAAQ,OAAO,OAAO,EACtB,QAAQ,OAAO,KAAK;AACzB,aAAO,IAAI,OAAO,KAAK,EAAE,KAAK,EAAE;AAAA,IACpC,CAAC;AAAA,EACL;AAEA,SAAO;AAAA,IACH,MAAM;AAAA;AAAA,IAGN,gBAAgB,EAAE,MAAM,WAAW;AAC/B,UAAI,gBAAgB,IAAI,GAAG;AAIvB,eAAO;AAAA,MACX;AAAA,IACJ;AAAA,EAAA;AAER;"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@it-compiles/anima",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ },
12
+ "./react": {
13
+ "types": "./dist/react.d.ts",
14
+ "import": "./dist/react.js"
15
+ },
16
+ "./vite": {
17
+ "types": "./dist/vite.d.ts",
18
+ "import": "./dist/vite.js"
19
+ }
20
+ },
21
+ "sideEffects": false,
22
+ "files": [
23
+ "dist",
24
+ "README.md"
25
+ ],
26
+ "scripts": {
27
+ "build": "vite build && tsc --emitDeclarationOnly",
28
+ "dev": "vite build --watch"
29
+ },
30
+ "peerDependencies": {
31
+ "react": ">=18.0.0",
32
+ "react-dom": ">=18.0.0",
33
+ "vite": ">=5.0.0"
34
+ },
35
+ "peerDependenciesMeta": {
36
+ "react": { "optional": true },
37
+ "react-dom": { "optional": true },
38
+ "vite": { "optional": true }
39
+ },
40
+ "dependencies": {
41
+ "mp4-muxer": "^5.2.2"
42
+ },
43
+ "devDependencies": {
44
+ "@vitejs/plugin-react": "^5.1.1",
45
+ "vite": "^7.2.4",
46
+ "vite-plugin-dts": "^4.5.4"
47
+ }
48
+ }