rig-play 1.4.0 → 1.6.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/README.md CHANGED
@@ -263,6 +263,62 @@ box, an inverse clip removes nothing, and bounding boxes, paths and points do
263
263
  not draw and do not count. Both cost nothing until called and read the same
264
264
  numbers in `dom` and `canvas` mode.
265
265
 
266
+ ### Drawing some slots only
267
+
268
+ `slots` is a draw filter — an allow list of slot names or a predicate — settable up
269
+ front and on a live player. The pose is the whole rig's whatever the filter:
270
+ bones, constraints, physics, `bone()`, `adjust`, events and tracks see no filter;
271
+ only the draw does, in both modes, and `bounds()` reads the drawn slots. A
272
+ clipping slot the filter leaves out does not clip. An allow list naming a slot
273
+ the document does not have is refused by name.
274
+
275
+ ```ts
276
+ const hand = new RigPlayer(frontRoot, assets, { slots: ['hand_f', 'arm_f_lo'] });
277
+ player.slots = (slot) => !slot.startsWith('weapon');
278
+ ```
279
+
280
+ Two players over one `ModelAssets` share the load but each poses the rig. To
281
+ pose it once and draw it twice — a hand drawn again in front of another
282
+ character — give a second renderer this player's pose under another filter:
283
+
284
+ ```ts
285
+ const front = new DomRenderer(frontRoot, assets.regionImages, assets.pageImages);
286
+ // each frame, after player.frame(dt):
287
+ front.render(player.posedFrame(['hand_f', 'arm_f_lo']));
288
+ ```
289
+
290
+ ### Several tracks
291
+
292
+ A base on track 0, a layer over it, a one-shot played once and mixed back out —
293
+ rig-c's live tracks (`openTracks`), whose mixing is the Spine runtime's
294
+ `AnimationState` held at tolerance 0:
295
+
296
+ ```ts
297
+ player.play('idle'); // track 0, as always
298
+ player.play('smile', { track: 1, loop: false, mix: 0.2 }); // held at its end, mixed in over 0.2 s
299
+ player.play('wave', { track: 2, loop: false, mix: 0.1 }); // a one-shot…
300
+ player.queueClear(2, { mix: 0.1 }); // …mixed back out over its last 0.1 s
301
+ player.queue('idle_b', { track: 0, mix: 0.3 }); // after the current idle cycle completes
302
+ player.clear(1, { mix: 0.2 }); // the layer gone, the base showing through
303
+ player.entry(2); // { animation, loop, trackTime, animationTime, duration } | null
304
+ ```
305
+
306
+ `play(name)` keeps meaning what it meant: a plain play on track 0 runs on rig-c's
307
+ single live track, which poses everything the core poses. The first call that
308
+ composes — a `mix`, a `track` above 0, a `queue`, a `clear` — moves the player onto
309
+ the tracks, carrying the single track over by replay (its animation set, pose 0
310
+ taken, stepped to its time); from then on `seek` and `skin` are refused by name,
311
+ since the player cannot replay a composition to a time — step it forward instead.
312
+ Every entry mixes from the setup pose each step, so `adjust` writes still last one
313
+ pose. **What the tracks do not mix**, in rig-c's words at `play`/`queue`: an
314
+ animation keying a constraint (ik, transform, path, physics, slider), a sequence,
315
+ the draw order, or a path's deform is refused when it is set on the tracks — it
316
+ plays on the single track only. `'event'` carries `track`; a one-shot that is
317
+ mixing out fires nothing. `'complete'` is per track, the player's rule: a looping
318
+ entry each cycle, a held one when it reaches its duration, and an entry that is
319
+ replaced — by `play`, or by the queued entry that starts at its completion less the
320
+ mix — completes no more than it fires.
321
+
266
322
  ### Adjusting bones
267
323
 
268
324
  A per-pose write to bone locals — a breath's scale, a look's rotation, a mouth
@@ -596,11 +652,13 @@ name, and unloading is still elements first, bitmaps second.
596
652
  | `DomTexture` | none | Not exported; there is no atlas page to attach a texture to. |
597
653
  | `new Skeleton(assets.data)` and `new AnimationState(new AnimationStateData(assets.data))` | `new RigPlayer(root, assets, options?)` | The player holds the pose and the track. |
598
654
  | `state.setAnimation(0, 'walk', true)` | `player.play('walk', { loop: true })` | `loop` defaults to true. `play` opens the animation at its first pose with the physics reset there. `player.current` names what is playing. |
655
+ | `skeleton.findSlot('x').attachment = null` to hide a slot, or a second skeleton with slots emptied | `RigPlayerOptions.slots`, `player.slots`, `player.posedFrame(slots)` | A draw filter since 1.6.0 — the pose is the whole rig's; a clipping slot left out does not clip. See *Drawing some slots only*. |
656
+ | `state.setAnimation(1, 'smile', false)` with a mix, `addAnimation`, `setEmptyAnimation`, `addEmptyAnimation`, `getCurrent(track)` | `player.play(name, { track, loop, mix })`, `player.queue(name, { track, loop, mix, delay })`, `player.clear(track, { mix })`, `player.queueClear(track, { mix, delay })`, `player.entry(track)` | Since 1.5.0, rig-c's live tracks: the runtime's mixing at tolerance 0. Constraint, sequence, draw-order and path-deform timelines are not mixed and are refused on the tracks. See *Several tracks*. |
599
657
  | `state.update(delta)`, `state.apply(skeleton)`, `skeleton.update(delta)`, `skeleton.updateWorldTransform(Physics.update)`, `renderer.render(skeleton)` | `player.frame(dt)` | Or `player.advance(dt)` then `player.draw()`, to time the two apart. |
