cute-cube 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts","../src/manifest.ts","../src/core/CharacterPlayer.ts","../src/vue/index.ts"],"names":["h"],"mappings":"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","file":"vue.js","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","import {\n defineComponent,\n h,\n onBeforeUnmount,\n onMounted,\n ref,\n type PropType,\n} from \"vue\";\nimport { CharacterPlayer } from \"../core/CharacterPlayer.js\";\nimport type {\n CharacterManifest,\n CharacterPlayerOptions,\n CharacterPose,\n} from \"../types.js\";\n\nexport const CharacterView = defineComponent({\n name: \"CharacterView\",\n props: {\n manifest: { type: Object as PropType<CharacterManifest>, required: true },\n baseUrl: { type: String, required: true },\n initialState: String as PropType<string | undefined>,\n initialPose: Object as PropType<CharacterPose | undefined>,\n debug: Boolean as PropType<boolean | undefined>,\n transitionMs: Number as PropType<number | undefined>,\n fitPadding: Number as PropType<number | undefined>,\n characterWidth: Number as PropType<number | undefined>,\n characterHeight: Number as PropType<number | undefined>,\n queueStateUntilCycleEnd: Boolean as PropType<boolean | undefined>,\n },\n setup(props) {\n const el = ref<HTMLElement | null>(null);\n let player: CharacterPlayer | null = null;\n\n onMounted(async () => {\n if (!el.value) {\n return;\n }\n const options: CharacterPlayerOptions = {\n container: el.value,\n manifest: props.manifest,\n baseUrl: props.baseUrl,\n };\n if (props.initialState !== undefined) {\n options.initialState = props.initialState;\n }\n if (props.initialPose !== undefined) {\n options.initialPose = props.initialPose;\n }\n if (props.debug !== undefined) {\n options.debug = props.debug;\n }\n if (props.transitionMs !== undefined) {\n options.transitionMs = props.transitionMs;\n }\n if (props.fitPadding !== undefined) {\n options.fitPadding = props.fitPadding;\n }\n if (props.characterWidth !== undefined) {\n options.characterWidth = props.characterWidth;\n }\n if (props.characterHeight !== undefined) {\n options.characterHeight = props.characterHeight;\n }\n if (props.queueStateUntilCycleEnd !== undefined) {\n options.queueStateUntilCycleEnd = props.queueStateUntilCycleEnd;\n }\n player = new CharacterPlayer(options);\n await player.init();\n });\n\n onBeforeUnmount(() => {\n player?.destroy();\n player = null;\n });\n\n return () =>\n h(\"div\", {\n ref: el,\n style: {\n width: \"100%\",\n height: \"100%\",\n minHeight: \"240px\",\n },\n });\n },\n});\n\nexport default CharacterView;\n"]}
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "cute-cube",
3
+ "version": "0.1.0",
4
+ "description": "Framework-agnostic sprite character with named animation states (PixiJS)",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ },
20
+ "./vue": {
21
+ "import": {
22
+ "types": "./dist/vue.d.ts",
23
+ "default": "./dist/vue.js"
24
+ },
25
+ "require": {
26
+ "types": "./dist/vue.d.cts",
27
+ "default": "./dist/vue.cjs"
28
+ }
29
+ },
30
+ "./react": {
31
+ "import": {
32
+ "types": "./dist/react.d.ts",
33
+ "default": "./dist/react.js"
34
+ },
35
+ "require": {
36
+ "types": "./dist/react.d.cts",
37
+ "default": "./dist/react.cjs"
38
+ }
39
+ },
40
+ "./package.json": "./package.json"
41
+ },
42
+ "files": [
43
+ "dist",
44
+ "assets"
45
+ ],
46
+ "sideEffects": false,
47
+ "scripts": {
48
+ "build": "tsup",
49
+ "dev": "vite --config demo/vite.config.ts",
50
+ "build:demo": "vite build --config demo/vite.config.ts",
51
+ "preview": "vite preview --config demo/vite.config.ts",
52
+ "prepublishOnly": "npm run build"
53
+ },
54
+ "peerDependencies": {
55
+ "pixi.js": "^8.0.0",
56
+ "react": "^18.0.0 || ^19.0.0",
57
+ "react-dom": "^18.0.0 || ^19.0.0",
58
+ "vue": "^3.4.0"
59
+ },
60
+ "peerDependenciesMeta": {
61
+ "react": { "optional": true },
62
+ "react-dom": { "optional": true },
63
+ "vue": { "optional": true }
64
+ },
65
+ "devDependencies": {
66
+ "@types/react": "^19.0.0",
67
+ "@types/react-dom": "^19.0.0",
68
+ "@vitejs/plugin-react": "^4.3.4",
69
+ "@vitejs/plugin-vue": "^5.2.1",
70
+ "pixi.js": "^8.6.6",
71
+ "react": "^19.0.0",
72
+ "react-dom": "^19.0.0",
73
+ "tsup": "^8.3.5",
74
+ "typescript": "^5.7.2",
75
+ "vite": "^6.0.3",
76
+ "vue": "^3.5.13"
77
+ },
78
+ "keywords": [
79
+ "pixi",
80
+ "sprite",
81
+ "character",
82
+ "animation"
83
+ ],
84
+ "license": "MIT"
85
+ }