rig-play 0.8.0 → 1.0.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.
Files changed (44) hide show
  1. package/NOTICE.md +50 -23
  2. package/README.md +354 -461
  3. package/dist/CanvasRenderer.d.ts +139 -0
  4. package/dist/CanvasRenderer.d.ts.map +1 -0
  5. package/dist/{SpineHtmlRenderer.d.ts → DomRenderer.d.ts} +70 -65
  6. package/dist/DomRenderer.d.ts.map +1 -0
  7. package/dist/DomTexture.d.ts +34 -14
  8. package/dist/DomTexture.d.ts.map +1 -1
  9. package/dist/MeshGlBlitter.d.ts +67 -1
  10. package/dist/MeshGlBlitter.d.ts.map +1 -1
  11. package/dist/index.d.ts +6 -4
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +7271 -5
  14. package/dist/index.js.map +1 -1
  15. package/dist/loadModel.d.ts +92 -0
  16. package/dist/loadModel.d.ts.map +1 -0
  17. package/dist/player.d.ts +151 -0
  18. package/dist/player.d.ts.map +1 -0
  19. package/dist/posedFrame.d.ts +99 -0
  20. package/dist/posedFrame.d.ts.map +1 -0
  21. package/package.json +13 -19
  22. package/dist/DomTexture.js +0 -520
  23. package/dist/DomTexture.js.map +0 -1
  24. package/dist/MeshGlBlitter.js +0 -365
  25. package/dist/MeshGlBlitter.js.map +0 -1
  26. package/dist/SpineHtmlRenderer.d.ts.map +0 -1
  27. package/dist/SpineHtmlRenderer.js +0 -1107
  28. package/dist/SpineHtmlRenderer.js.map +0 -1
  29. package/dist/binary.d.ts +0 -48
  30. package/dist/binary.d.ts.map +0 -1
  31. package/dist/binary.js +0 -29
  32. package/dist/binary.js.map +0 -1
  33. package/dist/coreCompat.d.ts +0 -153
  34. package/dist/coreCompat.d.ts.map +0 -1
  35. package/dist/coreCompat.js +0 -136
  36. package/dist/coreCompat.js.map +0 -1
  37. package/dist/loadAtlasAssets.d.ts +0 -73
  38. package/dist/loadAtlasAssets.d.ts.map +0 -1
  39. package/dist/loadAtlasAssets.js +0 -75
  40. package/dist/loadAtlasAssets.js.map +0 -1
  41. package/dist/loadSkeletonAssets.d.ts +0 -88
  42. package/dist/loadSkeletonAssets.d.ts.map +0 -1
  43. package/dist/loadSkeletonAssets.js +0 -79
  44. package/dist/loadSkeletonAssets.js.map +0 -1