600
658
  | time scale (the caller's own, on the spine-core side) | `player.timeScale` | Multiplies every step. 0 holds the pose without re-posing it; a negative value is not stepped. |
601
659
  | holding a pose (the caller stopped advancing) | `player.pause()`, `player.resume()` | `frame` keeps drawing the held pose. |
602
660
  | moving to a time (the caller's own, on the spine-core side) | `player.seek(time)`, `RigPlayerOptions.seekStep`, `player.time` | A seek reopens the animation and steps forward in `seekStep` increments (1/60 s by default). Events and completes crossed on the way are not fired. |
603
- | events (the caller's own listener on the spine-core side) | `player.on('event', listener)`, `player.on('complete', listener)` | `'event'` hands a `RigEvent` (`name`, `time`, `int`, `float`, `string`); `'complete'` hands `{ animation }`. `on` returns a function that removes the listener. |
661
+ | events (the caller's own listener on the spine-core side) | `player.on('event', listener)`, `player.on('complete', listener)` | `'event'` hands a `RigEvent` (`name`, `time`, `int`, `float`, `string`, `track`); `'complete'` hands `{ animation, track }`. `on` returns a function that removes the listener. |
604
662
  | skin (set by the caller on its `Skeleton`) | `RigPlayerOptions.skin`, `player.skin` | A constructor option, and settable on a live player since 1.4.0: the pose re-resolves under the new skin and the track keeps its animation, loop and time (reopened and stepped there, as `seek` does). The names are in `ModelAssets.skins`. Without it the rig is posed with no skin set. |
605
663
  | `SpineHtmlRenderer` | `DomRenderer`, reached as `player.renderer` | In `mode: 'dom'`, the default. `mode: 'canvas'` is new and makes `player.renderer` a `CanvasRenderer`. |
606
664
  | `new SpineHtmlRenderer(root, regionImages)` | `new DomRenderer(root, regionImages, pages?)` | Only for drawing your own frames; `RigPlayer` constructs its renderer. `pages` is the page-image map the mesh tier samples (`ModelAssets.pageImages`). A hand-built `regionImages` map is still accepted. |
@@ -634,8 +692,6 @@ export, for which 1.0.0 declares nothing:
634
692
  - **One unpacked atlas shared by different skeletons.** A document is one rig, and each
635
693
  `loadModel` cuts its own regions and owns its own blob URLs. Sharing is per rig: one
636
694
  load, several players.
637
- - **More than one track, mixing between animations, or queueing one after another.**
638
- `RigPlayer` declares one track; `play` reopens it at the animation's first pose.
639
695
  - **Changing one slot from code** (its attachment, its colour). `RigPlayer` declares only
640
696
  the whole-rig `color`. The frame record is a plain object, so a caller that draws its
641
697
  own frames through `DomRenderer.render` or `CanvasRenderer.render` decides what is in
package/dist/index.d.ts CHANGED
@@ -2,6 +2,6 @@ export { type CanvasBackend, CanvasRenderer, type CanvasViewport } from './Canva
2
2
  export { DomRenderer, type MeshBackend } from './DomRenderer.js';
3
3
  export { type PageLayout, type PageRegion, type RegionEncoding, type RegionImage, revokeRegions, type UnpackRegionsOptions, unpackRegions } from './DomTexture.js';
4
4
  export { type LoadModelOptions, loadModel, type ModelAssets, type ModelDocument, type RegionLoading } from './loadModel.js';
5
- export { type AdjustableBones, type BoneAdjust, type BoneLocals, type BoneWorld, type PoseBounds, type RenderMode, type RigEvent, RigPlayer, type RigPlayerOptions } from './player.js';
5
+ export { type AdjustableBones, type BoneAdjust, type BoneLocals, type BoneWorld, type PlayOptions, type PoseBounds, type QueueOptions, type RenderMode, type RigComplete, type RigEvent, RigPlayer, type RigPlayerOptions, type SlotFilter, type TrackEntry } from './player.js';
6
6
  export type { BlendMode, PosedClip, PosedFrame, PosedMesh, PosedRegion, PosedSlot, } from './posedFrame.js';
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACnK,OAAO,EAAE,KAAK,gBAAgB,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC5H,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACxL,YAAY,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,WAAW,EACX,SAAS,GACV,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACnK,OAAO,EAAE,KAAK,gBAAgB,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC5H,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AACjR,YAAY,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,WAAW,EACX,SAAS,GACV,MAAM,iBAAiB,CAAC"}