cute-cube 0.1.0 → 0.1.1

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
@@ -2,6 +2,10 @@
2
2
 
3
3
  Framework-agnostic sprite character with named animation states, built on [PixiJS](https://pixijs.com/). Optional Vue 3 and React bindings are published as subpath exports.
4
4
 
5
+ ## Preview
6
+
7
+ ![cute-cube demo preview](assets/cube.gif)
8
+
5
9
  ## Install
6
10
 
7
11
  Install `cute-cube` and its required peer dependency `pixi.js`. Add Vue or React only if you use those bindings.
@@ -82,18 +86,4 @@ React (`CharacterView` component):
82
86
  import { CharacterView } from "cute-cube/react";
83
87
  ```
84
88
 
85
- See `src/index.ts` and the `demo/` app for concrete examples.
86
-
87
- ## Publishing (maintainers)
88
-
89
- Public JavaScript packages are published to the **npm registry** (`https://registry.npmjs.org/`). Yarn, pnpm, and Bun all consume that same registry for public packages—there is no separate “Yarn package” registry for open-source libraries.
90
-
91
- 1. **Account** — Create an account on [npmjs.com](https://www.npmjs.com/) and verify your email.
92
- 2. **Login** — Run `npm login` (or `yarn npm login` in Yarn Berry) and follow the prompts.
93
- 3. **Build** — `npm run build` (or rely on `prepublishOnly`, which runs the build before publish).
94
- 4. **Name & version** — Ensure `package.json` `name` is available on npm and bump `version` per [semver](https://semver.org/).
95
- 5. **Publish** — From the package root:
96
- - **npm:** `npm publish` (use `npm publish --access public` for scoped packages like `@org/pkg`).
97
- - **Yarn (Berry):** `yarn npm publish` (same registry as npm).
98
-
99
- After publish, users install with any client (`npm`, `yarn`, `pnpm`, `bun`) using the instructions above.
89
+ See `src/index.ts` and the `demo/` app for concrete examples.
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/dist/index.cjs CHANGED
@@ -280,6 +280,19 @@ function joinBase(baseUrl, frame) {
280
280
  const base = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
281
281
  return new URL(frame, base).href;
282
282
  }
283
+ function collectManifestTextureUrls(flatStates, baseUrl) {
284
+ const seen = /* @__PURE__ */ new Set();
285
+ for (const cfg of Object.values(flatStates)) {
286
+ if (isGridSheetAnimation(cfg)) {
287
+ seen.add(joinBase(baseUrl, cfg.gridSheet.image));
288
+ } else {
289
+ for (const f of cfg.frames) {
290
+ seen.add(joinBase(baseUrl, f));
291
+ }
292
+ }
293
+ }
294
+ return [...seen];
295
+ }
283
296
  function validateGridSheetAgainstTexture(texWidth, texHeight, g) {
284
297
  const { frameWidth, frameHeight, columns, frameCount } = g;
285
298
  if (frameCount < 1) {
@@ -431,6 +444,27 @@ var CharacterPlayer = class {
431
444
  const start = this.currentFlatKey;
432
445
  await this.mountState(start);
433
446
  }
447
+ /**
448
+ * Fetches every texture URL from the manifest into Pixi’s asset cache so later clip changes
449
+ * reuse cached data instead of waiting on the network. Safe to call after {@link init}; does not
450
+ * change the current animation. Failed loads are ignored unless `debug` is enabled (then failures
451
+ * are logged with `console.debug`).
452
+ */
453
+ async preloadAllAssets() {
454
+ if (this.destroyed) {
455
+ return;
456
+ }
457
+ const urls = collectManifestTextureUrls(this.flatStates, this.baseUrl);
458
+ const results = await Promise.allSettled(urls.map((url) => pixi_js.Assets.load(url)));
459
+ if (!this.debug) {
460
+ return;
461
+ }
462
+ results.forEach((r, i) => {
463
+ if (r.status === "rejected") {
464
+ console.debug("[CharacterPlayer] preload failed", urls[i], r.reason);
465
+ }
466
+ });
467
+ }
434
468
  /**
435
469
  * Current clip key. Layered manifests use `characterState/action` (e.g. `neutral/idle`);
436
470
  * during a character-state transition the internal `__tr__/from/to` key may be returned.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/manifest.ts","../src/core/CharacterPlayer.ts"],"names":["Texture","Rectangle","Application","Container","Assets","AnimatedSprite"],"mappings":"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","file":"index.cjs","sourcesContent":["/** Uniform grid spritesheet: one image, equal-sized cells. */\nexport type GridSheetOrder = \"row-major\" | \"column-major\";\nexport interface GridSheetConfig {\n /** Image path relative to `baseUrl`. */\n image: string;\n frameWidth: number;\n frameHeight: number;\n /** Number of columns in the grid (>= 1). */\n columns: number;\n /**\n * Frames to play (may leave unused cells at the end of the grid).\n * Determines how the linear `frameCount` sequence maps onto the 2D grid.\n */\n frameCount: number;\n /**\n * How frames are read out of the grid.\n * - Default: `row-major` (left-to-right, then top-to-bottom)\n * - `column-major` (top-to-bottom, then left-to-right)\n */\n order?: GridSheetOrder;\n}\n\n/** One named animation (e.g. idle, talk): either per-frame files or a single grid sheet. */\nexport type AnimationStateConfig = AnimationStateFramesConfig | AnimationStateGridSheetConfig;\n\nexport interface AnimationStateFramesConfig {\n /** Frame filenames relative to `baseUrl` (e.g. `frame_001.png`). */\n frames: string[];\n fps: number;\n loop: boolean;\n}\n\nexport interface AnimationStateGridSheetConfig {\n gridSheet: GridSheetConfig;\n fps: number;\n loop: boolean;\n}\n\nexport function isGridSheetAnimation(\n cfg: AnimationStateConfig,\n): cfg is AnimationStateGridSheetConfig {\n return \"gridSheet\" in cfg && cfg.gridSheet !== undefined;\n}\n\n/** Character mood/state (e.g. neutral, sad) paired with an action (idle, talk). */\nexport interface CharacterPose {\n characterState: string;\n action: string;\n}\n\n/**\n * Legacy manifest: flat clip names (`idle`, `talk`, …) each mapping to one sprite.\n */\nexport interface LegacyCharacterManifest {\n states: Record<string, AnimationStateConfig>;\n /** Defaults to the first key in `states` if omitted. */\n defaultState?: string;\n}\n\n/**\n * Layered manifest: actions grouped under character states, plus optional one-shot\n * transition clips between character states (`transitions[from][to]`).\n */\nexport interface LayeredCharacterManifest {\n characterStates: Record<string, { actions: Record<string, AnimationStateConfig> }>;\n /** Directed edges: play once (`loop: false` in each config) when switching `from` → `to`. */\n transitions: Record<string, Record<string, AnimationStateConfig>>;\n /** Defaults to the first character state and its first action if omitted. */\n defaultPose?: CharacterPose;\n}\n\n/** Union of supported manifest shapes. */\nexport type CharacterManifest = LegacyCharacterManifest | LayeredCharacterManifest;\n\nexport function isLayeredManifest(\n manifest: CharacterManifest,\n): manifest is LayeredCharacterManifest {\n return (\n \"characterStates\" in manifest &&\n manifest.characterStates !== undefined &&\n Object.keys(manifest.characterStates).length > 0\n );\n}\n\nexport interface CharacterPlayerOptions {\n /** Element that will receive the canvas (and optional resize observer). */\n container: HTMLElement;\n /** Manifest defining clips (flat or layered). */\n manifest: CharacterManifest;\n /** Base URL for frame files (trailing slash optional). */\n baseUrl: string;\n /** Crossfade duration when changing clips; `0` = instant swap. Default 200. */\n transitionMs?: number;\n /**\n * Legacy: initial flat state name. Ignored when `initialPose` is set or when using\n * a layered manifest with `defaultPose`.\n */\n initialState?: string;\n /** Layered: initial pose; overrides `initialState` when set. */\n initialPose?: CharacterPose;\n /** Extra scale factor after fitting to the container (default 1). */\n fitPadding?: number;\n /**\n * Optional rendered size in CSS pixels (sprite texture dimensions × scale).\n * When either is set, scaling follows these constraints instead of fitting the container;\n * the sprite stays centered in the container and may extend past its edges.\n * - Only `characterWidth`: scale so width matches.\n * - Only `characterHeight`: scale so height matches.\n * - Both: preserve aspect ratio and fit inside the box (contain).\n */\n characterWidth?: number;\n characterHeight?: number;\n /**\n * When true, `setState` / `setPose` waits until the current clip finishes one loop (`loop: true`)\n * or ends (`loop: false`) before crossfading. Default false: apply the new clip as soon as the\n * request is processed (still queued while a crossfade or character-state transition clip runs).\n */\n queueStateUntilCycleEnd?: boolean;\n /**\n * When true, emit `console.debug` for pose changes, character-state transitions, and edge lookup.\n */\n debug?: boolean;\n}\n","import type {\n AnimationStateConfig,\n AnimationStateGridSheetConfig,\n CharacterManifest,\n CharacterPose,\n GridSheetConfig,\n GridSheetOrder,\n LayeredCharacterManifest,\n LegacyCharacterManifest,\n} from \"./types.js\";\nimport { isLayeredManifest } from \"./types.js\";\n\n/** Separator for flat keys: `characterState/action` (e.g. `neutral/idle`). */\nexport const POSE_KEY_SEPARATOR = \"/\";\n\n/** `frame_001.png` … `frame_181.png` */\nexport function idleFrameNames(count = 181): string[] {\n return Array.from({ length: count }, (_, i) => {\n const n = String(i + 1).padStart(3, \"0\");\n return `frame_${n}.png`;\n });\n}\n\n/** `idle/frame_001.png` … when `subdir` is `idle`; use with `baseUrl` at the assets root. */\nexport function framePaths(subdir: string, count: number): string[] {\n const prefix = subdir.replace(/\\/$/, \"\");\n return Array.from({ length: count }, (_, i) => {\n const n = String(i + 1).padStart(3, \"0\");\n return `${prefix}/frame_${n}.png`;\n });\n}\n\nexport function poseToKey(pose: CharacterPose): string {\n return `${pose.characterState}${POSE_KEY_SEPARATOR}${pose.action}`;\n}\n\n/** Parse `neutral/idle` into a pose; returns null if not a layered key. */\nexport function keyToPose(key: string): CharacterPose | null {\n const i = key.indexOf(POSE_KEY_SEPARATOR);\n if (i <= 0 || i === key.length - 1) {\n return null;\n }\n return {\n characterState: key.slice(0, i),\n action: key.slice(i + POSE_KEY_SEPARATOR.length),\n };\n}\n\n/** Internal flat key for a one-shot character-state transition clip. */\nexport function transitionFlatKey(fromCharacterState: string, toCharacterState: string): string {\n return `__tr__${POSE_KEY_SEPARATOR}${fromCharacterState}${POSE_KEY_SEPARATOR}${toCharacterState}`;\n}\n\nexport function isTransitionFlatKey(key: string): boolean {\n return key.startsWith(`__tr__${POSE_KEY_SEPARATOR}`);\n}\n\n/**\n * Merge layered character actions and transition clips into one flat `states` map for the player.\n */\nexport function flattenLayeredManifest(manifest: LayeredCharacterManifest): Record<\n string,\n AnimationStateConfig\n> {\n const states: Record<string, AnimationStateConfig> = {};\n for (const [characterState, { actions }] of Object.entries(manifest.characterStates)) {\n for (const [action, cfg] of Object.entries(actions)) {\n states[poseToKey({ characterState, action })] = cfg;\n }\n }\n if (manifest.transitions) {\n for (const [from, toMap] of Object.entries(manifest.transitions)) {\n for (const [to, cfg] of Object.entries(toMap)) {\n states[transitionFlatKey(from, to)] = cfg;\n }\n }\n }\n return states;\n}\n\n/** Resolve default pose for a layered manifest (deterministic: first entry keys). */\nexport function defaultPoseForLayered(manifest: LayeredCharacterManifest): CharacterPose {\n if (manifest.defaultPose) {\n return manifest.defaultPose;\n }\n const csKeys = Object.keys(manifest.characterStates);\n if (csKeys.length === 0) {\n throw new Error(\"manifest.characterStates must not be empty\");\n }\n const characterState = csKeys[0];\n const actionKeys = Object.keys(manifest.characterStates[characterState].actions);\n if (actionKeys.length === 0) {\n throw new Error(`manifest.characterStates[\"${characterState}\"].actions must not be empty`);\n }\n return { characterState, action: actionKeys[0] };\n}\n\n/** Build a single flat `states` map for CharacterPlayer from any manifest shape. */\nexport function manifestToFlatStates(manifest: CharacterManifest): Record<string, AnimationStateConfig> {\n if (isLayeredManifest(manifest)) {\n return flattenLayeredManifest(manifest);\n }\n return manifest.states;\n}\n\n/** Default manifest: `idle` and `talk` under distinct asset folders (legacy flat). */\nexport function createDefaultManifest(): LegacyCharacterManifest {\n return {\n defaultState: \"idle\",\n states: {\n idle: {\n frames: framePaths(\"idle\", 181),\n fps: 32,\n loop: true,\n },\n talk: {\n frames: framePaths(\"talk\", 90),\n fps: 32,\n loop: true,\n },\n },\n };\n}\n\n/** Frame counts for packaged sad demo assets under `assets/sheets/` (must match PNG layout). */\nexport const SAD_DEMO_FRAMES = {\n /**\n * `neutral_to_sad.png` is 5120×3830 → 10×10 cells @ 512×383; only **91** frames are drawn\n * (9 full rows + 1 cell in row 10). The last 9 cells in the bottom row are empty—do not play them.\n */\n transitionNeutralToSad: 91,\n /** `sad_to_neutral.png` is 4608×3064 → 9×8 cells @ 512×383 (66 frames; last row partial). */\n transitionSadToNeutral: 66,\n sadIdle: 149,\n sadTalk: 126,\n /** `neutral_click_512.png` is 3072×2298 → 6×6 cells @ 512×383 (36 frames). */\n neutralClick: 36,\n /**\n * `sad_click_512.png` is 4608×3447 → 9×9 grid @ 512×383; only **75** frames have content\n * (last 6 cells in row-major order are empty padding—do not play them).\n */\n sadClick: 75,\n /**\n * `sad_thinking_512.png` is 5632×3830 → 11×10 grid @ 512×383; **105** frames drawn\n * (last 5 cells empty—avoids blink when looping).\n */\n sadThinking: 105,\n /**\n * `neutral_thinking_512.png` is 6144×4213 → 12×11 grid @ 512×383; **122** frames drawn\n * (last 10 cells empty—avoids blink when looping).\n */\n neutralThinking: 122,\n /**\n * `sad_celebrating_512.png` is 6144×4213 → 12×11 grid @ 512×383; **122** frames drawn\n * (last 10 cells empty).\n */\n sadCelebrating: 122,\n /**\n * `neutral_celebrating_512.png` is 6656×4596 → 13×12 grid @ 512×383; **150** frames drawn\n * (last 6 cells empty).\n */\n neutralCelebrating: 150,\n} as const;\n\n/**\n * Uniform grid parameters per `assets/sheets/*.png`, derived from image pixel size and\n * {@link SAD_DEMO_FRAMES} (row-major cells; unused trailing cells are allowed).\n */\nexport const SAD_DEMO_GRID_SHEETS = {\n neutralIdle: {\n image: \"sheets/neutral_idle_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 14,\n frameCount: 181,\n },\n neutralTalk: {\n image: \"sheets/neutral_talk_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 10,\n frameCount: 93,\n },\n neutralClick: {\n image: \"sheets/neutral_click_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 6,\n frameCount: SAD_DEMO_FRAMES.neutralClick,\n },\n sadIdle: {\n image: \"sheets/sad_idle_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 13,\n frameCount: SAD_DEMO_FRAMES.sadIdle,\n },\n sadTalk: {\n image: \"sheets/sad_talk_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 12,\n frameCount: SAD_DEMO_FRAMES.sadTalk,\n },\n neutralToSad: {\n image: \"sheets/neutral_to_sad.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 10,\n frameCount: SAD_DEMO_FRAMES.transitionNeutralToSad,\n },\n sadToNeutral: {\n image: \"sheets/sad_to_neutral.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 9,\n frameCount: SAD_DEMO_FRAMES.transitionSadToNeutral,\n },\n sadClick: {\n image: \"sheets/sad_click_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 9,\n frameCount: SAD_DEMO_FRAMES.sadClick,\n },\n sadThinking: {\n image: \"sheets/sad_thinking_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 11,\n frameCount: SAD_DEMO_FRAMES.sadThinking,\n },\n neutralThinking: {\n image: \"sheets/neutral_thinking_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 12,\n frameCount: SAD_DEMO_FRAMES.neutralThinking,\n },\n sadCelebrating: {\n image: \"sheets/sad_celebrating_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 12,\n frameCount: SAD_DEMO_FRAMES.sadCelebrating,\n },\n neutralCelebrating: {\n image: \"sheets/neutral_celebrating_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 13,\n frameCount: SAD_DEMO_FRAMES.neutralCelebrating,\n },\n} as const;\n\nfunction sadDemoGridClip(\n sheet: (typeof SAD_DEMO_GRID_SHEETS)[keyof typeof SAD_DEMO_GRID_SHEETS],\n fps: number,\n loop: boolean,\n): AnimationStateGridSheetConfig {\n const gridSheet: GridSheetConfig = {\n image: sheet.image,\n frameWidth: sheet.frameWidth,\n frameHeight: sheet.frameHeight,\n columns: sheet.columns,\n frameCount: sheet.frameCount,\n };\n if (\"order\" in sheet && sheet.order !== undefined && sheet.order !== null) {\n gridSheet.order = sheet.order as GridSheetOrder;\n }\n return {\n gridSheet,\n fps,\n loop,\n };\n}\n\n/**\n * Layered manifest: neutral, sad, and one-shot transitions using one PNG grid sheet per clip\n * under `assets/sheets/` (see {@link SAD_DEMO_GRID_SHEETS}).\n */\nexport function createSadDemoManifest(): LayeredCharacterManifest {\n return {\n defaultPose: { characterState: \"neutral\", action: \"idle\" },\n characterStates: {\n neutral: {\n actions: {\n idle: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.neutralIdle, 32, true),\n talk: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.neutralTalk, 32, true),\n click: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.neutralClick, 50, false),\n thinking: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.neutralThinking, 32, true),\n celebrating: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.neutralCelebrating, 32, false),\n },\n },\n sad: {\n actions: {\n idle: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.sadIdle, 32, true),\n talk: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.sadTalk, 32, true),\n click: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.sadClick, 50, false),\n thinking: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.sadThinking, 32, true),\n celebrating: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.sadCelebrating, 32, false),\n },\n },\n },\n transitions: {\n neutral: {\n sad: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.neutralToSad, 32, false),\n },\n sad: {\n neutral: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.sadToNeutral, 32, false),\n },\n },\n };\n}\n","import { AnimatedSprite, Application, Assets, Container, Rectangle, Texture } from \"pixi.js\";\nimport type {\n AnimationStateConfig,\n CharacterManifest,\n CharacterPlayerOptions,\n CharacterPose,\n GridSheetConfig,\n LayeredCharacterManifest,\n LegacyCharacterManifest,\n} from \"../types.js\";\nimport { isGridSheetAnimation, isLayeredManifest } from \"../types.js\";\nimport {\n defaultPoseForLayered,\n isTransitionFlatKey,\n keyToPose,\n manifestToFlatStates,\n POSE_KEY_SEPARATOR,\n poseToKey,\n transitionFlatKey,\n} from \"../manifest.js\";\n\nfunction joinBase(baseUrl: string, frame: string): string {\n const base = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n return new URL(frame, base).href;\n}\n\nfunction validateGridSheetAgainstTexture(\n texWidth: number,\n texHeight: number,\n g: GridSheetConfig,\n): void {\n const { frameWidth, frameHeight, columns, frameCount } = g;\n if (frameCount < 1) {\n throw new Error(`gridSheet.frameCount must be >= 1, got ${frameCount}`);\n }\n if (columns < 1) {\n throw new Error(`gridSheet.columns must be >= 1, got ${columns}`);\n }\n if (frameWidth <= 0 || frameHeight <= 0) {\n throw new Error(\n `gridSheet frameWidth and frameHeight must be positive, got ${frameWidth}x${frameHeight}`,\n );\n }\n const rows = Math.ceil(frameCount / columns);\n const minW = columns * frameWidth;\n const minH = rows * frameHeight;\n if (texWidth < minW) {\n throw new Error(\n `Spritesheet width ${texWidth}px is smaller than grid width ${minW}px (${columns} columns × ${frameWidth}px)`,\n );\n }\n if (texHeight < minH) {\n throw new Error(\n `Spritesheet height ${texHeight}px is smaller than grid height ${minH}px (${rows} rows × ${frameHeight}px for ${frameCount} frames)`,\n );\n }\n}\n\nfunction texturesFromGridSheet(base: Texture, g: GridSheetConfig): Texture[] {\n const { frameWidth, frameHeight, columns, frameCount, order } = g;\n const resolvedOrder = order ?? \"row-major\";\n // The physical grid row count is derived from how many linear frames we expose.\n const rows = Math.ceil(frameCount / columns);\n const textures: Texture[] = [];\n const source = base.source;\n for (let i = 0; i < frameCount; i++) {\n const col = resolvedOrder === \"column-major\" ? Math.floor(i / rows) : i % columns;\n const row = resolvedOrder === \"column-major\" ? i % rows : Math.floor(i / columns);\n const x = col * frameWidth;\n const y = row * frameHeight;\n textures.push(\n new Texture({\n source,\n frame: new Rectangle(x, y, frameWidth, frameHeight),\n }),\n );\n }\n return textures;\n}\n\nexport class CharacterPlayer {\n readonly container: HTMLElement;\n private readonly manifest: CharacterManifest;\n private readonly flatStates: Record<string, AnimationStateConfig>;\n private readonly layered: boolean;\n private readonly transitionMap: Record<string, Record<string, AnimationStateConfig>> | null;\n private readonly baseUrl: string;\n private readonly transitionMs: number;\n private readonly fitPadding: number;\n private characterWidth: number | undefined;\n private characterHeight: number | undefined;\n private readonly queueStateUntilCycleEnd: boolean;\n private readonly debug: boolean;\n\n private app: Application | null = null;\n private root: Container | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private currentSprite: AnimatedSprite | null = null;\n\n /** Current clip key: legacy `idle` / `talk`, layered `neutral/idle`, or internal `__tr__/a/b`. */\n private currentFlatKey: string | null = null;\n /** Logical pose when `layered`; unchanged while a transition clip plays. */\n private currentPose: CharacterPose | null = null;\n\n private transitioning = false;\n private fromSprite: AnimatedSprite | null = null;\n private toSprite: AnimatedSprite | null = null;\n private transitionProgress = 0;\n private transitionTargetFlatKey: string | null = null;\n private pendingFlatKey: string | null = null;\n private transitionUpdateBound = this.onTransitionTick.bind(this);\n\n private deferredTargetFlatKey: string | null = null;\n private waitingForCycleEnd = false;\n\n /** After a one-shot transition clip mounts, crossfade into this pose key. */\n private pendingAfterTransitionClip: { targetKey: string } | null = null;\n\n private textureWidth = 512;\n private textureHeight = 512;\n\n /** Invalidates in-flight `playOneShotAction` completion handlers after a new one-shot or `destroy()`. */\n private oneShotCompletionToken = 0;\n private destroyed = false;\n\n constructor(options: CharacterPlayerOptions) {\n this.container = options.container;\n this.manifest = options.manifest;\n this.flatStates = manifestToFlatStates(options.manifest);\n this.layered = isLayeredManifest(options.manifest);\n this.transitionMap = isLayeredManifest(options.manifest)\n ? (options.manifest as LayeredCharacterManifest).transitions\n : null;\n this.baseUrl = options.baseUrl;\n this.transitionMs = options.transitionMs ?? 200;\n this.fitPadding = options.fitPadding ?? 1;\n this.characterWidth = options.characterWidth;\n this.characterHeight = options.characterHeight;\n this.queueStateUntilCycleEnd = options.queueStateUntilCycleEnd ?? false;\n this.debug = options.debug ?? false;\n\n const keys = Object.keys(this.flatStates);\n if (keys.length === 0) {\n throw new Error(\"CharacterPlayer: manifest must define at least one clip\");\n }\n\n if (this.layered) {\n const pose =\n options.initialPose ??\n (options.manifest as LayeredCharacterManifest).defaultPose ??\n defaultPoseForLayered(options.manifest as LayeredCharacterManifest);\n const k = poseToKey(pose);\n if (!this.flatStates[k]) {\n throw new Error(`CharacterPlayer: unknown initial pose \"${k}\"`);\n }\n this.currentPose = pose;\n this.currentFlatKey = k;\n } else {\n if (options.initialPose !== undefined) {\n throw new Error(\"CharacterPlayer: initialPose is only valid with a layered manifest\");\n }\n const legacy = options.manifest as LegacyCharacterManifest;\n const def =\n options.initialState ?? legacy.defaultState ?? Object.keys(legacy.states)[0];\n if (!this.flatStates[def]) {\n throw new Error(`CharacterPlayer: unknown initial state \"${def}\"`);\n }\n this.currentFlatKey = def;\n }\n\n this.logDebug(\"constructor\", { layered: this.layered, initial: this.currentFlatKey });\n }\n\n /** Create Pixi app, load first clip, append canvas. Call once. */\n async init(): Promise<void> {\n if (this.app) {\n return;\n }\n\n const app = new Application();\n await app.init({\n resizeTo: this.container,\n backgroundAlpha: 0,\n antialias: true,\n autoDensity: true,\n resolution: typeof window !== \"undefined\" ? window.devicePixelRatio : 1,\n preference: \"webgl\",\n });\n\n this.app = app;\n this.container.appendChild(app.canvas as HTMLCanvasElement);\n\n this.resizeObserver = new ResizeObserver(() => {\n const resize = (app as unknown as { resize?: () => void }).resize;\n resize?.call(app);\n this.layout();\n });\n this.resizeObserver.observe(this.container);\n\n app.renderer.on(\"resize\", () => this.layout());\n\n const root = new Container();\n this.root = root;\n app.stage.addChild(root);\n\n const start = this.currentFlatKey!;\n await this.mountState(start);\n }\n\n /**\n * Current clip key. Layered manifests use `characterState/action` (e.g. `neutral/idle`);\n * during a character-state transition the internal `__tr__/from/to` key may be returned.\n */\n getState(): string | null {\n return this.currentFlatKey;\n }\n\n /** Logical pose for layered manifests; `null` for legacy flat manifests. */\n getPose(): CharacterPose | null {\n return this.currentPose;\n }\n\n /**\n * Set explicit character size in CSS pixels (see `CharacterPlayerOptions.characterWidth` /\n * `characterHeight`). Pass no arguments or `undefined` for both dimensions to restore\n * scaling that fits the container (still multiplied by `fitPadding`).\n */\n setCharacterSize(width?: number, height?: number): void {\n this.characterWidth = width;\n this.characterHeight = height;\n this.layout();\n }\n\n /** Switch pose (layered manifests only). */\n async setPose(pose: CharacterPose): Promise<void> {\n if (!this.layered) {\n throw new Error(\"CharacterPlayer: setPose requires a layered manifest\");\n }\n this.validatePose(pose);\n const key = poseToKey(pose);\n await this.applySetFlatKey(key);\n }\n\n /** Switch animation clip; crossfades when `transitionMs` > 0. */\n async setState(name: string): Promise<void> {\n const key = this.resolveSetStateName(name);\n await this.applySetFlatKey(key);\n }\n\n /**\n * Play a one-shot action clip immediately: aborts crossfades, cycle queues, and transition clips,\n * then returns to `{ characterState, action: \"idle\" }` when the clip ends. Layered manifests only;\n * requires a matching clip and playback context for that character state (including a\n * `from`→… transition clip when `from` matches).\n */\n async playOneShotAction(pose: CharacterPose): Promise<void> {\n if (!this.layered) {\n throw new Error(\"CharacterPlayer: playOneShotAction requires a layered manifest\");\n }\n this.validatePose(pose);\n const actionKey = poseToKey(pose);\n if (!this.flatStates[actionKey]) {\n throw new Error(`CharacterPlayer: manifest has no \"${actionKey}\" clip`);\n }\n const cfg = this.flatStates[actionKey]!;\n if (cfg.loop) {\n throw new Error(\n `CharacterPlayer: playOneShotAction expects a non-looping clip; \"${actionKey}\" has loop: true`,\n );\n }\n if (!this.isCharacterStatePlaybackContext(pose.characterState)) {\n throw new Error(\n `CharacterPlayer: playOneShotAction only applies when playback matches character state \"${pose.characterState}\" (including a matching transition clip)`,\n );\n }\n if (!this.app || !this.root) {\n throw new Error(\"CharacterPlayer: playOneShotAction requires init() first\");\n }\n\n const token = ++this.oneShotCompletionToken;\n this.logDebug(\"playOneShotAction: start\", { token, actionKey });\n\n // Load textures while the current clip is still visible. `abortImmediatePlayback` clears the\n // stage; if we tore down first, the first trigger would show an empty canvas until `Assets.load`\n // finishes (subsequent runs hit the cache and barely flash).\n const incoming = await this.createSpriteForState(actionKey, { autoPlay: false });\n if (this.destroyed || token !== this.oneShotCompletionToken) {\n incoming.destroy({ texture: false, textureSource: false });\n return;\n }\n\n this.abortImmediatePlayback();\n if (!this.root) {\n incoming.destroy({ texture: false, textureSource: false });\n return;\n }\n\n this.attachSprite(incoming);\n incoming.gotoAndPlay(0);\n this.currentFlatKey = actionKey;\n this.syncPoseFromFlatKey();\n this.maybeAttachTransitionClipCompletion();\n\n if (this.destroyed || token !== this.oneShotCompletionToken) {\n return;\n }\n\n const sprite = this.currentSprite;\n if (!sprite) {\n return;\n }\n const idleKey = poseToKey({ characterState: pose.characterState, action: \"idle\" });\n\n const done = (): void => {\n sprite.onComplete = undefined;\n sprite.onLoop = undefined;\n if (this.destroyed) {\n return;\n }\n if (token !== this.oneShotCompletionToken) {\n this.logDebug(\"playOneShotAction: completion ignored (superseded)\", { token });\n return;\n }\n this.logDebug(\"playOneShotAction: complete -> idle\", { token, idleKey });\n void this.applyTransitionNow(idleKey);\n };\n\n sprite.onComplete = done;\n sprite.onLoop = undefined;\n }\n\n /**\n * Play the neutral `click` clip (see {@link playOneShotAction}).\n */\n async playNeutralClick(): Promise<void> {\n return this.playOneShotAction({ characterState: \"neutral\", action: \"click\" });\n }\n\n private resolveSetStateName(name: string): string {\n if (this.layered && (name === \"idle\" || name === \"talk\" || name === \"click\")) {\n return poseToKey({ characterState: \"neutral\", action: name });\n }\n return name;\n }\n\n /** True when the current clip is for `characterState` or a transition clip leaving that state. */\n private isCharacterStatePlaybackContext(characterState: string): boolean {\n const k = this.currentFlatKey;\n if (!k) {\n return false;\n }\n if (k.startsWith(`${characterState}/`)) {\n return true;\n }\n if (isTransitionFlatKey(k)) {\n const rest = k.slice(`__tr__${POSE_KEY_SEPARATOR}`.length);\n const i = rest.indexOf(POSE_KEY_SEPARATOR);\n if (i <= 0) {\n return false;\n }\n return rest.slice(0, i) === characterState;\n }\n return false;\n }\n\n /**\n * Stops and tears down active playback so a one-shot (e.g. click) can start immediately.\n * Clears crossfade ticker, transition sprites, cycle/queue state, and the current sprite.\n */\n private abortImmediatePlayback(): void {\n if (this.app) {\n this.app.ticker.remove(this.transitionUpdateBound);\n }\n this.transitioning = false;\n this.transitionProgress = 0;\n this.transitionTargetFlatKey = null;\n\n this.fromSprite?.stop();\n this.fromSprite?.destroy({ texture: false, textureSource: false });\n this.fromSprite = null;\n this.toSprite?.stop();\n this.toSprite?.destroy({ texture: false, textureSource: false });\n this.toSprite = null;\n\n this.clearCycleWait();\n this.deferredTargetFlatKey = null;\n this.waitingForCycleEnd = false;\n this.pendingFlatKey = null;\n this.pendingAfterTransitionClip = null;\n\n this.currentSprite?.stop();\n this.currentSprite?.destroy({ texture: false, textureSource: false });\n this.currentSprite = null;\n if (this.root) {\n this.root.removeChildren();\n }\n this.logDebug(\"abortImmediatePlayback\");\n }\n\n private validatePose(pose: CharacterPose): void {\n if (!isLayeredManifest(this.manifest)) {\n return;\n }\n const m = this.manifest as LayeredCharacterManifest;\n const block = m.characterStates[pose.characterState];\n if (!block?.actions[pose.action]) {\n throw new Error(\n `CharacterPlayer: unknown pose \"${pose.characterState}/${pose.action}\"`,\n );\n }\n }\n\n private logDebug(message: string, data?: Record<string, unknown>): void {\n if (this.debug) {\n // eslint-disable-next-line no-console\n console.debug(`[CharacterPlayer] ${message}`, data ?? \"\");\n }\n }\n\n private logWarn(message: string, data?: Record<string, unknown>): void {\n // eslint-disable-next-line no-console\n console.warn(`[CharacterPlayer] ${message}`, data ?? \"\");\n }\n\n /** True while a one-shot character-state transition clip is playing (after crossfade onto it). */\n private isPlayingTransitionClip(): boolean {\n return this.currentFlatKey !== null && isTransitionFlatKey(this.currentFlatKey);\n }\n\n private async applySetFlatKey(targetKey: string): Promise<void> {\n if (!this.flatStates[targetKey]) {\n throw new Error(`CharacterPlayer: unknown state \"${targetKey}\"`);\n }\n if (!this.app || !this.root) {\n this.currentFlatKey = targetKey;\n this.syncPoseFromFlatKey();\n this.logDebug(\"applySetFlatKey (no app)\", { targetKey });\n return;\n }\n\n if (this.isPlayingTransitionClip()) {\n this.pendingFlatKey = targetKey;\n this.logDebug(\"queue: pending while transition clip plays\", { targetKey });\n return;\n }\n\n if (this.transitioning) {\n this.pendingFlatKey = targetKey;\n this.logDebug(\"queue: pending while crossfading\", { targetKey });\n return;\n }\n\n if (this.waitingForCycleEnd) {\n if (targetKey === this.currentFlatKey) {\n this.clearCycleWait();\n return;\n }\n this.deferredTargetFlatKey = targetKey;\n this.logDebug(\"queue: deferred until cycle end\", { targetKey });\n return;\n }\n\n if (targetKey === this.currentFlatKey) {\n return;\n }\n\n if (!this.queueStateUntilCycleEnd) {\n await this.applyTransitionNow(targetKey);\n return;\n }\n\n this.deferredTargetFlatKey = targetKey;\n this.waitingForCycleEnd = true;\n this.attachCycleEndListener();\n }\n\n private syncPoseFromFlatKey(): void {\n if (!this.layered) {\n return;\n }\n const p = this.currentFlatKey ? keyToPose(this.currentFlatKey) : null;\n if (p) {\n this.currentPose = p;\n }\n }\n\n private async applyTransitionNow(targetFlatKey: string): Promise<void> {\n const fromPose = this.currentPose;\n const toPose = keyToPose(targetFlatKey);\n if (\n this.layered &&\n fromPose &&\n toPose &&\n fromPose.characterState !== toPose.characterState\n ) {\n this.logDebug(\"applyTransitionNow: character-state change\", {\n from: fromPose.characterState,\n to: toPose.characterState,\n });\n await this.applyCharacterStateChange(toPose, targetFlatKey);\n return;\n }\n if (this.transitionMs <= 0) {\n await this.swapInstant(targetFlatKey);\n } else {\n await this.beginCrossfade(targetFlatKey);\n }\n }\n\n private async applyCharacterStateChange(\n targetPose: CharacterPose,\n targetKey: string,\n ): Promise<void> {\n const from = this.currentPose!.characterState;\n const to = targetPose.characterState;\n const tr = this.transitionMap?.[from]?.[to];\n if (!tr) {\n this.logWarn(`no transition clip for character state \"${from}\" -> \"${to}\"; crossfading`, {\n from,\n to,\n });\n if (this.transitionMs <= 0) {\n await this.swapInstant(targetKey);\n this.syncPoseFromFlatKey();\n } else {\n await this.beginCrossfade(targetKey);\n }\n return;\n }\n const trKey = transitionFlatKey(from, to);\n this.logDebug(\"play transition clip then target\", { trKey, targetKey });\n this.pendingAfterTransitionClip = { targetKey };\n await this.applyTransitionNow(trKey);\n }\n\n private clearCycleWait(): void {\n const sprite = this.currentSprite;\n if (sprite) {\n sprite.onLoop = undefined;\n sprite.onComplete = undefined;\n }\n this.deferredTargetFlatKey = null;\n this.waitingForCycleEnd = false;\n }\n\n private attachCycleEndListener(): void {\n const sprite = this.currentSprite;\n if (!sprite) {\n void this.finishDeferredAndTransition();\n return;\n }\n const stateName = this.currentFlatKey;\n if (!stateName) {\n void this.finishDeferredAndTransition();\n return;\n }\n const cfg = this.flatStates[stateName];\n if (sprite.totalFrames <= 1) {\n void this.finishDeferredAndTransition();\n return;\n }\n if (!cfg.loop && !sprite.playing) {\n void this.finishDeferredAndTransition();\n return;\n }\n\n const done = (): void => {\n if (!this.waitingForCycleEnd) {\n return;\n }\n void this.finishDeferredAndTransition();\n };\n\n if (cfg.loop) {\n sprite.onLoop = done;\n sprite.onComplete = undefined;\n } else {\n sprite.onComplete = done;\n sprite.onLoop = undefined;\n }\n }\n\n private async finishDeferredAndTransition(): Promise<void> {\n const sprite = this.currentSprite;\n if (sprite) {\n sprite.onLoop = undefined;\n sprite.onComplete = undefined;\n }\n const target = this.deferredTargetFlatKey;\n this.deferredTargetFlatKey = null;\n this.waitingForCycleEnd = false;\n if (!target || target === this.currentFlatKey) {\n return;\n }\n await this.applyTransitionNow(target);\n }\n\n /** Returns true if we scheduled waiting for a transition clip to finish (skip processing crossfade queue). */\n private maybeAttachTransitionClipCompletion(): boolean {\n if (\n !this.pendingAfterTransitionClip ||\n !this.currentFlatKey ||\n !isTransitionFlatKey(this.currentFlatKey)\n ) {\n return false;\n }\n const { targetKey } = this.pendingAfterTransitionClip;\n this.pendingAfterTransitionClip = null;\n this.attachTransitionClipCompletion(targetKey);\n return true;\n }\n\n private attachTransitionClipCompletion(targetKey: string): void {\n const sprite = this.currentSprite;\n if (!sprite) {\n void this.finishCharacterTransitionChain(targetKey);\n return;\n }\n const cfg = this.flatStates[this.currentFlatKey!];\n if (!cfg) {\n void this.finishCharacterTransitionChain(targetKey);\n return;\n }\n this.logDebug(\"attachTransitionClipCompletion\", { targetKey, loop: cfg.loop });\n const done = (): void => {\n sprite.onComplete = undefined;\n sprite.onLoop = undefined;\n void this.finishCharacterTransitionChain(targetKey);\n };\n if (!cfg.loop) {\n sprite.onComplete = done;\n } else {\n done();\n }\n }\n\n private async finishCharacterTransitionChain(targetKey: string): Promise<void> {\n const use = this.pendingFlatKey ?? targetKey;\n this.pendingFlatKey = null;\n this.logDebug(\"transition clip complete -> target pose\", { targetKey, use });\n await this.applyTransitionNow(use);\n }\n\n private async swapInstant(name: string): Promise<void> {\n this.currentSprite?.stop();\n this.currentSprite?.destroy({ texture: false, textureSource: false });\n this.currentSprite = null;\n if (this.root) {\n this.root.removeChildren();\n }\n await this.mountState(name);\n this.currentFlatKey = name;\n this.syncPoseFromFlatKey();\n this.maybeAttachTransitionClipCompletion();\n }\n\n private async beginCrossfade(name: string): Promise<void> {\n const app = this.app!;\n const root = this.root!;\n\n const outgoing = this.currentSprite;\n if (!outgoing) {\n await this.swapInstant(name);\n return;\n }\n\n const incoming = await this.createSpriteForState(name);\n incoming.alpha = 0;\n root.addChild(incoming);\n\n this.fromSprite = outgoing;\n this.toSprite = incoming;\n this.transitionTargetFlatKey = name;\n this.transitioning = true;\n this.transitionProgress = 0;\n\n app.ticker.add(this.transitionUpdateBound);\n }\n\n private onTransitionTick(): void {\n if (!this.transitioning || !this.fromSprite || !this.toSprite || !this.app) {\n return;\n }\n const ms = this.app.ticker.deltaMS;\n this.transitionProgress += ms / this.transitionMs;\n const t = Math.min(1, this.transitionProgress);\n this.fromSprite.alpha = 1 - t;\n this.toSprite.alpha = t;\n\n if (t >= 1) {\n this.finishCrossfade();\n }\n }\n\n private finishCrossfade(): void {\n const app = this.app!;\n app.ticker.remove(this.transitionUpdateBound);\n\n this.fromSprite?.stop();\n this.fromSprite?.destroy({ texture: false, textureSource: false });\n this.fromSprite = null;\n\n const kept = this.toSprite!;\n this.toSprite = null;\n this.currentSprite = kept;\n this.transitioning = false;\n\n if (this.transitionTargetFlatKey) {\n this.currentFlatKey = this.transitionTargetFlatKey;\n this.syncPoseFromFlatKey();\n }\n this.transitionTargetFlatKey = null;\n\n const waitingOnTransitionClip = this.maybeAttachTransitionClipCompletion();\n\n if (!waitingOnTransitionClip) {\n const queued = this.pendingFlatKey;\n this.pendingFlatKey = null;\n\n if (queued && queued !== this.currentFlatKey) {\n void this.applySetFlatKey(queued);\n }\n }\n }\n\n private async mountState(name: string): Promise<void> {\n const sprite = await this.createSpriteForState(name);\n this.attachSprite(sprite);\n }\n\n private attachSprite(sprite: AnimatedSprite): void {\n this.root!.addChild(sprite);\n this.currentSprite = sprite;\n const tex = sprite.texture;\n this.textureWidth = tex.width;\n this.textureHeight = tex.height;\n this.layout();\n }\n\n private async createSpriteForState(\n name: string,\n options?: { autoPlay?: boolean },\n ): Promise<AnimatedSprite> {\n const cfg = this.flatStates[name];\n let textures: Texture[];\n\n if (isGridSheetAnimation(cfg)) {\n const g = cfg.gridSheet;\n const url = joinBase(this.baseUrl, g.image);\n const base = await Assets.load<Texture>(url);\n const tw = base.width;\n const th = base.height;\n validateGridSheetAgainstTexture(tw, th, g);\n if (this.debug) {\n console.debug(\n `[CharacterPlayer] gridSheet \"${name}\": image=${url} size=${tw}x${th} cell=${g.frameWidth}x${g.frameHeight} columns=${g.columns} frameCount=${g.frameCount}`,\n );\n }\n textures = texturesFromGridSheet(base, g);\n if (this.debug) {\n console.log(\"[FIX] gridSheet textures built\", {\n name,\n image: g.image,\n texturePx: `${tw}x${th}`,\n cellPx: `${g.frameWidth}x${g.frameHeight}`,\n columns: g.columns,\n frames: textures.length,\n order: g.order ?? \"row-major\",\n });\n }\n } else {\n const urls = cfg.frames.map((f) => joinBase(this.baseUrl, f));\n textures = await Promise.all(urls.map((url) => Assets.load<Texture>(url)));\n }\n\n const sprite = new AnimatedSprite({\n textures,\n animationSpeed: cfg.fps / 60,\n loop: cfg.loop,\n autoPlay: false,\n });\n sprite.anchor.set(0.5);\n if (options?.autoPlay !== false) {\n sprite.play();\n }\n return sprite;\n }\n\n private layout(): void {\n if (!this.app || !this.root) {\n return;\n }\n const w = this.app.screen.width;\n const h = this.app.screen.height;\n this.root.x = w / 2;\n this.root.y = h / 2;\n\n const tw = this.textureWidth;\n const th = this.textureHeight;\n if (tw <= 0 || th <= 0) {\n return;\n }\n const cw = this.characterWidth;\n const ch = this.characterHeight;\n let scale: number;\n if (cw !== undefined && ch !== undefined) {\n scale = Math.min(cw / tw, ch / th) * this.fitPadding;\n } else if (cw !== undefined) {\n scale = (cw / tw) * this.fitPadding;\n } else if (ch !== undefined) {\n scale = (ch / th) * this.fitPadding;\n } else {\n scale = Math.min(w / tw, h / th) * this.fitPadding;\n }\n this.root.scale.set(scale);\n }\n\n destroy(): void {\n this.destroyed = true;\n this.oneShotCompletionToken += 1;\n this.clearCycleWait();\n\n if (this.app) {\n this.app.ticker.remove(this.transitionUpdateBound);\n }\n\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n\n this.currentSprite?.destroy({ texture: false, textureSource: false });\n this.currentSprite = null;\n this.fromSprite?.destroy({ texture: false, textureSource: false });\n this.fromSprite = null;\n this.toSprite?.destroy({ texture: false, textureSource: false });\n this.toSprite = null;\n\n if (this.app) {\n this.app.destroy(true, { children: true, texture: false });\n this.app = null;\n }\n this.root = null;\n this.currentFlatKey = null;\n this.currentPose = null;\n this.pendingAfterTransitionClip = null;\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/manifest.ts","../src/core/CharacterPlayer.ts"],"names":["Texture","Rectangle","Application","Container","Assets","AnimatedSprite"],"mappings":"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","file":"index.cjs","sourcesContent":["/** Uniform grid spritesheet: one image, equal-sized cells. */\nexport type GridSheetOrder = \"row-major\" | \"column-major\";\nexport interface GridSheetConfig {\n /** Image path relative to `baseUrl`. */\n image: string;\n frameWidth: number;\n frameHeight: number;\n /** Number of columns in the grid (>= 1). */\n columns: number;\n /**\n * Frames to play (may leave unused cells at the end of the grid).\n * Determines how the linear `frameCount` sequence maps onto the 2D grid.\n */\n frameCount: number;\n /**\n * How frames are read out of the grid.\n * - Default: `row-major` (left-to-right, then top-to-bottom)\n * - `column-major` (top-to-bottom, then left-to-right)\n */\n order?: GridSheetOrder;\n}\n\n/** One named animation (e.g. idle, talk): either per-frame files or a single grid sheet. */\nexport type AnimationStateConfig = AnimationStateFramesConfig | AnimationStateGridSheetConfig;\n\nexport interface AnimationStateFramesConfig {\n /** Frame filenames relative to `baseUrl` (e.g. `frame_001.png`). */\n frames: string[];\n fps: number;\n loop: boolean;\n}\n\nexport interface AnimationStateGridSheetConfig {\n gridSheet: GridSheetConfig;\n fps: number;\n loop: boolean;\n}\n\nexport function isGridSheetAnimation(\n cfg: AnimationStateConfig,\n): cfg is AnimationStateGridSheetConfig {\n return \"gridSheet\" in cfg && cfg.gridSheet !== undefined;\n}\n\n/** Character mood/state (e.g. neutral, sad) paired with an action (idle, talk). */\nexport interface CharacterPose {\n characterState: string;\n action: string;\n}\n\n/**\n * Legacy manifest: flat clip names (`idle`, `talk`, …) each mapping to one sprite.\n */\nexport interface LegacyCharacterManifest {\n states: Record<string, AnimationStateConfig>;\n /** Defaults to the first key in `states` if omitted. */\n defaultState?: string;\n}\n\n/**\n * Layered manifest: actions grouped under character states, plus optional one-shot\n * transition clips between character states (`transitions[from][to]`).\n */\nexport interface LayeredCharacterManifest {\n characterStates: Record<string, { actions: Record<string, AnimationStateConfig> }>;\n /** Directed edges: play once (`loop: false` in each config) when switching `from` → `to`. */\n transitions: Record<string, Record<string, AnimationStateConfig>>;\n /** Defaults to the first character state and its first action if omitted. */\n defaultPose?: CharacterPose;\n}\n\n/** Union of supported manifest shapes. */\nexport type CharacterManifest = LegacyCharacterManifest | LayeredCharacterManifest;\n\nexport function isLayeredManifest(\n manifest: CharacterManifest,\n): manifest is LayeredCharacterManifest {\n return (\n \"characterStates\" in manifest &&\n manifest.characterStates !== undefined &&\n Object.keys(manifest.characterStates).length > 0\n );\n}\n\nexport interface CharacterPlayerOptions {\n /** Element that will receive the canvas (and optional resize observer). */\n container: HTMLElement;\n /** Manifest defining clips (flat or layered). */\n manifest: CharacterManifest;\n /** Base URL for frame files (trailing slash optional). */\n baseUrl: string;\n /** Crossfade duration when changing clips; `0` = instant swap. Default 200. */\n transitionMs?: number;\n /**\n * Legacy: initial flat state name. Ignored when `initialPose` is set or when using\n * a layered manifest with `defaultPose`.\n */\n initialState?: string;\n /** Layered: initial pose; overrides `initialState` when set. */\n initialPose?: CharacterPose;\n /** Extra scale factor after fitting to the container (default 1). */\n fitPadding?: number;\n /**\n * Optional rendered size in CSS pixels (sprite texture dimensions × scale).\n * When either is set, scaling follows these constraints instead of fitting the container;\n * the sprite stays centered in the container and may extend past its edges.\n * - Only `characterWidth`: scale so width matches.\n * - Only `characterHeight`: scale so height matches.\n * - Both: preserve aspect ratio and fit inside the box (contain).\n */\n characterWidth?: number;\n characterHeight?: number;\n /**\n * When true, `setState` / `setPose` waits until the current clip finishes one loop (`loop: true`)\n * or ends (`loop: false`) before crossfading. Default false: apply the new clip as soon as the\n * request is processed (still queued while a crossfade or character-state transition clip runs).\n */\n queueStateUntilCycleEnd?: boolean;\n /**\n * When true, emit `console.debug` for pose changes, character-state transitions, and edge lookup.\n */\n debug?: boolean;\n}\n","import type {\n AnimationStateConfig,\n AnimationStateGridSheetConfig,\n CharacterManifest,\n CharacterPose,\n GridSheetConfig,\n GridSheetOrder,\n LayeredCharacterManifest,\n LegacyCharacterManifest,\n} from \"./types.js\";\nimport { isLayeredManifest } from \"./types.js\";\n\n/** Separator for flat keys: `characterState/action` (e.g. `neutral/idle`). */\nexport const POSE_KEY_SEPARATOR = \"/\";\n\n/** `frame_001.png` … `frame_181.png` */\nexport function idleFrameNames(count = 181): string[] {\n return Array.from({ length: count }, (_, i) => {\n const n = String(i + 1).padStart(3, \"0\");\n return `frame_${n}.png`;\n });\n}\n\n/** `idle/frame_001.png` … when `subdir` is `idle`; use with `baseUrl` at the assets root. */\nexport function framePaths(subdir: string, count: number): string[] {\n const prefix = subdir.replace(/\\/$/, \"\");\n return Array.from({ length: count }, (_, i) => {\n const n = String(i + 1).padStart(3, \"0\");\n return `${prefix}/frame_${n}.png`;\n });\n}\n\nexport function poseToKey(pose: CharacterPose): string {\n return `${pose.characterState}${POSE_KEY_SEPARATOR}${pose.action}`;\n}\n\n/** Parse `neutral/idle` into a pose; returns null if not a layered key. */\nexport function keyToPose(key: string): CharacterPose | null {\n const i = key.indexOf(POSE_KEY_SEPARATOR);\n if (i <= 0 || i === key.length - 1) {\n return null;\n }\n return {\n characterState: key.slice(0, i),\n action: key.slice(i + POSE_KEY_SEPARATOR.length),\n };\n}\n\n/** Internal flat key for a one-shot character-state transition clip. */\nexport function transitionFlatKey(fromCharacterState: string, toCharacterState: string): string {\n return `__tr__${POSE_KEY_SEPARATOR}${fromCharacterState}${POSE_KEY_SEPARATOR}${toCharacterState}`;\n}\n\nexport function isTransitionFlatKey(key: string): boolean {\n return key.startsWith(`__tr__${POSE_KEY_SEPARATOR}`);\n}\n\n/**\n * Merge layered character actions and transition clips into one flat `states` map for the player.\n */\nexport function flattenLayeredManifest(manifest: LayeredCharacterManifest): Record<\n string,\n AnimationStateConfig\n> {\n const states: Record<string, AnimationStateConfig> = {};\n for (const [characterState, { actions }] of Object.entries(manifest.characterStates)) {\n for (const [action, cfg] of Object.entries(actions)) {\n states[poseToKey({ characterState, action })] = cfg;\n }\n }\n if (manifest.transitions) {\n for (const [from, toMap] of Object.entries(manifest.transitions)) {\n for (const [to, cfg] of Object.entries(toMap)) {\n states[transitionFlatKey(from, to)] = cfg;\n }\n }\n }\n return states;\n}\n\n/** Resolve default pose for a layered manifest (deterministic: first entry keys). */\nexport function defaultPoseForLayered(manifest: LayeredCharacterManifest): CharacterPose {\n if (manifest.defaultPose) {\n return manifest.defaultPose;\n }\n const csKeys = Object.keys(manifest.characterStates);\n if (csKeys.length === 0) {\n throw new Error(\"manifest.characterStates must not be empty\");\n }\n const characterState = csKeys[0];\n const actionKeys = Object.keys(manifest.characterStates[characterState].actions);\n if (actionKeys.length === 0) {\n throw new Error(`manifest.characterStates[\"${characterState}\"].actions must not be empty`);\n }\n return { characterState, action: actionKeys[0] };\n}\n\n/** Build a single flat `states` map for CharacterPlayer from any manifest shape. */\nexport function manifestToFlatStates(manifest: CharacterManifest): Record<string, AnimationStateConfig> {\n if (isLayeredManifest(manifest)) {\n return flattenLayeredManifest(manifest);\n }\n return manifest.states;\n}\n\n/** Default manifest: `idle` and `talk` under distinct asset folders (legacy flat). */\nexport function createDefaultManifest(): LegacyCharacterManifest {\n return {\n defaultState: \"idle\",\n states: {\n idle: {\n frames: framePaths(\"idle\", 181),\n fps: 32,\n loop: true,\n },\n talk: {\n frames: framePaths(\"talk\", 90),\n fps: 32,\n loop: true,\n },\n },\n };\n}\n\n/** Frame counts for packaged sad demo assets under `assets/sheets/` (must match PNG layout). */\nexport const SAD_DEMO_FRAMES = {\n /**\n * `neutral_to_sad.png` is 5120×3830 → 10×10 cells @ 512×383; only **91** frames are drawn\n * (9 full rows + 1 cell in row 10). The last 9 cells in the bottom row are empty—do not play them.\n */\n transitionNeutralToSad: 91,\n /** `sad_to_neutral.png` is 4608×3064 → 9×8 cells @ 512×383 (66 frames; last row partial). */\n transitionSadToNeutral: 66,\n sadIdle: 149,\n sadTalk: 126,\n /** `neutral_click_512.png` is 3072×2298 → 6×6 cells @ 512×383 (36 frames). */\n neutralClick: 36,\n /**\n * `sad_click_512.png` is 4608×3447 → 9×9 grid @ 512×383; only **75** frames have content\n * (last 6 cells in row-major order are empty padding—do not play them).\n */\n sadClick: 75,\n /**\n * `sad_thinking_512.png` is 5632×3830 → 11×10 grid @ 512×383; **105** frames drawn\n * (last 5 cells empty—avoids blink when looping).\n */\n sadThinking: 105,\n /**\n * `neutral_thinking_512.png` is 6144×4213 → 12×11 grid @ 512×383; **122** frames drawn\n * (last 10 cells empty—avoids blink when looping).\n */\n neutralThinking: 122,\n /**\n * `sad_celebrating_512.png` is 6144×4213 → 12×11 grid @ 512×383; **122** frames drawn\n * (last 10 cells empty).\n */\n sadCelebrating: 122,\n /**\n * `neutral_celebrating_512.png` is 6656×4596 → 13×12 grid @ 512×383; **150** frames drawn\n * (last 6 cells empty).\n */\n neutralCelebrating: 150,\n} as const;\n\n/**\n * Uniform grid parameters per `assets/sheets/*.png`, derived from image pixel size and\n * {@link SAD_DEMO_FRAMES} (row-major cells; unused trailing cells are allowed).\n */\nexport const SAD_DEMO_GRID_SHEETS = {\n neutralIdle: {\n image: \"sheets/neutral_idle_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 14,\n frameCount: 181,\n },\n neutralTalk: {\n image: \"sheets/neutral_talk_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 10,\n frameCount: 93,\n },\n neutralClick: {\n image: \"sheets/neutral_click_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 6,\n frameCount: SAD_DEMO_FRAMES.neutralClick,\n },\n sadIdle: {\n image: \"sheets/sad_idle_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 13,\n frameCount: SAD_DEMO_FRAMES.sadIdle,\n },\n sadTalk: {\n image: \"sheets/sad_talk_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 12,\n frameCount: SAD_DEMO_FRAMES.sadTalk,\n },\n neutralToSad: {\n image: \"sheets/neutral_to_sad.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 10,\n frameCount: SAD_DEMO_FRAMES.transitionNeutralToSad,\n },\n sadToNeutral: {\n image: \"sheets/sad_to_neutral.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 9,\n frameCount: SAD_DEMO_FRAMES.transitionSadToNeutral,\n },\n sadClick: {\n image: \"sheets/sad_click_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 9,\n frameCount: SAD_DEMO_FRAMES.sadClick,\n },\n sadThinking: {\n image: \"sheets/sad_thinking_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 11,\n frameCount: SAD_DEMO_FRAMES.sadThinking,\n },\n neutralThinking: {\n image: \"sheets/neutral_thinking_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 12,\n frameCount: SAD_DEMO_FRAMES.neutralThinking,\n },\n sadCelebrating: {\n image: \"sheets/sad_celebrating_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 12,\n frameCount: SAD_DEMO_FRAMES.sadCelebrating,\n },\n neutralCelebrating: {\n image: \"sheets/neutral_celebrating_512.png\",\n frameWidth: 512,\n frameHeight: 383,\n columns: 13,\n frameCount: SAD_DEMO_FRAMES.neutralCelebrating,\n },\n} as const;\n\nfunction sadDemoGridClip(\n sheet: (typeof SAD_DEMO_GRID_SHEETS)[keyof typeof SAD_DEMO_GRID_SHEETS],\n fps: number,\n loop: boolean,\n): AnimationStateGridSheetConfig {\n const gridSheet: GridSheetConfig = {\n image: sheet.image,\n frameWidth: sheet.frameWidth,\n frameHeight: sheet.frameHeight,\n columns: sheet.columns,\n frameCount: sheet.frameCount,\n };\n if (\"order\" in sheet && sheet.order !== undefined && sheet.order !== null) {\n gridSheet.order = sheet.order as GridSheetOrder;\n }\n return {\n gridSheet,\n fps,\n loop,\n };\n}\n\n/**\n * Layered manifest: neutral, sad, and one-shot transitions using one PNG grid sheet per clip\n * under `assets/sheets/` (see {@link SAD_DEMO_GRID_SHEETS}).\n */\nexport function createSadDemoManifest(): LayeredCharacterManifest {\n return {\n defaultPose: { characterState: \"neutral\", action: \"idle\" },\n characterStates: {\n neutral: {\n actions: {\n idle: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.neutralIdle, 32, true),\n talk: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.neutralTalk, 32, true),\n click: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.neutralClick, 50, false),\n thinking: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.neutralThinking, 32, true),\n celebrating: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.neutralCelebrating, 32, false),\n },\n },\n sad: {\n actions: {\n idle: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.sadIdle, 32, true),\n talk: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.sadTalk, 32, true),\n click: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.sadClick, 50, false),\n thinking: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.sadThinking, 32, true),\n celebrating: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.sadCelebrating, 32, false),\n },\n },\n },\n transitions: {\n neutral: {\n sad: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.neutralToSad, 32, false),\n },\n sad: {\n neutral: sadDemoGridClip(SAD_DEMO_GRID_SHEETS.sadToNeutral, 32, false),\n },\n },\n };\n}\n","import { AnimatedSprite, Application, Assets, Container, Rectangle, Texture } from \"pixi.js\";\nimport type {\n AnimationStateConfig,\n CharacterManifest,\n CharacterPlayerOptions,\n CharacterPose,\n GridSheetConfig,\n LayeredCharacterManifest,\n LegacyCharacterManifest,\n} from \"../types.js\";\nimport { isGridSheetAnimation, isLayeredManifest } from \"../types.js\";\nimport {\n defaultPoseForLayered,\n isTransitionFlatKey,\n keyToPose,\n manifestToFlatStates,\n POSE_KEY_SEPARATOR,\n poseToKey,\n transitionFlatKey,\n} from \"../manifest.js\";\n\nfunction joinBase(baseUrl: string, frame: string): string {\n const base = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n return new URL(frame, base).href;\n}\n\n/** Unique texture URLs referenced by a flat manifest (grid sheets + per-frame lists). */\nfunction collectManifestTextureUrls(\n flatStates: Record<string, AnimationStateConfig>,\n baseUrl: string,\n): string[] {\n const seen = new Set<string>();\n for (const cfg of Object.values(flatStates)) {\n if (isGridSheetAnimation(cfg)) {\n seen.add(joinBase(baseUrl, cfg.gridSheet.image));\n } else {\n for (const f of cfg.frames) {\n seen.add(joinBase(baseUrl, f));\n }\n }\n }\n return [...seen];\n}\n\nfunction validateGridSheetAgainstTexture(\n texWidth: number,\n texHeight: number,\n g: GridSheetConfig,\n): void {\n const { frameWidth, frameHeight, columns, frameCount } = g;\n if (frameCount < 1) {\n throw new Error(`gridSheet.frameCount must be >= 1, got ${frameCount}`);\n }\n if (columns < 1) {\n throw new Error(`gridSheet.columns must be >= 1, got ${columns}`);\n }\n if (frameWidth <= 0 || frameHeight <= 0) {\n throw new Error(\n `gridSheet frameWidth and frameHeight must be positive, got ${frameWidth}x${frameHeight}`,\n );\n }\n const rows = Math.ceil(frameCount / columns);\n const minW = columns * frameWidth;\n const minH = rows * frameHeight;\n if (texWidth < minW) {\n throw new Error(\n `Spritesheet width ${texWidth}px is smaller than grid width ${minW}px (${columns} columns × ${frameWidth}px)`,\n );\n }\n if (texHeight < minH) {\n throw new Error(\n `Spritesheet height ${texHeight}px is smaller than grid height ${minH}px (${rows} rows × ${frameHeight}px for ${frameCount} frames)`,\n );\n }\n}\n\nfunction texturesFromGridSheet(base: Texture, g: GridSheetConfig): Texture[] {\n const { frameWidth, frameHeight, columns, frameCount, order } = g;\n const resolvedOrder = order ?? \"row-major\";\n // The physical grid row count is derived from how many linear frames we expose.\n const rows = Math.ceil(frameCount / columns);\n const textures: Texture[] = [];\n const source = base.source;\n for (let i = 0; i < frameCount; i++) {\n const col = resolvedOrder === \"column-major\" ? Math.floor(i / rows) : i % columns;\n const row = resolvedOrder === \"column-major\" ? i % rows : Math.floor(i / columns);\n const x = col * frameWidth;\n const y = row * frameHeight;\n textures.push(\n new Texture({\n source,\n frame: new Rectangle(x, y, frameWidth, frameHeight),\n }),\n );\n }\n return textures;\n}\n\nexport class CharacterPlayer {\n readonly container: HTMLElement;\n private readonly manifest: CharacterManifest;\n private readonly flatStates: Record<string, AnimationStateConfig>;\n private readonly layered: boolean;\n private readonly transitionMap: Record<string, Record<string, AnimationStateConfig>> | null;\n private readonly baseUrl: string;\n private readonly transitionMs: number;\n private readonly fitPadding: number;\n private characterWidth: number | undefined;\n private characterHeight: number | undefined;\n private readonly queueStateUntilCycleEnd: boolean;\n private readonly debug: boolean;\n\n private app: Application | null = null;\n private root: Container | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private currentSprite: AnimatedSprite | null = null;\n\n /** Current clip key: legacy `idle` / `talk`, layered `neutral/idle`, or internal `__tr__/a/b`. */\n private currentFlatKey: string | null = null;\n /** Logical pose when `layered`; unchanged while a transition clip plays. */\n private currentPose: CharacterPose | null = null;\n\n private transitioning = false;\n private fromSprite: AnimatedSprite | null = null;\n private toSprite: AnimatedSprite | null = null;\n private transitionProgress = 0;\n private transitionTargetFlatKey: string | null = null;\n private pendingFlatKey: string | null = null;\n private transitionUpdateBound = this.onTransitionTick.bind(this);\n\n private deferredTargetFlatKey: string | null = null;\n private waitingForCycleEnd = false;\n\n /** After a one-shot transition clip mounts, crossfade into this pose key. */\n private pendingAfterTransitionClip: { targetKey: string } | null = null;\n\n private textureWidth = 512;\n private textureHeight = 512;\n\n /** Invalidates in-flight `playOneShotAction` completion handlers after a new one-shot or `destroy()`. */\n private oneShotCompletionToken = 0;\n private destroyed = false;\n\n constructor(options: CharacterPlayerOptions) {\n this.container = options.container;\n this.manifest = options.manifest;\n this.flatStates = manifestToFlatStates(options.manifest);\n this.layered = isLayeredManifest(options.manifest);\n this.transitionMap = isLayeredManifest(options.manifest)\n ? (options.manifest as LayeredCharacterManifest).transitions\n : null;\n this.baseUrl = options.baseUrl;\n this.transitionMs = options.transitionMs ?? 200;\n this.fitPadding = options.fitPadding ?? 1;\n this.characterWidth = options.characterWidth;\n this.characterHeight = options.characterHeight;\n this.queueStateUntilCycleEnd = options.queueStateUntilCycleEnd ?? false;\n this.debug = options.debug ?? false;\n\n const keys = Object.keys(this.flatStates);\n if (keys.length === 0) {\n throw new Error(\"CharacterPlayer: manifest must define at least one clip\");\n }\n\n if (this.layered) {\n const pose =\n options.initialPose ??\n (options.manifest as LayeredCharacterManifest).defaultPose ??\n defaultPoseForLayered(options.manifest as LayeredCharacterManifest);\n const k = poseToKey(pose);\n if (!this.flatStates[k]) {\n throw new Error(`CharacterPlayer: unknown initial pose \"${k}\"`);\n }\n this.currentPose = pose;\n this.currentFlatKey = k;\n } else {\n if (options.initialPose !== undefined) {\n throw new Error(\"CharacterPlayer: initialPose is only valid with a layered manifest\");\n }\n const legacy = options.manifest as LegacyCharacterManifest;\n const def =\n options.initialState ?? legacy.defaultState ?? Object.keys(legacy.states)[0];\n if (!this.flatStates[def]) {\n throw new Error(`CharacterPlayer: unknown initial state \"${def}\"`);\n }\n this.currentFlatKey = def;\n }\n\n this.logDebug(\"constructor\", { layered: this.layered, initial: this.currentFlatKey });\n }\n\n /** Create Pixi app, load first clip, append canvas. Call once. */\n async init(): Promise<void> {\n if (this.app) {\n return;\n }\n\n const app = new Application();\n await app.init({\n resizeTo: this.container,\n backgroundAlpha: 0,\n antialias: true,\n autoDensity: true,\n resolution: typeof window !== \"undefined\" ? window.devicePixelRatio : 1,\n preference: \"webgl\",\n });\n\n this.app = app;\n this.container.appendChild(app.canvas as HTMLCanvasElement);\n\n this.resizeObserver = new ResizeObserver(() => {\n const resize = (app as unknown as { resize?: () => void }).resize;\n resize?.call(app);\n this.layout();\n });\n this.resizeObserver.observe(this.container);\n\n app.renderer.on(\"resize\", () => this.layout());\n\n const root = new Container();\n this.root = root;\n app.stage.addChild(root);\n\n const start = this.currentFlatKey!;\n await this.mountState(start);\n }\n\n /**\n * Fetches every texture URL from the manifest into Pixi’s asset cache so later clip changes\n * reuse cached data instead of waiting on the network. Safe to call after {@link init}; does not\n * change the current animation. Failed loads are ignored unless `debug` is enabled (then failures\n * are logged with `console.debug`).\n */\n async preloadAllAssets(): Promise<void> {\n if (this.destroyed) {\n return;\n }\n const urls = collectManifestTextureUrls(this.flatStates, this.baseUrl);\n const results = await Promise.allSettled(urls.map((url) => Assets.load<Texture>(url)));\n if (!this.debug) {\n return;\n }\n results.forEach((r, i) => {\n if (r.status === \"rejected\") {\n console.debug(\"[CharacterPlayer] preload failed\", urls[i], r.reason);\n }\n });\n }\n\n /**\n * Current clip key. Layered manifests use `characterState/action` (e.g. `neutral/idle`);\n * during a character-state transition the internal `__tr__/from/to` key may be returned.\n */\n getState(): string | null {\n return this.currentFlatKey;\n }\n\n /** Logical pose for layered manifests; `null` for legacy flat manifests. */\n getPose(): CharacterPose | null {\n return this.currentPose;\n }\n\n /**\n * Set explicit character size in CSS pixels (see `CharacterPlayerOptions.characterWidth` /\n * `characterHeight`). Pass no arguments or `undefined` for both dimensions to restore\n * scaling that fits the container (still multiplied by `fitPadding`).\n */\n setCharacterSize(width?: number, height?: number): void {\n this.characterWidth = width;\n this.characterHeight = height;\n this.layout();\n }\n\n /** Switch pose (layered manifests only). */\n async setPose(pose: CharacterPose): Promise<void> {\n if (!this.layered) {\n throw new Error(\"CharacterPlayer: setPose requires a layered manifest\");\n }\n this.validatePose(pose);\n const key = poseToKey(pose);\n await this.applySetFlatKey(key);\n }\n\n /** Switch animation clip; crossfades when `transitionMs` > 0. */\n async setState(name: string): Promise<void> {\n const key = this.resolveSetStateName(name);\n await this.applySetFlatKey(key);\n }\n\n /**\n * Play a one-shot action clip immediately: aborts crossfades, cycle queues, and transition clips,\n * then returns to `{ characterState, action: \"idle\" }` when the clip ends. Layered manifests only;\n * requires a matching clip and playback context for that character state (including a\n * `from`→… transition clip when `from` matches).\n */\n async playOneShotAction(pose: CharacterPose): Promise<void> {\n if (!this.layered) {\n throw new Error(\"CharacterPlayer: playOneShotAction requires a layered manifest\");\n }\n this.validatePose(pose);\n const actionKey = poseToKey(pose);\n if (!this.flatStates[actionKey]) {\n throw new Error(`CharacterPlayer: manifest has no \"${actionKey}\" clip`);\n }\n const cfg = this.flatStates[actionKey]!;\n if (cfg.loop) {\n throw new Error(\n `CharacterPlayer: playOneShotAction expects a non-looping clip; \"${actionKey}\" has loop: true`,\n );\n }\n if (!this.isCharacterStatePlaybackContext(pose.characterState)) {\n throw new Error(\n `CharacterPlayer: playOneShotAction only applies when playback matches character state \"${pose.characterState}\" (including a matching transition clip)`,\n );\n }\n if (!this.app || !this.root) {\n throw new Error(\"CharacterPlayer: playOneShotAction requires init() first\");\n }\n\n const token = ++this.oneShotCompletionToken;\n this.logDebug(\"playOneShotAction: start\", { token, actionKey });\n\n // Load textures while the current clip is still visible. `abortImmediatePlayback` clears the\n // stage; if we tore down first, the first trigger would show an empty canvas until `Assets.load`\n // finishes (subsequent runs hit the cache and barely flash).\n const incoming = await this.createSpriteForState(actionKey, { autoPlay: false });\n if (this.destroyed || token !== this.oneShotCompletionToken) {\n incoming.destroy({ texture: false, textureSource: false });\n return;\n }\n\n this.abortImmediatePlayback();\n if (!this.root) {\n incoming.destroy({ texture: false, textureSource: false });\n return;\n }\n\n this.attachSprite(incoming);\n incoming.gotoAndPlay(0);\n this.currentFlatKey = actionKey;\n this.syncPoseFromFlatKey();\n this.maybeAttachTransitionClipCompletion();\n\n if (this.destroyed || token !== this.oneShotCompletionToken) {\n return;\n }\n\n const sprite = this.currentSprite;\n if (!sprite) {\n return;\n }\n const idleKey = poseToKey({ characterState: pose.characterState, action: \"idle\" });\n\n const done = (): void => {\n sprite.onComplete = undefined;\n sprite.onLoop = undefined;\n if (this.destroyed) {\n return;\n }\n if (token !== this.oneShotCompletionToken) {\n this.logDebug(\"playOneShotAction: completion ignored (superseded)\", { token });\n return;\n }\n this.logDebug(\"playOneShotAction: complete -> idle\", { token, idleKey });\n void this.applyTransitionNow(idleKey);\n };\n\n sprite.onComplete = done;\n sprite.onLoop = undefined;\n }\n\n /**\n * Play the neutral `click` clip (see {@link playOneShotAction}).\n */\n async playNeutralClick(): Promise<void> {\n return this.playOneShotAction({ characterState: \"neutral\", action: \"click\" });\n }\n\n private resolveSetStateName(name: string): string {\n if (this.layered && (name === \"idle\" || name === \"talk\" || name === \"click\")) {\n return poseToKey({ characterState: \"neutral\", action: name });\n }\n return name;\n }\n\n /** True when the current clip is for `characterState` or a transition clip leaving that state. */\n private isCharacterStatePlaybackContext(characterState: string): boolean {\n const k = this.currentFlatKey;\n if (!k) {\n return false;\n }\n if (k.startsWith(`${characterState}/`)) {\n return true;\n }\n if (isTransitionFlatKey(k)) {\n const rest = k.slice(`__tr__${POSE_KEY_SEPARATOR}`.length);\n const i = rest.indexOf(POSE_KEY_SEPARATOR);\n if (i <= 0) {\n return false;\n }\n return rest.slice(0, i) === characterState;\n }\n return false;\n }\n\n /**\n * Stops and tears down active playback so a one-shot (e.g. click) can start immediately.\n * Clears crossfade ticker, transition sprites, cycle/queue state, and the current sprite.\n */\n private abortImmediatePlayback(): void {\n if (this.app) {\n this.app.ticker.remove(this.transitionUpdateBound);\n }\n this.transitioning = false;\n this.transitionProgress = 0;\n this.transitionTargetFlatKey = null;\n\n this.fromSprite?.stop();\n this.fromSprite?.destroy({ texture: false, textureSource: false });\n this.fromSprite = null;\n this.toSprite?.stop();\n this.toSprite?.destroy({ texture: false, textureSource: false });\n this.toSprite = null;\n\n this.clearCycleWait();\n this.deferredTargetFlatKey = null;\n this.waitingForCycleEnd = false;\n this.pendingFlatKey = null;\n this.pendingAfterTransitionClip = null;\n\n this.currentSprite?.stop();\n this.currentSprite?.destroy({ texture: false, textureSource: false });\n this.currentSprite = null;\n if (this.root) {\n this.root.removeChildren();\n }\n this.logDebug(\"abortImmediatePlayback\");\n }\n\n private validatePose(pose: CharacterPose): void {\n if (!isLayeredManifest(this.manifest)) {\n return;\n }\n const m = this.manifest as LayeredCharacterManifest;\n const block = m.characterStates[pose.characterState];\n if (!block?.actions[pose.action]) {\n throw new Error(\n `CharacterPlayer: unknown pose \"${pose.characterState}/${pose.action}\"`,\n );\n }\n }\n\n private logDebug(message: string, data?: Record<string, unknown>): void {\n if (this.debug) {\n // eslint-disable-next-line no-console\n console.debug(`[CharacterPlayer] ${message}`, data ?? \"\");\n }\n }\n\n private logWarn(message: string, data?: Record<string, unknown>): void {\n // eslint-disable-next-line no-console\n console.warn(`[CharacterPlayer] ${message}`, data ?? \"\");\n }\n\n /** True while a one-shot character-state transition clip is playing (after crossfade onto it). */\n private isPlayingTransitionClip(): boolean {\n return this.currentFlatKey !== null && isTransitionFlatKey(this.currentFlatKey);\n }\n\n private async applySetFlatKey(targetKey: string): Promise<void> {\n if (!this.flatStates[targetKey]) {\n throw new Error(`CharacterPlayer: unknown state \"${targetKey}\"`);\n }\n if (!this.app || !this.root) {\n this.currentFlatKey = targetKey;\n this.syncPoseFromFlatKey();\n this.logDebug(\"applySetFlatKey (no app)\", { targetKey });\n return;\n }\n\n if (this.isPlayingTransitionClip()) {\n this.pendingFlatKey = targetKey;\n this.logDebug(\"queue: pending while transition clip plays\", { targetKey });\n return;\n }\n\n if (this.transitioning) {\n this.pendingFlatKey = targetKey;\n this.logDebug(\"queue: pending while crossfading\", { targetKey });\n return;\n }\n\n if (this.waitingForCycleEnd) {\n if (targetKey === this.currentFlatKey) {\n this.clearCycleWait();\n return;\n }\n this.deferredTargetFlatKey = targetKey;\n this.logDebug(\"queue: deferred until cycle end\", { targetKey });\n return;\n }\n\n if (targetKey === this.currentFlatKey) {\n return;\n }\n\n if (!this.queueStateUntilCycleEnd) {\n await this.applyTransitionNow(targetKey);\n return;\n }\n\n this.deferredTargetFlatKey = targetKey;\n this.waitingForCycleEnd = true;\n this.attachCycleEndListener();\n }\n\n private syncPoseFromFlatKey(): void {\n if (!this.layered) {\n return;\n }\n const p = this.currentFlatKey ? keyToPose(this.currentFlatKey) : null;\n if (p) {\n this.currentPose = p;\n }\n }\n\n private async applyTransitionNow(targetFlatKey: string): Promise<void> {\n const fromPose = this.currentPose;\n const toPose = keyToPose(targetFlatKey);\n if (\n this.layered &&\n fromPose &&\n toPose &&\n fromPose.characterState !== toPose.characterState\n ) {\n this.logDebug(\"applyTransitionNow: character-state change\", {\n from: fromPose.characterState,\n to: toPose.characterState,\n });\n await this.applyCharacterStateChange(toPose, targetFlatKey);\n return;\n }\n if (this.transitionMs <= 0) {\n await this.swapInstant(targetFlatKey);\n } else {\n await this.beginCrossfade(targetFlatKey);\n }\n }\n\n private async applyCharacterStateChange(\n targetPose: CharacterPose,\n targetKey: string,\n ): Promise<void> {\n const from = this.currentPose!.characterState;\n const to = targetPose.characterState;\n const tr = this.transitionMap?.[from]?.[to];\n if (!tr) {\n this.logWarn(`no transition clip for character state \"${from}\" -> \"${to}\"; crossfading`, {\n from,\n to,\n });\n if (this.transitionMs <= 0) {\n await this.swapInstant(targetKey);\n this.syncPoseFromFlatKey();\n } else {\n await this.beginCrossfade(targetKey);\n }\n return;\n }\n const trKey = transitionFlatKey(from, to);\n this.logDebug(\"play transition clip then target\", { trKey, targetKey });\n this.pendingAfterTransitionClip = { targetKey };\n await this.applyTransitionNow(trKey);\n }\n\n private clearCycleWait(): void {\n const sprite = this.currentSprite;\n if (sprite) {\n sprite.onLoop = undefined;\n sprite.onComplete = undefined;\n }\n this.deferredTargetFlatKey = null;\n this.waitingForCycleEnd = false;\n }\n\n private attachCycleEndListener(): void {\n const sprite = this.currentSprite;\n if (!sprite) {\n void this.finishDeferredAndTransition();\n return;\n }\n const stateName = this.currentFlatKey;\n if (!stateName) {\n void this.finishDeferredAndTransition();\n return;\n }\n const cfg = this.flatStates[stateName];\n if (sprite.totalFrames <= 1) {\n void this.finishDeferredAndTransition();\n return;\n }\n if (!cfg.loop && !sprite.playing) {\n void this.finishDeferredAndTransition();\n return;\n }\n\n const done = (): void => {\n if (!this.waitingForCycleEnd) {\n return;\n }\n void this.finishDeferredAndTransition();\n };\n\n if (cfg.loop) {\n sprite.onLoop = done;\n sprite.onComplete = undefined;\n } else {\n sprite.onComplete = done;\n sprite.onLoop = undefined;\n }\n }\n\n private async finishDeferredAndTransition(): Promise<void> {\n const sprite = this.currentSprite;\n if (sprite) {\n sprite.onLoop = undefined;\n sprite.onComplete = undefined;\n }\n const target = this.deferredTargetFlatKey;\n this.deferredTargetFlatKey = null;\n this.waitingForCycleEnd = false;\n if (!target || target === this.currentFlatKey) {\n return;\n }\n await this.applyTransitionNow(target);\n }\n\n /** Returns true if we scheduled waiting for a transition clip to finish (skip processing crossfade queue). */\n private maybeAttachTransitionClipCompletion(): boolean {\n if (\n !this.pendingAfterTransitionClip ||\n !this.currentFlatKey ||\n !isTransitionFlatKey(this.currentFlatKey)\n ) {\n return false;\n }\n const { targetKey } = this.pendingAfterTransitionClip;\n this.pendingAfterTransitionClip = null;\n this.attachTransitionClipCompletion(targetKey);\n return true;\n }\n\n private attachTransitionClipCompletion(targetKey: string): void {\n const sprite = this.currentSprite;\n if (!sprite) {\n void this.finishCharacterTransitionChain(targetKey);\n return;\n }\n const cfg = this.flatStates[this.currentFlatKey!];\n if (!cfg) {\n void this.finishCharacterTransitionChain(targetKey);\n return;\n }\n this.logDebug(\"attachTransitionClipCompletion\", { targetKey, loop: cfg.loop });\n const done = (): void => {\n sprite.onComplete = undefined;\n sprite.onLoop = undefined;\n void this.finishCharacterTransitionChain(targetKey);\n };\n if (!cfg.loop) {\n sprite.onComplete = done;\n } else {\n done();\n }\n }\n\n private async finishCharacterTransitionChain(targetKey: string): Promise<void> {\n const use = this.pendingFlatKey ?? targetKey;\n this.pendingFlatKey = null;\n this.logDebug(\"transition clip complete -> target pose\", { targetKey, use });\n await this.applyTransitionNow(use);\n }\n\n private async swapInstant(name: string): Promise<void> {\n this.currentSprite?.stop();\n this.currentSprite?.destroy({ texture: false, textureSource: false });\n this.currentSprite = null;\n if (this.root) {\n this.root.removeChildren();\n }\n await this.mountState(name);\n this.currentFlatKey = name;\n this.syncPoseFromFlatKey();\n this.maybeAttachTransitionClipCompletion();\n }\n\n private async beginCrossfade(name: string): Promise<void> {\n const app = this.app!;\n const root = this.root!;\n\n const outgoing = this.currentSprite;\n if (!outgoing) {\n await this.swapInstant(name);\n return;\n }\n\n const incoming = await this.createSpriteForState(name);\n incoming.alpha = 0;\n root.addChild(incoming);\n\n this.fromSprite = outgoing;\n this.toSprite = incoming;\n this.transitionTargetFlatKey = name;\n this.transitioning = true;\n this.transitionProgress = 0;\n\n app.ticker.add(this.transitionUpdateBound);\n }\n\n private onTransitionTick(): void {\n if (!this.transitioning || !this.fromSprite || !this.toSprite || !this.app) {\n return;\n }\n const ms = this.app.ticker.deltaMS;\n this.transitionProgress += ms / this.transitionMs;\n const t = Math.min(1, this.transitionProgress);\n this.fromSprite.alpha = 1 - t;\n this.toSprite.alpha = t;\n\n if (t >= 1) {\n this.finishCrossfade();\n }\n }\n\n private finishCrossfade(): void {\n const app = this.app!;\n app.ticker.remove(this.transitionUpdateBound);\n\n this.fromSprite?.stop();\n this.fromSprite?.destroy({ texture: false, textureSource: false });\n this.fromSprite = null;\n\n const kept = this.toSprite!;\n this.toSprite = null;\n this.currentSprite = kept;\n this.transitioning = false;\n\n if (this.transitionTargetFlatKey) {\n this.currentFlatKey = this.transitionTargetFlatKey;\n this.syncPoseFromFlatKey();\n }\n this.transitionTargetFlatKey = null;\n\n const waitingOnTransitionClip = this.maybeAttachTransitionClipCompletion();\n\n if (!waitingOnTransitionClip) {\n const queued = this.pendingFlatKey;\n this.pendingFlatKey = null;\n\n if (queued && queued !== this.currentFlatKey) {\n void this.applySetFlatKey(queued);\n }\n }\n }\n\n private async mountState(name: string): Promise<void> {\n const sprite = await this.createSpriteForState(name);\n this.attachSprite(sprite);\n }\n\n private attachSprite(sprite: AnimatedSprite): void {\n this.root!.addChild(sprite);\n this.currentSprite = sprite;\n const tex = sprite.texture;\n this.textureWidth = tex.width;\n this.textureHeight = tex.height;\n this.layout();\n }\n\n private async createSpriteForState(\n name: string,\n options?: { autoPlay?: boolean },\n ): Promise<AnimatedSprite> {\n const cfg = this.flatStates[name];\n let textures: Texture[];\n\n if (isGridSheetAnimation(cfg)) {\n const g = cfg.gridSheet;\n const url = joinBase(this.baseUrl, g.image);\n const base = await Assets.load<Texture>(url);\n const tw = base.width;\n const th = base.height;\n validateGridSheetAgainstTexture(tw, th, g);\n if (this.debug) {\n console.debug(\n `[CharacterPlayer] gridSheet \"${name}\": image=${url} size=${tw}x${th} cell=${g.frameWidth}x${g.frameHeight} columns=${g.columns} frameCount=${g.frameCount}`,\n );\n }\n textures = texturesFromGridSheet(base, g);\n if (this.debug) {\n console.log(\"[FIX] gridSheet textures built\", {\n name,\n image: g.image,\n texturePx: `${tw}x${th}`,\n cellPx: `${g.frameWidth}x${g.frameHeight}`,\n columns: g.columns,\n frames: textures.length,\n order: g.order ?? \"row-major\",\n });\n }\n } else {\n const urls = cfg.frames.map((f) => joinBase(this.baseUrl, f));\n textures = await Promise.all(urls.map((url) => Assets.load<Texture>(url)));\n }\n\n const sprite = new AnimatedSprite({\n textures,\n animationSpeed: cfg.fps / 60,\n loop: cfg.loop,\n autoPlay: false,\n });\n sprite.anchor.set(0.5);\n if (options?.autoPlay !== false) {\n sprite.play();\n }\n return sprite;\n }\n\n private layout(): void {\n if (!this.app || !this.root) {\n return;\n }\n const w = this.app.screen.width;\n const h = this.app.screen.height;\n this.root.x = w / 2;\n this.root.y = h / 2;\n\n const tw = this.textureWidth;\n const th = this.textureHeight;\n if (tw <= 0 || th <= 0) {\n return;\n }\n const cw = this.characterWidth;\n const ch = this.characterHeight;\n let scale: number;\n if (cw !== undefined && ch !== undefined) {\n scale = Math.min(cw / tw, ch / th) * this.fitPadding;\n } else if (cw !== undefined) {\n scale = (cw / tw) * this.fitPadding;\n } else if (ch !== undefined) {\n scale = (ch / th) * this.fitPadding;\n } else {\n scale = Math.min(w / tw, h / th) * this.fitPadding;\n }\n this.root.scale.set(scale);\n }\n\n destroy(): void {\n this.destroyed = true;\n this.oneShotCompletionToken += 1;\n this.clearCycleWait();\n\n if (this.app) {\n this.app.ticker.remove(this.transitionUpdateBound);\n }\n\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n\n this.currentSprite?.destroy({ texture: false, textureSource: false });\n this.currentSprite = null;\n this.fromSprite?.destroy({ texture: false, textureSource: false });\n this.fromSprite = null;\n this.toSprite?.destroy({ texture: false, textureSource: false });\n this.toSprite = null;\n\n if (this.app) {\n this.app.destroy(true, { children: true, texture: false });\n this.app = null;\n }\n this.root = null;\n this.currentFlatKey = null;\n this.currentPose = null;\n this.pendingAfterTransitionClip = null;\n }\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -41,6 +41,13 @@ declare class CharacterPlayer {
41
41
  constructor(options: CharacterPlayerOptions);
42
42
  /** Create Pixi app, load first clip, append canvas. Call once. */
43
43
  init(): Promise<void>;
44
+ /**
45
+ * Fetches every texture URL from the manifest into Pixi’s asset cache so later clip changes
46
+ * reuse cached data instead of waiting on the network. Safe to call after {@link init}; does not
47
+ * change the current animation. Failed loads are ignored unless `debug` is enabled (then failures
48
+ * are logged with `console.debug`).
49
+ */
50
+ preloadAllAssets(): Promise<void>;
44
51
  /**
45
52
  * Current clip key. Layered manifests use `characterState/action` (e.g. `neutral/idle`);
46
53
  * during a character-state transition the internal `__tr__/from/to` key may be returned.
package/dist/index.d.ts CHANGED
@@ -41,6 +41,13 @@ declare class CharacterPlayer {
41
41
  constructor(options: CharacterPlayerOptions);
42
42
  /** Create Pixi app, load first clip, append canvas. Call once. */
43
43
  init(): Promise<void>;
44
+ /**
45
+ * Fetches every texture URL from the manifest into Pixi’s asset cache so later clip changes
46
+ * reuse cached data instead of waiting on the network. Safe to call after {@link init}; does not
47
+ * change the current animation. Failed loads are ignored unless `debug` is enabled (then failures
48
+ * are logged with `console.debug`).
49
+ */
50
+ preloadAllAssets(): Promise<void>;
44
51
  /**
45
52
  * Current clip key. Layered manifests use `characterState/action` (e.g. `neutral/idle`);
46
53
  * during a character-state transition the internal `__tr__/from/to` key may be returned.
package/dist/index.js CHANGED
@@ -278,6 +278,19 @@ function joinBase(baseUrl, frame) {
278
278
  const base = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
279
279
  return new URL(frame, base).href;
280
280
  }
281
+ function collectManifestTextureUrls(flatStates, baseUrl) {
282
+ const seen = /* @__PURE__ */ new Set();
283
+ for (const cfg of Object.values(flatStates)) {
284
+ if (isGridSheetAnimation(cfg)) {
285
+ seen.add(joinBase(baseUrl, cfg.gridSheet.image));
286
+ } else {
287
+ for (const f of cfg.frames) {
288
+ seen.add(joinBase(baseUrl, f));
289
+ }
290
+ }
291
+ }
292
+ return [...seen];
293
+ }
281
294
  function validateGridSheetAgainstTexture(texWidth, texHeight, g) {
282
295
  const { frameWidth, frameHeight, columns, frameCount } = g;
283
296
  if (frameCount < 1) {
@@ -429,6 +442,27 @@ var CharacterPlayer = class {
429
442
  const start = this.currentFlatKey;
430
443
  await this.mountState(start);
431
444
  }
445
+ /**
446
+ * Fetches every texture URL from the manifest into Pixi’s asset cache so later clip changes
447
+ * reuse cached data instead of waiting on the network. Safe to call after {@link init}; does not
448
+ * change the current animation. Failed loads are ignored unless `debug` is enabled (then failures
449
+ * are logged with `console.debug`).
450
+ */
451
+ async preloadAllAssets() {
452
+ if (this.destroyed) {
453
+ return;
454
+ }
455
+ const urls = collectManifestTextureUrls(this.flatStates, this.baseUrl);
456
+ const results = await Promise.allSettled(urls.map((url) => Assets.load(url)));
457
+ if (!this.debug) {
458
+ return;
459
+ }
460
+ results.forEach((r, i) => {
461
+ if (r.status === "rejected") {
462
+ console.debug("[CharacterPlayer] preload failed", urls[i], r.reason);
463
+ }
464
+ });
465
+ }
432
466
  /**
433
467
  * Current clip key. Layered manifests use `characterState/action` (e.g. `neutral/idle`);
434
468
  * during a character-state transition the internal `__tr__/from/to` key may be returned.