@@ -0,0 +1,92 @@
1
+ import { type RegionImage } from './DomTexture.js';
2
+ /**
3
+ * Loads a rig built by `rigc build`: the compiled model document
4
+ * (`skeleton.model.json`, spec `rigc-compiled/3`) and the page images its
5
+ * `pages` section names, cut into region bitmaps once.
6
+ *
7
+ * The document states everything the player reads — the skeleton, the
8
+ * animations, and where every region sits on its page — so the `.atlas` and
9
+ * `skeleton.json` the build writes beside it are not fetched. A Spine export
10
+ * (`.json`, `.skel`) is refused by name: this package poses the compiled model
11
+ * through `rig-c/core` and reads nothing else.
12
+ */
13
+ export interface LoadModelOptions {
14
+ /** URL of the compiled model document (`skeleton.model.json`). */
15
+ modelUrl: string;
16
+ /**
17
+ * Maps a page name from the document's `pages` section to the URL its image
18
+ * lives at. Defaults to resolving the name against the model URL's
19
+ * directory: a build writes page names as paths relative to its own
20
+ * directory, which is where the document sits.
21
+ */
22
+ resolvePage?: (pageName: string, modelUrl: string) => string;
23
+ /**
24
+ * crossOrigin attribute for the page images. Needed when the images come
25
+ * from another origin: the region cut reads them into a canvas, and a
26
+ * tainted canvas cannot be exported (SecurityError from toBlob).
27
+ */
28
+ crossOrigin?: string;
29
+ /** fetch implementation, for custom headers or a test double. */
30
+ fetch?: typeof globalThis.fetch;
31
+ }
32
+ /**
33
+ * What `new RigPlayer(root, assets)` draws from. The caller owns it: one load
34
+ * can back any number of players, and nothing a player does disposes it.
35
+ */
36
+ export interface ModelAssets {
37
+ /** The document's spec, e.g. `rigc-compiled/3`. */
38
+ readonly spec: string;
39
+ /** Every animation the document carries, in its order, with the runtime's duration. */
40
+ readonly animations: ReadonlyArray<{
41
+ readonly name: string;
42
+ readonly duration: number;
43
+ }>;
44
+ /** Every skin the document declares, in its order. */
45
+ readonly skins: readonly string[];
46
+ /**
47
+ * The setup pose's box in world units (Y up) as the document states it —
48
+ * the rig's own framing, for laying out a stage — or null where it states
49
+ * none.
50
+ */
51
+ readonly stage: {
52
+ readonly x: number;
53
+ readonly y: number;
54
+ readonly width: number;
55
+ readonly height: number;
56
+ } | null;
57
+ /** Unpacked per-region bitmaps, keyed by region name — the rigid tier's. */
58
+ readonly regionImages: Map<string, RegionImage>;
59
+ /** Page images, keyed by the document's page names — the mesh tier's. */
60
+ readonly pageImages: Map<string, HTMLImageElement>;
61
+ /**
62
+ * The document as `rig-c/core` read it. Opaque to callers: the player poses
63
+ * it, and its shape is rig-c's, not this package's.
64
+ */
65
+ readonly document: ModelDocument;
66
+ /**
67
+ * Frees the blob URLs this load created (see revokeRegions). Idempotent.
68
+ * Call it after the players drawing from these assets are disposed — a live
69
+ * <img> would be left pointing at a dead URL.
70
+ */
71
+ dispose(): void;
72
+ }
73
+ /** The read document, held for the player. Deliberately opaque. */
74
+ export interface ModelDocument {
75
+ readonly spec: string;
76
+ }
77
+ /**
78
+ * Loads a rig built by `rigc build`.
79
+ *
80
+ * ```ts
81
+ * const assets = await loadModel({ modelUrl: '/rigs/walk/skeleton.model.json' });
82
+ * const player = new RigPlayer(root, assets);
83
+ * player.play('walk');
84
+ * // each frame: player.frame(dt)
85
+ * // …later: player.dispose(); assets.dispose();
86
+ * ```
87
+ *
88
+ * Page images load in parallel. If anything fails part-way, no blob URL is
89
+ * left behind.
90
+ */
91
+ export declare function loadModel(options: LoadModelOptions): Promise<ModelAssets>;
92
+ //# sourceMappingURL=loadModel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadModel.d.ts","sourceRoot":"","sources":["../src/loadModel.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,WAAW,EAAgC,MAAM,iBAAiB,CAAC;AAEjF;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7D;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uFAAuF;IACvF,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzF,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACnH,4EAA4E;IAC5E,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAChD,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACnD;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC;;;;OAIG;IACH,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,mEAAmE;AACnE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAgED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAqC/E"}
@@ -0,0 +1,151 @@
1
+ import { CanvasRenderer } from './CanvasRenderer.js';
2
+ import { DomRenderer, type MeshBackend } from './DomRenderer.js';
3
+ import type { ModelAssets } from './loadModel.js';
4
+ import { type PosedFrame } from './posedFrame.js';
5
+ /**
6
+ * Plays a rig built by `rigc build` on a DOM root.
7
+ *
8
+ * The player owns the track and the renderer: `play` opens an animation on a
9
+ * live track (`openTrack` from `rig-c/core`), each `frame(dt)` steps it by
10
+ * `dt × timeScale`, turns the pose into a `PosedFrame` and hands that to its
11
+ * renderer — a `DomRenderer` (`mode: 'dom'`, the default) or a
12
+ * `CanvasRenderer` (`mode: 'canvas'`). Everything the pose holds is computed by
13
+ * the core from the compiled model document; this class schedules and draws.
14
+ */
15
+ /**
16
+ * How a player draws: `'dom'` — elements, the rigid tier as `<img>` and the
17
+ * mesh tier on per-part canvases (`DomRenderer`); `'canvas'` — the whole frame
18
+ * into one `<canvas>` through the shared WebGL context (`CanvasRenderer`).
19
+ */
20
+ export type RenderMode = 'dom' | 'canvas';
21
+ export interface RigPlayerOptions {
22
+ /**
23
+ * The skin to pose under. Absent is the runtime's "no skin set" — a fresh
24
+ * skeleton whose `setSkin` was never called (`underNoSkin`): no skin's bones
25
+ * or constraints applied, every slot resolved through the default skin.
26
+ */
27
+ skin?: string;
28
+ /** How the player draws (see `RenderMode`). Default `'dom'`. Can be changed later through `mode`. */
29
+ mode?: RenderMode;
30
+ /** The mesh tier's rasterizer (see `DomRenderer.meshBackend`) — the DOM mode only. */
31
+ meshBackend?: MeshBackend;
32
+ /**
33
+ * The step `seek` walks the track forward with, in seconds. A seek is
34
+ * "reopen, then step to the time", never a jump: a physics rig has history,
35
+ * and the pose at a time depends on the steps taken to reach it.
36
+ */
37
+ seekStep?: number;
38
+ }
39
+ /** What `on('event', …)` hands a listener: one event key the step crossed. */
40
+ export interface RigEvent {
41
+ name: string;
42
+ /** The key's time in the animation. */
43
+ time: number;
44
+ int: number;
45
+ float: number;
46
+ string: string | null;
47
+ }
48
+ type Listener<T> = (payload: T) => void;
49
+ /**
50
+ * One rig on one root.
51
+ *
52
+ * ```ts
53
+ * const player = new RigPlayer(root, assets);
54
+ * player.play('walk');
55
+ * requestAnimationFrame(function tick(now) { player.frame(dt); requestAnimationFrame(tick); });
56
+ * ```
57
+ */
58
+ export declare class RigPlayer {
59
+ /**
60
+ * The renderer this player draws through — its knobs and counters are the
61
+ * caller's to read and set. A `DomRenderer` in the DOM mode, a
62
+ * `CanvasRenderer` in the canvas mode; a new object after `mode` changes.
63
+ */
64
+ get renderer(): DomRenderer | CanvasRenderer;
65
+ /** Multiplies every step. 0 holds the pose (nothing is re-posed); negative is refused by the track. */
66
+ timeScale: number;
67
+ /** The player's whole-rig colour, r g b a — multiplied into every slot's tint. Not a document value. */
68
+ color: [number, number, number, number];
69
+ private active;
70
+ private readonly root;
71
+ private readonly assets;
72
+ private readonly meshBackend;
73
+ private readonly view;
74
+ private readonly source;
75
+ private readonly seekStep;
76
+ private track;
77
+ private animation;
78
+ private loop;
79
+ private paused;
80
+ private pose;
81
+ private readonly listeners;
82
+ constructor(root: HTMLElement, assets: ModelAssets, options?: RigPlayerOptions);
83
+ /**
84
+ * How the player draws. Setting it swaps the renderer without reloading
85
+ * anything: the old one is disposed (its elements removed, its GPU pages
86
+ * handed back), the new one is created over the same root and the same
87
+ * assets, `pixelRatio` and `clipping` carry over, and the pose the player
88
+ * holds is drawn again at once.
89
+ */
90
+ get mode(): RenderMode;
91
+ set mode(mode: RenderMode);
92
+ private create;
93
+ /** The animation the track is playing, or null before `play`. */
94
+ get current(): string | null;
95
+ /** The track time — the running sum of the steps since `play` (or the last `seek`). */
96
+ get time(): number;
97
+ /**
98
+ * Opens `name` on the track at its first pose, the physics reset there. The
99
+ * pose is drawn on the next `frame`.
100
+ */
101
+ play(name: string, options?: {
102
+ loop?: boolean;
103
+ }): void;
104
+ /** Stops stepping; `frame` keeps drawing the pose it holds. */
105
+ pause(): void;
106
+ /** Resumes stepping after `pause`. */
107
+ resume(): void;
108
+ /**
109
+ * Moves the track to `time`: the animation is reopened and stepped forward
110
+ * in `seekStep` increments (the last one shorter) until the track time
111
+ * reaches `time`. Events and completes crossed on the way are not fired.
112
+ */
113
+ seek(time: number): void;
114
+ /** Adds a listener; returns a function that removes it. */
115
+ on(type: 'event', listener: Listener<RigEvent>): () => void;
116
+ on(type: 'complete', listener: Listener<{
117
+ animation: string;
118
+ }>): () => void;
119
+ /**
120
+ * Advances the track by `dt × timeScale` seconds and draws the pose —
121
+ * `advance(dt)` then `draw()`.
122
+ */
123
+ frame(dt: number): void;
124
+ /**
125
+ * Steps the track by `dt × timeScale` seconds and fires the step's listeners,
126
+ * without drawing. A paused player, or a step of zero, keeps the pose it
127
+ * holds without re-posing it, so a held rig costs the renderer's dirty
128
+ * checks and nothing else.
129
+ */
130
+ advance(dt: number): void;
131
+ /** Draws the pose the player holds. */
132
+ draw(): void;
133
+ /** The pose the player holds, as the frame record the renderer draws. */
134
+ posedFrame(): PosedFrame;
135
+ /** Removes the renderer's elements and hands its GPU pages back. The assets stay the caller's. */
136
+ dispose(): void;
137
+ private open;
138
+ /**
139
+ * The step's events, then its complete. The core fires the keys
140
+ * (`pose.events`, in the runtime's order across a wrap) and leaves
141
+ * `complete` to the player, which derives it from the track time and the
142
+ * duration: on a looping track, once on a step whose whole cycles rose past
143
+ * 0 (rig-c `src/core/track.ts`, *Across the wrap*); on a held one, on the
144
+ * step that reaches the duration. The runtime queues a looping complete
145
+ * between the keys before the wrap and the keys after it; this player
146
+ * dispatches it after all of the step's keys.
147
+ */
148
+ private dispatch;
149
+ }
150
+ export {};
151
+ //# sourceMappingURL=player.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * The record the DOM tier draws: one posed moment of a rig, every slot the
3
+ * renderer shows, in draw order.
4
+ *
5
+ * The renderer never needed a skeleton. Per slot it needs the kind, four world
6
+ * corners or world vertices with page UVs and triangles, the bitmap or the
7
+ * page image with its alpha convention, a tint, a blend mode, a clip polygon
8
+ * and a stacking position — and every one of those is a field of a pose that
9
+ * `rig-c/core` computes from the compiled model document, plus that document's
10
+ * `pages` section. This module is the adapter from one to the other
11
+ * (`frameOf`), and these types are the whole of what crosses it.
12
+ *
13
+ * Coordinates are world space, Y up, exactly as the poser computed them; the
14
+ * renderer does the Y flip. Nothing here is rounded or re-ordered.
15
+ */
16
+ export interface PosedFrame {
17
+ /** Every slot that draws, in draw order. */
18
+ order: PosedSlot[];
19
+ }
20
+ /** The four blend modes, spelled as the runtime's enum names them. */
21
+ export type BlendMode = 'Normal' | 'Additive' | 'Multiply' | 'Screen';
22
+ /**
23
+ * A clip polygon in world space and whether it keeps what is outside it.
24
+ *
25
+ * One object per clip in force: every slot a clip covers carries the *same*
26
+ * object, which is how the renderer tells a clip that covers the whole frame
27
+ * (one `clip-path` on the root) from one that covers a range of it.
28
+ */
29
+ export interface PosedClip {
30
+ /** Flat x, y pairs, world space. */
31
+ polygon: number[];
32
+ inverse: boolean;
33
+ /**
34
+ * The clipping attachment's `convex` flag: a polygon that is not convex is
35
+ * clipped against its hull rather than decomposed. The DOM tier's CSS
36
+ * `clip-path` takes the polygon as authored and does not read it; the canvas
37
+ * mode's triangle cut does (`clipThrough` in `rig-c/core`).
38
+ */
39
+ convex: boolean;
40
+ }
41
+ interface PosedSlotCommon {
42
+ /** The slot's name — the renderer keys its element on it. */
43
+ slot: string;
44
+ /** The slot's index in the full draw order (hidden slots included): its z-index. */
45
+ z: number;
46
+ blend: BlendMode;
47
+ /** Slot colour × attachment colour × the player's own colour, r g b a in [0, 1]. */
48
+ tint: [number, number, number, number];
49
+ /** The slot's dark (two-colour) tint, where it carries one. The DOM tier cannot draw it. */
50
+ dark?: [number, number, number];
51
+ /** The clip in force over this slot, where one is. */
52
+ clip?: PosedClip;
53
+ }
54
+ /** A rigid slot: an unpacked region bitmap posed by its four world corners. */
55
+ export interface PosedRegion extends PosedSlotCommon {
56
+ kind: 'region';
57
+ /** The region drawn — the key into the region bitmap map (a sequence frame's own name). */
58
+ region: string;
59
+ /** Four world corners, bottom-left, upper-left, upper-right, bottom-right: x0 y0 … x3 y3. */
60
+ corners: number[];
61
+ /**
62
+ * The page the region sits on — the key into the page image map. The DOM tier
63
+ * draws the region's own bitmap and never reads it; the canvas mode samples
64
+ * the page through `uvs`.
65
+ */
66
+ page: string;
67
+ /** Whether the page's texels are premultiplied by their alpha. */
68
+ pma: boolean;
69
+ /**
70
+ * The region's page UVs at its four corners, in the corners' order (u, v
71
+ * pairs, the page spanning [0, 1]) — the runtime's region UVs, a 90°-packed
72
+ * region's turn included. The same array object from frame to frame for the
73
+ * same region.
74
+ */
75
+ uvs: number[];
76
+ }
77
+ /** A deform slot: world vertices over page UVs, rastered from the page image. */
78
+ export interface PosedMesh extends PosedSlotCommon {
79
+ kind: 'mesh';
80
+ /** The page drawn — the key into the page image map. */
81
+ page: string;
82
+ /** Whether the page's texels are premultiplied by their alpha. */
83
+ pma: boolean;
84
+ /** World vertices, flat x, y pairs. */
85
+ vertices: number[];
86
+ /**
87
+ * Page UVs, flat u, v pairs, the page spanning [0, 1]. The same array object
88
+ * from frame to frame for the same region and attachment, so the renderer
89
+ * can tell a mesh whose texture did not change by identity.
90
+ */
91
+ uvs: number[];
92
+ /** Triangle indices into `vertices`, three per triangle. Stable by identity like `uvs`. */
93
+ triangles: number[];
94
+ /** The sequence frame drawn (0 for an attachment with no series). */
95
+ sequence: number;
96
+ }
97
+ export type PosedSlot = PosedRegion | PosedMesh;
98
+ export {};
99
+ //# sourceMappingURL=posedFrame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"posedFrame.d.ts","sourceRoot":"","sources":["../src/posedFrame.ts"],"names":[],"mappings":"AAiBA;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,UAAU;IACzB,4CAA4C;IAC5C,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAED,sEAAsE;AACtE,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEtE;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,oCAAoC;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,UAAU,eAAe;IACvB,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,SAAS,CAAC;IACjB,oFAAoF;IACpF,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,4FAA4F;IAC5F,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,sDAAsD;IACtD,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,+EAA+E;AAC/E,MAAM,WAAW,WAAY,SAAQ,eAAe;IAClD,IAAI,EAAE,QAAQ,CAAC;IACf,2FAA2F;IAC3F,MAAM,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,GAAG,EAAE,OAAO,CAAC;IACb;;;;;OAKG;IACH,GAAG,EAAE,MAAM,EAAE,CAAC;CACf;AAED,iFAAiF;AACjF,MAAM,WAAW,SAAU,SAAQ,eAAe;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,GAAG,EAAE,OAAO,CAAC;IACb,uCAAuC;IACvC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;;OAIG;IACH,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,2FAA2F;IAC3F,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC"}
package/package.json CHANGED
@@ -1,19 +1,23 @@
1
1
  {
2
2
  "name": "rig-play",
3
- "version": "0.8.0",
4
- "description": "Render Spine skeletal animations as plain DOM — rigid slots as <img> posed by CSS matrix, deform meshes on small per-part canvases, interleaved in one stacking context.",
3
+ "version": "1.0.0",
4
+ "description": "Plays skeleton.model.json written by rigc build as plain DOM elements — rigid slots as <img> posed by CSS matrix, deform meshes on small per-part canvases — or as one canvas.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": "firejune",
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "https://github.com/firejune/spine-html.git"
10
+ "url": "https://github.com/firejune/rig-play.git"
11
11
  },
12
- "homepage": "https://github.com/firejune/spine-html#readme",
13
- "bugs": "https://github.com/firejune/spine-html/issues",
12
+ "homepage": "https://github.com/firejune/rig-play#readme",
13
+ "funding": {
14
+ "type": "github",
15
+ "url": "https://github.com/sponsors/firejune"
16
+ },
17
+ "bugs": "https://github.com/firejune/rig-play/issues",
14
18
  "keywords": [
15
- "spine",
16
- "spine2d",
19
+ "rigc",
20
+ "rig-c",
17
21
  "skeletal-animation",
18
22
  "mesh-deformation",
19
23
  "dom",
@@ -29,10 +33,6 @@
29
33
  ".": {
30
34
  "types": "./dist/index.d.ts",
31
35
  "import": "./dist/index.js"
32
- },
33
- "./binary": {
34
- "types": "./dist/binary.d.ts",
35
- "import": "./dist/binary.js"
36
36
  }
37
37
  },
38
38
  "files": [
@@ -45,9 +45,7 @@
45
45
  "dev": "vite",
46
46
  "prebuild": "bash scripts/fetch-assets.sh",
47
47
  "build": "tsc --noEmit && vite build",
48
- "prebuild:pages": "bash scripts/fetch-assets.sh",
49
- "build:pages": "vite build",
50
- "build:lib": "rm -rf dist && tsc -p tsconfig.build.json",
48
+ "build:lib": "rm -rf dist && node scripts/build-lib.mjs dist",
51
49
  "prepublishOnly": "npm run build:lib",
52
50
  "preview": "vite preview",
53
51
  "test": "playwright test",
@@ -56,14 +54,10 @@
56
54
  "bench:build": "bash scripts/fetch-assets.sh && vite build --config bench/vite.config.ts",
57
55
  "fetch-assets": "bash scripts/fetch-assets.sh"
58
56
  },
59
- "peerDependencies": {
60
- "@esotericsoftware/spine-core": ">=4.0.0 <4.4.0"
61
- },
62
57
  "devDependencies": {
63
- "@esotericsoftware/spine-core": "^4.3.13",
64
- "@esotericsoftware/spine-webgl": "4.3.13",
65
58
  "@playwright/test": "1.62.1",
66
59
  "@types/node": "^22",
60
+ "rig-c": "2.35.0",
67
61
  "typescript": "^5.6.0",
68
62
  "vite": "^6.0.0"
69
63
  }