@pixi-ui-editor/runtime-pixi 0.20.0 → 0.21.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.
@@ -67,6 +67,11 @@ export declare function addPageGroupViewPage(view: Container, page: Container):
67
67
  export declare function setOpacityGroupViewOpacity(view: Container, opacity: number | undefined): void;
68
68
  /** Enables or pauses editor-only automatic playback without affecting serialized node data. */
69
69
  export declare function setSpineViewAutoplay(view: Container, autoplay: boolean): void;
70
+ /**
71
+ * Переопределяет авторскую длительность кроссфейда (в секундах) для всех последующих переходов
72
+ * этого скелета — включая те, что игра запускает своим `state.setAnimation`.
73
+ */
74
+ export declare function setSpineViewAnimationMix(view: Container, mix: number): void;
70
75
  /** Activates authored bone/slot part connectors on one Spine node without mutating the document. */
71
76
  export declare function setSpineConnectorBonesActive(view: Container, active: boolean): void;
72
77
  /** Reasserts active connector matrices after a host performs live node-view updates. */
@@ -1 +1 @@
1
- {"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../src/controls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAiBpC,0EAA0E;AAC1E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CASnJ;AAED,kHAAkH;AAClH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CASrH;AAED,qGAAqG;AACrG,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI,CAE/E;AAED,4GAA4G;AAC5G,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAE9E;AAED,+GAA+G;AAC/G,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAE7E;AAED,yGAAyG;AACzG,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI,CAErF;AAED,sGAAsG;AACtG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,GAAG,IAAI,CAEhF;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAEvE;AAED,6EAA6E;AAC7E,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAElF;AAED,yHAAyH;AACzH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAEzE;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAEnF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,EAAE,CAElE;AAED,qFAAqF;AACrF,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,EAAE,CAEzE;AAED,4FAA4F;AAC5F,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAE1F;AAED,yFAAyF;AACzF,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAE7F;AAED,+FAA+F;AAC/F,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAEhG;AAED,4NAA4N;AAC5N,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAExE;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAExE;AAED,iIAAiI;AACjI,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAEjE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAEzF;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAE7F;AAED,+FAA+F;AAC/F,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAG7E;AAED,oGAAoG;AACpG,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAEnF;AAED,wFAAwF;AACxF,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAI,CAE1F"}
1
+ {"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../src/controls.ts"],"names":[],"mappings":"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"}
package/dist/controls.js CHANGED
@@ -152,6 +152,15 @@ export function setSpineViewAutoplay(view, autoplay) {
152
152
  if (spine !== undefined)
153
153
  spine.autoUpdate = autoplay;
154
154
  }
155
+ /**
156
+ * Переопределяет авторскую длительность кроссфейда (в секундах) для всех последующих переходов
157
+ * этого скелета — включая те, что игра запускает своим `state.setAnimation`.
158
+ */
159
+ export function setSpineViewAnimationMix(view, mix) {
160
+ const spine = findSpineChild(view);
161
+ if (spine !== undefined)
162
+ spine.state.data.defaultMix = Math.max(0, mix);
163
+ }
155
164
  /** Activates authored bone/slot part connectors on one Spine node without mutating the document. */
156
165
  export function setSpineConnectorBonesActive(view, active) {
157
166
  if (view instanceof SpineNodeView)
@@ -1 +1 @@
1
- {"version":3,"file":"controls.js","sourceRoot":"","sources":["../src/controls.ts"],"names":[],"mappings":"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","sourcesContent":["import { type SkeletonData, Spine } from \"@esotericsoftware/spine-pixi-v8\";\nimport { type ButtonStateKey, type LayoutPadding } from \"@pixi-ui-editor/schema\";\nimport { Container } from \"pixi.js\";\nimport { ButtonNodeView } from \"./views/ButtonNodeView.js\";\nimport { CheckboxNodeView } from \"./views/CheckboxNodeView.js\";\nimport { ItemTableNodeView } from \"./views/ItemTableNodeView.js\";\nimport { PageGroupNodeView } from \"./views/PageGroupNodeView.js\";\nimport { PaginationNodeView } from \"./views/PaginationNodeView.js\";\nimport { StagedButtonNodeView } from \"./views/StagedButtonNodeView.js\";\nimport { ImageNodeView, OpacityGroupNodeView } from \"./views/basic.js\";\nimport { NodeView } from \"./views/NodeView.js\";\nimport { ProgressBarNodeView, SliderNodeView } from \"./views/ValueControlNodeViews.js\";\nimport { SpineNodeView } from \"./views/SpineNodeView.js\";\n\nfunction findSpineChild(view: Container): Spine | undefined {\n if (view instanceof NodeView) return view.getSpine();\n return view instanceof Spine ? view : view.children.find((child): child is Spine => child instanceof Spine);\n}\n\n/** Reads the current 1-based animation frame for an editor Spine node. */\nexport function getSpineViewPlayback(view: Container, skeletonData: SkeletonData, animation: string): { current: number; total: number } | undefined {\n const spine = findSpineChild(view);\n const track = spine?.state.tracks[0];\n const duration = skeletonData.findAnimation(animation)?.duration;\n if (track === null || track === undefined || duration === undefined || duration <= 0) return undefined;\n const fps = skeletonData.fps && skeletonData.fps > 0 ? skeletonData.fps : 60;\n const total = Math.max(1, Math.round(duration * fps));\n const time = track.loop ? track.trackTime % duration : Math.min(track.trackTime, duration);\n return { current: Math.min(total, Math.floor(time * fps) + 1), total };\n}\n\n/** Seeks an editor Spine node to a 1-based animation frame without changing its serialized animation settings. */\nexport function setSpineViewFrame(view: Container, frame: number, skeletonData: SkeletonData, animation: string): void {\n const spine = findSpineChild(view);\n const track = spine?.state.tracks[0];\n const duration = skeletonData.findAnimation(animation)?.duration;\n if (track === null || track === undefined || duration === undefined || duration <= 0) return;\n const fps = skeletonData.fps && skeletonData.fps > 0 ? skeletonData.fps : 60;\n const total = Math.max(1, Math.round(duration * fps));\n track.trackTime = Math.min(total, Math.max(1, Math.round(frame)) - 1) / fps;\n spine?.update(0);\n}\n\n/** Forces an editor-only button state; the node's serialized `enabled` and states stay untouched. */\nexport function setButtonViewState(view: Container, state: ButtonStateKey): void {\n if (view instanceof ButtonNodeView) view.setState(state);\n}\n\n/** Forces an editor-only checkbox checked state; the node's serialized `defaultChecked` stays untouched. */\nexport function setCheckboxViewChecked(view: Container, checked: boolean): void {\n if (view instanceof CheckboxNodeView) view.forceCheck(checked);\n}\n\n/** Forces an editor-only staged button preview stage; the document's `stages`/current stage stay untouched. */\nexport function setStagedButtonViewStage(view: Container, index: number): void {\n if (view instanceof StagedButtonNodeView) view.forceStage(index);\n}\n\n/** Forces an editor-only staged button visual state; the node's serialized `enabled` stays untouched. */\nexport function setStagedButtonViewState(view: Container, state: ButtonStateKey): void {\n if (view instanceof StagedButtonNodeView) view.setState(state);\n}\n\n/** Live-previews nine-slice border edits while dragging the canvas gizmo; commits only on release. */\nexport function previewNineSlice(view: Container, nineSlice: LayoutPadding): void {\n if (view instanceof ImageNodeView || view instanceof ButtonNodeView || view instanceof StagedButtonNodeView) view.previewNineSlice(nineSlice);\n}\n\n/** Applies an editor-only slider preview value without touching the document. */\nexport function setSliderViewValue(view: Container, value: number): void {\n if (view instanceof SliderNodeView) view.value = value;\n}\n\n/** Applies an editor-only progress preview without touching the document. */\nexport function setProgressBarViewProgress(view: Container, progress: number): void {\n if (view instanceof ProgressBarNodeView) view.progress = progress;\n}\n\n/** One-way sync from game code (or editor preview) into the widget: highlights a dot without emitting `onPageChange`. */\nexport function setPaginationViewPage(view: Container, page: number): void {\n if (view instanceof PaginationNodeView) view.page = page;\n}\n\n/**\n * Rebuilds the widget's dots for a runtime-known page count, e.g. once actual content length is known.\n * Ignored while the widget pages through authored `items`: there the item list already fixes the count.\n */\nexport function setPaginationViewPageCount(view: Container, pageCount: number): void {\n if (view instanceof PaginationNodeView) view.pageCount = pageCount;\n}\n\n/**\n * Все элементы таблицы в порядке иерархии, включая скрытые вместимостью — «что вообще есть».\n * Возвращает пустой список, если `view` не item-table.\n */\nexport function getItemTableViewItems(view: Container): Container[] {\n return view instanceof ItemTableNodeView ? view.items : [];\n}\n\n/** Элементы, показанные прямо сейчас: столько, сколько влезает в текущем профиле. */\nexport function getItemTableViewVisibleItems(view: Container): Container[] {\n return view instanceof ItemTableNodeView ? view.visibleItems : [];\n}\n\n/** Один элемент по индексу — адресация, на которой игровой код раскладывает свои данные. */\nexport function getItemTableViewItem(view: Container, index: number): Container | undefined {\n return view instanceof ItemTableNodeView ? view.itemAt(index) : undefined;\n}\n\n/** Транзиентно меняет вместимость; `undefined` возвращает авторское значение профиля. */\nexport function setItemTableViewVisibleCount(view: Container, count: number | undefined): void {\n if (view instanceof ItemTableNodeView) view.visibleCount = count;\n}\n\n/** Показывает или прячет все элементы разом; `undefined` возвращает управление вместимости. */\nexport function setItemTableViewItemsVisible(view: Container, visible: boolean | undefined): void {\n if (view instanceof ItemTableNodeView) view.setItemsVisible(visible);\n}\n\n/** Switches which direct child (\"page\") of a page group is shown; every other child is hidden. Out-of-range indices clamp into range, so passing whatever a caller has on hand can never throw or leave the group blank. */\nexport function setPageGroupViewPage(view: Container, page: number): void {\n if (view instanceof PageGroupNodeView) view.page = page;\n}\n\n/** Currently shown page index, or `undefined` if `view` is not a page group. */\nexport function getPageGroupViewPage(view: Container): number | undefined {\n return view instanceof PageGroupNodeView ? view.page : undefined;\n}\n\n/** Total number of pages (authored children plus any appended via `addPageGroupViewPage`); `0` if `view` is not a page group. */\nexport function getPageGroupViewPageCount(view: Container): number {\n return view instanceof PageGroupNodeView ? view.pageCount : 0;\n}\n\n/**\n * Appends a page built at runtime (e.g. the `root` from `buildPrefabView`/`loadPrefabView`, or any\n * hand-built `Container`) after the last one — for a dataset that grows during play (a spin history\n * list, a chat log, ...) rather than one fully known at authoring time. Fits the page to the group's\n * current rectangle and hides it until switched to. Returns the new page's index, or `undefined` if\n * `view` is not a page group. Keep `setPaginationViewPageCount` in sync with the resulting `pageCount`\n * if a `pagination` widget is showing this group's page count.\n */\nexport function addPageGroupViewPage(view: Container, page: Container): number | undefined {\n return view instanceof PageGroupNodeView ? view.addPage(page) : undefined;\n}\n\n/**\n * Fades a whole subtree by driving one opacity group, the cheap `CanvasGroup.alpha` equivalent: the\n * value multiplies into every descendant through PixiJS `worldAlpha`, so animating a fade is one write\n * per frame regardless of how many nodes are inside. The node's authored `opacity` stays untouched in\n * the document; pass `undefined` to hand control back to it. Tweening itself belongs to game code —\n * the runtime deliberately ships no animation engine, the same way `page-group` ships no swipe gesture.\n */\nexport function setOpacityGroupViewOpacity(view: Container, opacity: number | undefined): void {\n if (view instanceof OpacityGroupNodeView) view.setOpacity(opacity);\n}\n\n/** Enables or pauses editor-only automatic playback without affecting serialized node data. */\nexport function setSpineViewAutoplay(view: Container, autoplay: boolean): void {\n const spine = findSpineChild(view);\n if (spine !== undefined) spine.autoUpdate = autoplay;\n}\n\n/** Activates authored bone/slot part connectors on one Spine node without mutating the document. */\nexport function setSpineConnectorBonesActive(view: Container, active: boolean): void {\n if (view instanceof SpineNodeView) view.activeConnectorBones = active;\n}\n\n/** Reasserts active connector matrices after a host performs live node-view updates. */\nexport function refreshSpineConnectorBones(nodeViews: ReadonlyMap<string, Container>): void {\n for (const view of nodeViews.values()) if (view instanceof SpineNodeView && view.activeConnectorBones) view.refreshConnectorBones();\n}\n"]}
1
+ {"version":3,"file":"controls.js","sourceRoot":"","sources":["../src/controls.ts"],"names":[],"mappings":"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","sourcesContent":["import { type SkeletonData, Spine } from \"@esotericsoftware/spine-pixi-v8\";\nimport { type ButtonStateKey, type LayoutPadding } from \"@pixi-ui-editor/schema\";\nimport { Container } from \"pixi.js\";\nimport { ButtonNodeView } from \"./views/ButtonNodeView.js\";\nimport { CheckboxNodeView } from \"./views/CheckboxNodeView.js\";\nimport { ItemTableNodeView } from \"./views/ItemTableNodeView.js\";\nimport { PageGroupNodeView } from \"./views/PageGroupNodeView.js\";\nimport { PaginationNodeView } from \"./views/PaginationNodeView.js\";\nimport { StagedButtonNodeView } from \"./views/StagedButtonNodeView.js\";\nimport { ImageNodeView, OpacityGroupNodeView } from \"./views/basic.js\";\nimport { NodeView } from \"./views/NodeView.js\";\nimport { ProgressBarNodeView, SliderNodeView } from \"./views/ValueControlNodeViews.js\";\nimport { SpineNodeView } from \"./views/SpineNodeView.js\";\n\nfunction findSpineChild(view: Container): Spine | undefined {\n if (view instanceof NodeView) return view.getSpine();\n return view instanceof Spine ? view : view.children.find((child): child is Spine => child instanceof Spine);\n}\n\n/** Reads the current 1-based animation frame for an editor Spine node. */\nexport function getSpineViewPlayback(view: Container, skeletonData: SkeletonData, animation: string): { current: number; total: number } | undefined {\n const spine = findSpineChild(view);\n const track = spine?.state.tracks[0];\n const duration = skeletonData.findAnimation(animation)?.duration;\n if (track === null || track === undefined || duration === undefined || duration <= 0) return undefined;\n const fps = skeletonData.fps && skeletonData.fps > 0 ? skeletonData.fps : 60;\n const total = Math.max(1, Math.round(duration * fps));\n const time = track.loop ? track.trackTime % duration : Math.min(track.trackTime, duration);\n return { current: Math.min(total, Math.floor(time * fps) + 1), total };\n}\n\n/** Seeks an editor Spine node to a 1-based animation frame without changing its serialized animation settings. */\nexport function setSpineViewFrame(view: Container, frame: number, skeletonData: SkeletonData, animation: string): void {\n const spine = findSpineChild(view);\n const track = spine?.state.tracks[0];\n const duration = skeletonData.findAnimation(animation)?.duration;\n if (track === null || track === undefined || duration === undefined || duration <= 0) return;\n const fps = skeletonData.fps && skeletonData.fps > 0 ? skeletonData.fps : 60;\n const total = Math.max(1, Math.round(duration * fps));\n track.trackTime = Math.min(total, Math.max(1, Math.round(frame)) - 1) / fps;\n spine?.update(0);\n}\n\n/** Forces an editor-only button state; the node's serialized `enabled` and states stay untouched. */\nexport function setButtonViewState(view: Container, state: ButtonStateKey): void {\n if (view instanceof ButtonNodeView) view.setState(state);\n}\n\n/** Forces an editor-only checkbox checked state; the node's serialized `defaultChecked` stays untouched. */\nexport function setCheckboxViewChecked(view: Container, checked: boolean): void {\n if (view instanceof CheckboxNodeView) view.forceCheck(checked);\n}\n\n/** Forces an editor-only staged button preview stage; the document's `stages`/current stage stay untouched. */\nexport function setStagedButtonViewStage(view: Container, index: number): void {\n if (view instanceof StagedButtonNodeView) view.forceStage(index);\n}\n\n/** Forces an editor-only staged button visual state; the node's serialized `enabled` stays untouched. */\nexport function setStagedButtonViewState(view: Container, state: ButtonStateKey): void {\n if (view instanceof StagedButtonNodeView) view.setState(state);\n}\n\n/** Live-previews nine-slice border edits while dragging the canvas gizmo; commits only on release. */\nexport function previewNineSlice(view: Container, nineSlice: LayoutPadding): void {\n if (view instanceof ImageNodeView || view instanceof ButtonNodeView || view instanceof StagedButtonNodeView) view.previewNineSlice(nineSlice);\n}\n\n/** Applies an editor-only slider preview value without touching the document. */\nexport function setSliderViewValue(view: Container, value: number): void {\n if (view instanceof SliderNodeView) view.value = value;\n}\n\n/** Applies an editor-only progress preview without touching the document. */\nexport function setProgressBarViewProgress(view: Container, progress: number): void {\n if (view instanceof ProgressBarNodeView) view.progress = progress;\n}\n\n/** One-way sync from game code (or editor preview) into the widget: highlights a dot without emitting `onPageChange`. */\nexport function setPaginationViewPage(view: Container, page: number): void {\n if (view instanceof PaginationNodeView) view.page = page;\n}\n\n/**\n * Rebuilds the widget's dots for a runtime-known page count, e.g. once actual content length is known.\n * Ignored while the widget pages through authored `items`: there the item list already fixes the count.\n */\nexport function setPaginationViewPageCount(view: Container, pageCount: number): void {\n if (view instanceof PaginationNodeView) view.pageCount = pageCount;\n}\n\n/**\n * Все элементы таблицы в порядке иерархии, включая скрытые вместимостью — «что вообще есть».\n * Возвращает пустой список, если `view` не item-table.\n */\nexport function getItemTableViewItems(view: Container): Container[] {\n return view instanceof ItemTableNodeView ? view.items : [];\n}\n\n/** Элементы, показанные прямо сейчас: столько, сколько влезает в текущем профиле. */\nexport function getItemTableViewVisibleItems(view: Container): Container[] {\n return view instanceof ItemTableNodeView ? view.visibleItems : [];\n}\n\n/** Один элемент по индексу — адресация, на которой игровой код раскладывает свои данные. */\nexport function getItemTableViewItem(view: Container, index: number): Container | undefined {\n return view instanceof ItemTableNodeView ? view.itemAt(index) : undefined;\n}\n\n/** Транзиентно меняет вместимость; `undefined` возвращает авторское значение профиля. */\nexport function setItemTableViewVisibleCount(view: Container, count: number | undefined): void {\n if (view instanceof ItemTableNodeView) view.visibleCount = count;\n}\n\n/** Показывает или прячет все элементы разом; `undefined` возвращает управление вместимости. */\nexport function setItemTableViewItemsVisible(view: Container, visible: boolean | undefined): void {\n if (view instanceof ItemTableNodeView) view.setItemsVisible(visible);\n}\n\n/** Switches which direct child (\"page\") of a page group is shown; every other child is hidden. Out-of-range indices clamp into range, so passing whatever a caller has on hand can never throw or leave the group blank. */\nexport function setPageGroupViewPage(view: Container, page: number): void {\n if (view instanceof PageGroupNodeView) view.page = page;\n}\n\n/** Currently shown page index, or `undefined` if `view` is not a page group. */\nexport function getPageGroupViewPage(view: Container): number | undefined {\n return view instanceof PageGroupNodeView ? view.page : undefined;\n}\n\n/** Total number of pages (authored children plus any appended via `addPageGroupViewPage`); `0` if `view` is not a page group. */\nexport function getPageGroupViewPageCount(view: Container): number {\n return view instanceof PageGroupNodeView ? view.pageCount : 0;\n}\n\n/**\n * Appends a page built at runtime (e.g. the `root` from `buildPrefabView`/`loadPrefabView`, or any\n * hand-built `Container`) after the last one — for a dataset that grows during play (a spin history\n * list, a chat log, ...) rather than one fully known at authoring time. Fits the page to the group's\n * current rectangle and hides it until switched to. Returns the new page's index, or `undefined` if\n * `view` is not a page group. Keep `setPaginationViewPageCount` in sync with the resulting `pageCount`\n * if a `pagination` widget is showing this group's page count.\n */\nexport function addPageGroupViewPage(view: Container, page: Container): number | undefined {\n return view instanceof PageGroupNodeView ? view.addPage(page) : undefined;\n}\n\n/**\n * Fades a whole subtree by driving one opacity group, the cheap `CanvasGroup.alpha` equivalent: the\n * value multiplies into every descendant through PixiJS `worldAlpha`, so animating a fade is one write\n * per frame regardless of how many nodes are inside. The node's authored `opacity` stays untouched in\n * the document; pass `undefined` to hand control back to it. Tweening itself belongs to game code —\n * the runtime deliberately ships no animation engine, the same way `page-group` ships no swipe gesture.\n */\nexport function setOpacityGroupViewOpacity(view: Container, opacity: number | undefined): void {\n if (view instanceof OpacityGroupNodeView) view.setOpacity(opacity);\n}\n\n/** Enables or pauses editor-only automatic playback without affecting serialized node data. */\nexport function setSpineViewAutoplay(view: Container, autoplay: boolean): void {\n const spine = findSpineChild(view);\n if (spine !== undefined) spine.autoUpdate = autoplay;\n}\n\n/**\n * Переопределяет авторскую длительность кроссфейда (в секундах) для всех последующих переходов\n * этого скелета — включая те, что игра запускает своим `state.setAnimation`.\n */\nexport function setSpineViewAnimationMix(view: Container, mix: number): void {\n const spine = findSpineChild(view);\n if (spine !== undefined) spine.state.data.defaultMix = Math.max(0, mix);\n}\n\n/** Activates authored bone/slot part connectors on one Spine node without mutating the document. */\nexport function setSpineConnectorBonesActive(view: Container, active: boolean): void {\n if (view instanceof SpineNodeView) view.activeConnectorBones = active;\n}\n\n/** Reasserts active connector matrices after a host performs live node-view updates. */\nexport function refreshSpineConnectorBones(nodeViews: ReadonlyMap<string, Container>): void {\n for (const view of nodeViews.values()) if (view instanceof SpineNodeView && view.activeConnectorBones) view.refreshConnectorBones();\n}\n"]}
package/dist/layout.d.ts CHANGED
@@ -22,6 +22,7 @@ export type ResolvedSpineSettings = {
22
22
  autoplay: boolean;
23
23
  loop: boolean;
24
24
  animationSpeed: number;
25
+ animationMix: number;
25
26
  };
26
27
  export declare const DEFAULT_TEXT_STYLE: TextStyleDefinition;
27
28
  export declare const CANVAS_SCALER_MATCH_WIDTH_OR_HEIGHT = 0.5;
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"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"}
package/dist/layout.js CHANGED
@@ -73,6 +73,7 @@ export function resolveSpineSettings(node, profile) {
73
73
  autoplay: override?.autoplay ?? node.autoplay ?? true,
74
74
  loop: override?.loop ?? node.loop ?? true,
75
75
  animationSpeed: override?.animationSpeed ?? node.animationSpeed ?? 1,
76
+ animationMix: override?.animationMix ?? node.animationMix ?? 0,
76
77
  };
77
78
  }
78
79
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"layout.js","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"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","sourcesContent":["import { type BitmapTextNode, type BitmapTextStyle, type LayoutProfileId, type ProjectDocument, type SpineReferenceFrame, type TextNode, type TextStyleDefinition, type UINode } from \"@pixi-ui-editor/schema\";\n\r\nexport type ResolvedProfileTransform = {\r\n transform: UINode[\"transform\"];\r\n visible: boolean;\r\n};\r\n\r\nexport type LayoutSize = { width: number; height: number };\n\nexport type FittedViewport = {\n scale: number;\n x: number;\n y: number;\n width: number;\n height: number;\n};\n\r\ntype SpineNode = Extract<UINode, { type: \"spine\" }>;\r\nexport type ResolvedSpineSettings = { animation: string | undefined; autoplay: boolean; loop: boolean; animationSpeed: number };\r\n\r\nexport const DEFAULT_TEXT_STYLE: TextStyleDefinition = {\r\n fontFamily: \"Arial\", fontSize: 24, fontWeight: \"normal\", fontStyle: \"normal\", fill: \"#FFFFFF\",\r\n align: \"left\", verticalAlign: \"top\", wordWrap: false, breakWords: false, letterSpacing: 0,\r\n};\r\n\r\nexport const CANVAS_SCALER_MATCH_WIDTH_OR_HEIGHT = 0.5;\nconst PROFILE_BREAKPOINT_HYSTERESIS = 0.05;\n\n/**\n * Uniformly contains an authored viewport inside a physical host without changing its aspect ratio.\n * Low-level primitive: callers with host measurements should use `resolveViewport`, which rejects\n * zero, non-finite, and otherwise degenerate sizes before any profile or fit is computed.\n */\nexport function fitViewportToHost(viewport: LayoutSize, host: LayoutSize): FittedViewport {\n const scale = Math.min(host.width / viewport.width, host.height / viewport.height);\n const width = viewport.width * scale;\n const height = viewport.height * scale;\n return {\n scale,\n x: (host.width - width) / 2,\n y: (host.height - height) / 2,\n width,\n height,\n };\n}\n\r\n/**\r\n * Unity Canvas Scaler's `Scale With Screen Size / Match Width Or Height` calculation.\r\n * Width and height are blended in logarithmic space, producing one uniform scale for the Canvas.\r\n */\r\nexport function getCanvasScale(\r\n screenSize: LayoutSize,\r\n referenceResolution: LayoutSize,\r\n matchWidthOrHeight = CANVAS_SCALER_MATCH_WIDTH_OR_HEIGHT,\r\n): number {\r\n const widthScale = screenSize.width / referenceResolution.width;\r\n const heightScale = screenSize.height / referenceResolution.height;\r\n const logWidth = Math.log2(widthScale);\r\n const logHeight = Math.log2(heightScale);\r\n return 2 ** (logWidth + (logHeight - logWidth) * matchWidthOrHeight);\r\n}\r\n\r\n/** Logical RectTransform space exposed by a scaled Canvas at the current screen aspect ratio. */\r\nexport function getCanvasLogicalSize(screenSize: LayoutSize, referenceResolution: LayoutSize): LayoutSize {\r\n const scale = getCanvasScale(screenSize, referenceResolution);\r\n return { width: screenSize.width / scale, height: screenSize.height / scale };\r\n}\r\n\r\n/** Resolves a node's base transform with a profile override applied field by field. */\r\nexport function resolveProfileTransform(node: UINode, profile: LayoutProfileId): ResolvedProfileTransform {\r\n const override = node.layoutOverrides?.[profile];\r\n\r\n return {\r\n transform: { ...node.transform, ...override?.transform },\r\n visible: override?.visible ?? node.visible,\r\n };\r\n}\r\n\r\n/** Resolves a text node's optional base style with the active profile's sparse style override. */\r\nexport function resolveTextStyle(node: TextNode, profile: LayoutProfileId): TextStyleDefinition | undefined {\n const override = node.textStyleOverrides?.[profile];\r\n if (node.style === undefined && override === undefined) return undefined;\r\n return { ...DEFAULT_TEXT_STYLE, ...node.style, ...override };\r\n}\n\n/** Resolves bitmap text's base visual presentation with the active sparse profile override. */\nexport function resolveBitmapTextStyle(node: BitmapTextNode, profile: LayoutProfileId): BitmapTextStyle {\n return {\n assetId: node.assetId,\n fontSize: node.fontSize,\n fill: node.fill,\n align: node.align,\n verticalAlign: node.verticalAlign,\n letterSpacing: node.letterSpacing,\n wordWrap: node.wordWrap,\n ...node.bitmapTextOverrides?.[profile],\n };\n}\n\r\n/** Resolves the authored initial Spine presentation; `null` explicitly clears a base animation. */\r\nexport function resolveSpineSettings(node: SpineNode, profile: LayoutProfileId): ResolvedSpineSettings {\r\n const override = node.spineOverrides?.[profile];\r\n return {\r\n animation: override?.animation === null ? undefined : override?.animation ?? node.animation,\r\n autoplay: override?.autoplay ?? node.autoplay ?? true,\r\n loop: override?.loop ?? node.loop ?? true,\r\n animationSpeed: override?.animationSpeed ?? node.animationSpeed ?? 1,\r\n };\r\n}\r\n\r\n/**\r\n * Resolves a Unity-style RectTransform in logical Canvas units.\r\n *\r\n * `x/y` are anchoredPosition (the pivot offset from the anchor reference), while `width/height`\r\n * are sizeDelta. A point anchor therefore keeps an absolute logical size; a split anchor adds its\r\n * share of the parent rectangle. Canvas Scaler is deliberately outside this function.\r\n */\r\nexport function resolveAnchoredTransform(transform: UINode[\"transform\"], parentSize?: LayoutSize): UINode[\"transform\"] {\r\n if (parentSize === undefined) return transform;\r\n const minX = transform.anchorMinX ?? 0;\r\n const minY = transform.anchorMinY ?? 0;\r\n const maxX = transform.anchorMaxX ?? minX;\r\n const maxY = transform.anchorMaxY ?? minY;\r\n const pivotX = transform.pivotX ?? 0;\r\n const pivotY = transform.pivotY ?? 0;\r\n return {\r\n ...transform,\r\n x: (minX + (maxX - minX) * pivotX) * parentSize.width + transform.x,\r\n y: (minY + (maxY - minY) * pivotY) * parentSize.height + transform.y,\r\n width: (maxX - minX) * parentSize.width + transform.width,\r\n height: (maxY - minY) * parentSize.height + transform.height,\r\n };\r\n}\r\n\r\n/** True when a viewport can safely participate in aspect-ratio and transform calculations. */\nexport function isUsableViewport(size: LayoutSize): boolean {\n return Number.isFinite(size.width) && size.width > 0 && Number.isFinite(size.height) && size.height > 0;\n}\n\n/**\n * Picks the layout profile using the document's aspect-ratio rule; the breakpoint itself is mobile.\n * Low-level primitive: it deliberately preserves the legacy result for degenerate numbers. Host code\n * should use `resolveViewport` instead. Passing `current` adds a five-percent dead zone around the\n * breakpoint so small resize oscillations do not repeatedly flip an already-live scene.\n */\nexport function resolveProfileForViewport(settings: ProjectDocument[\"settings\"], width: number, height: number, current?: LayoutProfileId): LayoutProfileId {\n const breakpoint = settings.layoutProfileSelection.mobileMaxAspectRatio;\n const aspectRatio = width / height;\n if (current === \"mobile\" && aspectRatio <= breakpoint * (1 + PROFILE_BREAKPOINT_HYSTERESIS)) return current;\n if (current === \"desktop\" && aspectRatio > breakpoint * (1 - PROFILE_BREAKPOINT_HYSTERESIS)) return current;\n return aspectRatio <= breakpoint ? \"mobile\" : \"desktop\";\n}\n\n/** Safely resolves both the selected profile and contain-fit for a measured host. */\nexport function resolveViewport(\n settings: ProjectDocument[\"settings\"],\n referenceViewport: LayoutSize | Record<LayoutProfileId, LayoutSize>,\n host: LayoutSize,\n current?: LayoutProfileId,\n): { profile: LayoutProfileId; fit: FittedViewport } | null {\n if (!isUsableViewport(host)) return null;\n const profile = resolveProfileForViewport(settings, host.width, host.height, current);\n const selectedReference = \"width\" in referenceViewport ? referenceViewport : referenceViewport[profile];\n if (!isUsableViewport(selectedReference)) return null;\n return { profile, fit: fitViewportToHost(selectedReference, host) };\n}\n\r\nexport function fitSpineToTransform(\r\n bounds: { x: number; y: number; width: number; height: number },\r\n transform: UINode[\"transform\"],\r\n referenceFrame?: SpineReferenceFrame,\r\n): { scaleX: number; scaleY: number; x: number; y: number } | undefined {\r\n const fitBounds = referenceFrame ?? bounds;\r\n if (!Number.isFinite(fitBounds.x) || !Number.isFinite(fitBounds.y) || !Number.isFinite(fitBounds.width) || !Number.isFinite(fitBounds.height) || fitBounds.width <= 0 || fitBounds.height <= 0) return undefined;\r\n if (referenceFrame !== undefined) {\r\n const scale = Math.min(transform.width / referenceFrame.width, transform.height / referenceFrame.height);\r\n return Number.isFinite(scale) && scale > 0\r\n ? {\r\n scaleX: scale,\r\n scaleY: scale,\r\n x: (transform.width - referenceFrame.width * scale) / 2 - referenceFrame.x * scale,\r\n y: (transform.height - referenceFrame.height * scale) / 2 - referenceFrame.y * scale,\r\n }\r\n : undefined;\r\n }\r\n const scaleX = transform.width / bounds.width;\r\n const scaleY = transform.height / bounds.height;\r\n return Number.isFinite(scaleX) && scaleX > 0 && Number.isFinite(scaleY) && scaleY > 0\r\n ? { scaleX, scaleY, x: -bounds.x * scaleX, y: -bounds.y * scaleY }\r\n : undefined;\r\n}\r\n"]}
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"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","sourcesContent":["import { type BitmapTextNode, type BitmapTextStyle, type LayoutProfileId, type ProjectDocument, type SpineReferenceFrame, type TextNode, type TextStyleDefinition, type UINode } from \"@pixi-ui-editor/schema\";\r\n\r\nexport type ResolvedProfileTransform = {\r\n transform: UINode[\"transform\"];\r\n visible: boolean;\r\n};\r\n\r\nexport type LayoutSize = { width: number; height: number };\r\n\r\nexport type FittedViewport = {\r\n scale: number;\r\n x: number;\r\n y: number;\r\n width: number;\r\n height: number;\r\n};\r\n\r\ntype SpineNode = Extract<UINode, { type: \"spine\" }>;\r\nexport type ResolvedSpineSettings = { animation: string | undefined; autoplay: boolean; loop: boolean; animationSpeed: number; animationMix: number };\r\n\r\nexport const DEFAULT_TEXT_STYLE: TextStyleDefinition = {\r\n fontFamily: \"Arial\", fontSize: 24, fontWeight: \"normal\", fontStyle: \"normal\", fill: \"#FFFFFF\",\r\n align: \"left\", verticalAlign: \"top\", wordWrap: false, breakWords: false, letterSpacing: 0,\r\n};\r\n\r\nexport const CANVAS_SCALER_MATCH_WIDTH_OR_HEIGHT = 0.5;\r\nconst PROFILE_BREAKPOINT_HYSTERESIS = 0.05;\r\n\r\n/**\r\n * Uniformly contains an authored viewport inside a physical host without changing its aspect ratio.\r\n * Low-level primitive: callers with host measurements should use `resolveViewport`, which rejects\r\n * zero, non-finite, and otherwise degenerate sizes before any profile or fit is computed.\r\n */\r\nexport function fitViewportToHost(viewport: LayoutSize, host: LayoutSize): FittedViewport {\r\n const scale = Math.min(host.width / viewport.width, host.height / viewport.height);\r\n const width = viewport.width * scale;\r\n const height = viewport.height * scale;\r\n return {\r\n scale,\r\n x: (host.width - width) / 2,\r\n y: (host.height - height) / 2,\r\n width,\r\n height,\r\n };\r\n}\r\n\r\n/**\r\n * Unity Canvas Scaler's `Scale With Screen Size / Match Width Or Height` calculation.\r\n * Width and height are blended in logarithmic space, producing one uniform scale for the Canvas.\r\n */\r\nexport function getCanvasScale(\r\n screenSize: LayoutSize,\r\n referenceResolution: LayoutSize,\r\n matchWidthOrHeight = CANVAS_SCALER_MATCH_WIDTH_OR_HEIGHT,\r\n): number {\r\n const widthScale = screenSize.width / referenceResolution.width;\r\n const heightScale = screenSize.height / referenceResolution.height;\r\n const logWidth = Math.log2(widthScale);\r\n const logHeight = Math.log2(heightScale);\r\n return 2 ** (logWidth + (logHeight - logWidth) * matchWidthOrHeight);\r\n}\r\n\r\n/** Logical RectTransform space exposed by a scaled Canvas at the current screen aspect ratio. */\r\nexport function getCanvasLogicalSize(screenSize: LayoutSize, referenceResolution: LayoutSize): LayoutSize {\r\n const scale = getCanvasScale(screenSize, referenceResolution);\r\n return { width: screenSize.width / scale, height: screenSize.height / scale };\r\n}\r\n\r\n/** Resolves a node's base transform with a profile override applied field by field. */\r\nexport function resolveProfileTransform(node: UINode, profile: LayoutProfileId): ResolvedProfileTransform {\r\n const override = node.layoutOverrides?.[profile];\r\n\r\n return {\r\n transform: { ...node.transform, ...override?.transform },\r\n visible: override?.visible ?? node.visible,\r\n };\r\n}\r\n\r\n/** Resolves a text node's optional base style with the active profile's sparse style override. */\r\nexport function resolveTextStyle(node: TextNode, profile: LayoutProfileId): TextStyleDefinition | undefined {\r\n const override = node.textStyleOverrides?.[profile];\r\n if (node.style === undefined && override === undefined) return undefined;\r\n return { ...DEFAULT_TEXT_STYLE, ...node.style, ...override };\r\n}\r\n\r\n/** Resolves bitmap text's base visual presentation with the active sparse profile override. */\r\nexport function resolveBitmapTextStyle(node: BitmapTextNode, profile: LayoutProfileId): BitmapTextStyle {\r\n return {\r\n assetId: node.assetId,\r\n fontSize: node.fontSize,\r\n fill: node.fill,\r\n align: node.align,\r\n verticalAlign: node.verticalAlign,\r\n letterSpacing: node.letterSpacing,\r\n wordWrap: node.wordWrap,\r\n ...node.bitmapTextOverrides?.[profile],\r\n };\r\n}\r\n\r\n/** Resolves the authored initial Spine presentation; `null` explicitly clears a base animation. */\r\nexport function resolveSpineSettings(node: SpineNode, profile: LayoutProfileId): ResolvedSpineSettings {\r\n const override = node.spineOverrides?.[profile];\r\n return {\r\n animation: override?.animation === null ? undefined : override?.animation ?? node.animation,\r\n autoplay: override?.autoplay ?? node.autoplay ?? true,\r\n loop: override?.loop ?? node.loop ?? true,\r\n animationSpeed: override?.animationSpeed ?? node.animationSpeed ?? 1,\r\n animationMix: override?.animationMix ?? node.animationMix ?? 0,\r\n };\r\n}\r\n\r\n/**\r\n * Resolves a Unity-style RectTransform in logical Canvas units.\r\n *\r\n * `x/y` are anchoredPosition (the pivot offset from the anchor reference), while `width/height`\r\n * are sizeDelta. A point anchor therefore keeps an absolute logical size; a split anchor adds its\r\n * share of the parent rectangle. Canvas Scaler is deliberately outside this function.\r\n */\r\nexport function resolveAnchoredTransform(transform: UINode[\"transform\"], parentSize?: LayoutSize): UINode[\"transform\"] {\r\n if (parentSize === undefined) return transform;\r\n const minX = transform.anchorMinX ?? 0;\r\n const minY = transform.anchorMinY ?? 0;\r\n const maxX = transform.anchorMaxX ?? minX;\r\n const maxY = transform.anchorMaxY ?? minY;\r\n const pivotX = transform.pivotX ?? 0;\r\n const pivotY = transform.pivotY ?? 0;\r\n return {\r\n ...transform,\r\n x: (minX + (maxX - minX) * pivotX) * parentSize.width + transform.x,\r\n y: (minY + (maxY - minY) * pivotY) * parentSize.height + transform.y,\r\n width: (maxX - minX) * parentSize.width + transform.width,\r\n height: (maxY - minY) * parentSize.height + transform.height,\r\n };\r\n}\r\n\r\n/** True when a viewport can safely participate in aspect-ratio and transform calculations. */\r\nexport function isUsableViewport(size: LayoutSize): boolean {\r\n return Number.isFinite(size.width) && size.width > 0 && Number.isFinite(size.height) && size.height > 0;\r\n}\r\n\r\n/**\r\n * Picks the layout profile using the document's aspect-ratio rule; the breakpoint itself is mobile.\r\n * Low-level primitive: it deliberately preserves the legacy result for degenerate numbers. Host code\r\n * should use `resolveViewport` instead. Passing `current` adds a five-percent dead zone around the\r\n * breakpoint so small resize oscillations do not repeatedly flip an already-live scene.\r\n */\r\nexport function resolveProfileForViewport(settings: ProjectDocument[\"settings\"], width: number, height: number, current?: LayoutProfileId): LayoutProfileId {\r\n const breakpoint = settings.layoutProfileSelection.mobileMaxAspectRatio;\r\n const aspectRatio = width / height;\r\n if (current === \"mobile\" && aspectRatio <= breakpoint * (1 + PROFILE_BREAKPOINT_HYSTERESIS)) return current;\r\n if (current === \"desktop\" && aspectRatio > breakpoint * (1 - PROFILE_BREAKPOINT_HYSTERESIS)) return current;\r\n return aspectRatio <= breakpoint ? \"mobile\" : \"desktop\";\r\n}\r\n\r\n/** Safely resolves both the selected profile and contain-fit for a measured host. */\r\nexport function resolveViewport(\r\n settings: ProjectDocument[\"settings\"],\r\n referenceViewport: LayoutSize | Record<LayoutProfileId, LayoutSize>,\r\n host: LayoutSize,\r\n current?: LayoutProfileId,\r\n): { profile: LayoutProfileId; fit: FittedViewport } | null {\r\n if (!isUsableViewport(host)) return null;\r\n const profile = resolveProfileForViewport(settings, host.width, host.height, current);\r\n const selectedReference = \"width\" in referenceViewport ? referenceViewport : referenceViewport[profile];\r\n if (!isUsableViewport(selectedReference)) return null;\r\n return { profile, fit: fitViewportToHost(selectedReference, host) };\r\n}\r\n\r\nexport function fitSpineToTransform(\r\n bounds: { x: number; y: number; width: number; height: number },\r\n transform: UINode[\"transform\"],\r\n referenceFrame?: SpineReferenceFrame,\r\n): { scaleX: number; scaleY: number; x: number; y: number } | undefined {\r\n const fitBounds = referenceFrame ?? bounds;\r\n if (!Number.isFinite(fitBounds.x) || !Number.isFinite(fitBounds.y) || !Number.isFinite(fitBounds.width) || !Number.isFinite(fitBounds.height) || fitBounds.width <= 0 || fitBounds.height <= 0) return undefined;\r\n if (referenceFrame !== undefined) {\r\n const scale = Math.min(transform.width / referenceFrame.width, transform.height / referenceFrame.height);\r\n return Number.isFinite(scale) && scale > 0\r\n ? {\r\n scaleX: scale,\r\n scaleY: scale,\r\n x: (transform.width - referenceFrame.width * scale) / 2 - referenceFrame.x * scale,\r\n y: (transform.height - referenceFrame.height * scale) / 2 - referenceFrame.y * scale,\r\n }\r\n : undefined;\r\n }\r\n const scaleX = transform.width / bounds.width;\r\n const scaleY = transform.height / bounds.height;\r\n return Number.isFinite(scaleX) && scaleX > 0 && Number.isFinite(scaleY) && scaleY > 0\r\n ? { scaleX, scaleY, x: -bounds.x * scaleX, y: -bounds.y * scaleY }\r\n : undefined;\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ButtonNodeView.d.ts","sourceRoot":"","sources":["../../src/views/ButtonNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACjH,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAgD,OAAO,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,EAAE,QAAQ,EAAE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAC;AAK7D;;;;;;;;GAQG;AACH,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,YAAY,CAAU;IAE9B,YAAY,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,WAAW,EAAE,oBAAoB,EAAE,KAAK,CAAC,EAAE,UAAU,EAStI;IAED;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAI/B,OAAO,CAAC,MAAM,CAAC,eAAe;IAW9B,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAKnC;;;;;;;;OAQG;IACH,OAAO,CAAC,WAAW;IAgCnB,uGAAuG;IACvG,OAAO,CAAC,YAAY;IAMpB,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAmDxE;IAED,2FAA2F;IAC3F,gBAAgB,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAS/C;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED,IAAI,KAAK,IAAI,cAAc,CAE1B;IAED,mGAAmG;IACnG,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAEpC;IAED,IAAI,OAAO,IAAI,WAAW,CAAC,SAAS,CAAC,CAAgC;IACrE,IAAI,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,CAA+B;IAClE,IAAI,IAAI,IAAI,WAAW,CAAC,MAAM,CAAC,CAA6B;IAC5D,IAAI,OAAO,IAAI,WAAW,CAAC,SAAS,CAAC,CAAgC;IACrE,IAAI,KAAK,IAAI,WAAW,CAAC,OAAO,CAAC,CAA8B;CAChE"}
1
+ {"version":3,"file":"ButtonNodeView.d.ts","sourceRoot":"","sources":["../../src/views/ButtonNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACjH,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAgD,OAAO,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,EAAE,QAAQ,EAAE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAC;AAK7D;;;;;;;;GAQG;AACH,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,YAAY,CAAU;IAE9B,YAAY,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,WAAW,EAAE,oBAAoB,EAAE,KAAK,CAAC,EAAE,UAAU,EAStI;IAED;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAI/B,OAAO,CAAC,MAAM,CAAC,eAAe;IAW9B,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAKnC;;;;;;;;OAQG;IACH,OAAO,CAAC,WAAW;IAwCnB,uGAAuG;IACvG,OAAO,CAAC,YAAY;IAMpB,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAuDxE;IAED,2FAA2F;IAC3F,gBAAgB,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAS/C;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED,IAAI,KAAK,IAAI,cAAc,CAE1B;IAED,mGAAmG;IACnG,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAEpC;IAED,IAAI,OAAO,IAAI,WAAW,CAAC,SAAS,CAAC,CAAgC;IACrE,IAAI,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,CAA+B;IAClE,IAAI,IAAI,IAAI,WAAW,CAAC,MAAM,CAAC,CAA6B;IAC5D,IAAI,OAAO,IAAI,WAAW,CAAC,SAAS,CAAC,CAAgC;IACrE,IAAI,KAAK,IAAI,WAAW,CAAC,OAAO,CAAC,CAA8B;CAChE"}
@@ -65,6 +65,10 @@ export class ButtonNodeView extends NodeView {
65
65
  * pass has run). Only feeds the initial placeholder paint above — see its doc comment for why.
66
66
  */
67
67
  buildButton(node, size) {
68
+ // `FancyButton` always starts in `default`. An internal rebuild must stay invisible to hosts
69
+ // and to the Inspector's transient state preview: otherwise rebuilding after a nine-slice or
70
+ // asset-type change leaves the Inspector on (say) Hover while the canvas silently shows Normal.
71
+ const previousState = this.button === undefined ? undefined : this.state;
68
72
  const nineSlice = node.nineSlice;
69
73
  const resolvedSize = size ?? { width: node.transform.width, height: node.transform.height };
70
74
  const normalTexture = this.textureFor(node.states.normalAssetId);
@@ -94,6 +98,10 @@ export class ButtonNodeView extends NodeView {
94
98
  this.button = button;
95
99
  this.stateViews = stateViews;
96
100
  this.setContent(button);
101
+ if (previousState !== undefined) {
102
+ this.applyEnabled(this.enabledState);
103
+ this.button.setState(FANCY_STATE_BY_KEY[previousState]);
104
+ }
97
105
  }
98
106
  /** In authoring mode `enabled` may only drive the visuals: `FancyButton` couples it to `eventMode`. */
99
107
  applyEnabled(enabled) {
@@ -157,6 +165,10 @@ export class ButtonNodeView extends NodeView {
157
165
  }
158
166
  ButtonNodeView.applyStateAppearance(view, node, state);
159
167
  }
168
+ // Re-activate the current view after changing its appearance. Besides keeping FancyButton's
169
+ // visibility bookkeeping authoritative, this invalidates the shown branch immediately when
170
+ // Inspector color/opacity previews update an already-built button.
171
+ this.button.setState(this.button.state, true);
160
172
  }
161
173
  // Только на изменение документа: иначе любой пересчёт layout сбрасывал бы transient preview state.
162
174
  if (node.enabled !== this.enabledState)
@@ -1 +1 @@
1
- {"version":3,"file":"ButtonNodeView.js","sourceRoot":"","sources":["../../src/views/ButtonNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { BUTTON_STATE_KEYS, type ButtonStateKey, type LayoutPadding, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { FancyButton } from \"@pixi/ui\";\r\nimport { Container, Graphics, NineSliceSprite, Sprite, Texture } from \"pixi.js\";\r\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.js\";\r\nimport type { SceneAudio } from \"../audio/bus.js\";\r\n\r\nexport type ButtonNode = Extract<UINode, { type: \"button\" }>;\r\n\r\nconst FANCY_STATE_BY_KEY = { normal: \"default\", hover: \"hover\", pressed: \"pressed\", disabled: \"disabled\" } as const;\r\nconst KEY_BY_FANCY_STATE = { default: \"normal\", hover: \"hover\", pressed: \"pressed\", disabled: \"disabled\" } as const;\r\n\r\n/**\r\n * Adapts a button node to `@pixi/ui`'s `FancyButton`, which owns the pointer state machine —\r\n * this class never reimplements it. Optional states fall back to the normal image, and runtime\r\n * changes to `enabled` or the current state stay in the view: they never touch the document.\r\n *\r\n * `nineSlice`, when set, applies the same borders to all four state views (`NineSliceSprite`\r\n * instead of `Sprite`) — the button's frame shape is normally the same regardless of which state\r\n * image is currently shown.\r\n */\r\nexport class ButtonNodeView extends NodeView {\r\n private button!: FancyButton;\r\n private stateViews!: Record<ButtonStateKey, Container>;\r\n private readonly interaction: SceneInteractionMode;\r\n private readonly audio: SceneAudio | undefined;\r\n private readonly nodeId: string;\r\n private soundAssetIds: ButtonNode[\"sounds\"];\r\n private enabledState: boolean;\r\n\r\n constructor(node: ButtonNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, audio?: SceneAudio) {\r\n super(textures);\r\n this.interaction = interaction;\r\n this.audio = audio;\r\n this.nodeId = node.id;\r\n this.soundAssetIds = node.sounds;\r\n this.enabledState = node.enabled;\r\n this.buildButton(node);\r\n this.applyEnabled(node.enabled);\r\n }\r\n\r\n /**\r\n * Invisible (alpha 0) but still hit-testable: Pixi's `containsPoint` hit-tests the fill's geometry\r\n * regardless of its alpha. Painted with a real size *before* the view ever reaches `FancyButton`:\r\n * `FancyButton` reads `defaultView`'s bounds exactly once, synchronously during construction, to\r\n * freeze its own `hitArea` — it never re-reads them afterwards. A `Graphics` still at its default\r\n * (0, 0) size at that moment would freeze a zero-size, permanently unclickable hit area.\r\n */\r\n private static paintPlaceholder(graphics: Graphics, width: number, height: number): void {\r\n graphics.clear().rect(0, 0, width, height).fill({ color: 0x000000, alpha: 0 });\r\n }\r\n\r\n private static createStateView(texture: Texture | undefined, nineSlice: LayoutPadding | undefined, size: { width: number; height: number }): Container {\r\n if (texture === undefined) {\r\n const graphics = new Graphics();\r\n ButtonNodeView.paintPlaceholder(graphics, size.width, size.height);\r\n return graphics;\r\n }\r\n return nineSlice === undefined\r\n ? new Sprite(texture)\r\n : new NineSliceSprite({ texture, leftWidth: nineSlice.left, topHeight: nineSlice.top, rightWidth: nineSlice.right, bottomHeight: nineSlice.bottom });\r\n }\r\n\r\n private static applyStateAppearance(view: Container, node: ButtonNode, state: ButtonStateKey): void {\r\n view.tint = node.states[`${state}Tint`] ?? \"#ffffff\";\r\n view.alpha = node.states[`${state}Opacity`] ?? 1;\r\n }\r\n\r\n /**\r\n * (Re)builds `FancyButton` and its four state views. `FancyButton` has no API to replace a view\r\n * after construction, so any change to a view's *type* — nine-slice toggled, or an asset\r\n * finishing an async load — goes through here instead of `syncContent`'s cheap in-place path.\r\n *\r\n * `size` is the best size known *right now*: the resolved layout rectangle when called from\r\n * `syncContent`, or the authored transform when called from the constructor (before any layout\r\n * pass has run). Only feeds the initial placeholder paint above — see its doc comment for why.\r\n */\r\n private buildButton(node: ButtonNode, size?: { width: number; height: number }): void {\r\n const nineSlice = node.nineSlice;\r\n const resolvedSize = size ?? { width: node.transform.width, height: node.transform.height };\r\n const normalTexture = this.textureFor(node.states.normalAssetId);\r\n const stateViews = {} as Record<ButtonStateKey, Container>;\r\n const viewFor = (state: ButtonStateKey, assetId: string | undefined): Container => {\r\n const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;\r\n const view = ButtonNodeView.createStateView(texture, nineSlice, resolvedSize);\r\n ButtonNodeView.applyStateAppearance(view, node, state);\r\n stateViews[state] = view;\r\n return view;\r\n };\r\n\r\n const button = new FancyButton({\r\n defaultView: viewFor(\"normal\", node.states.normalAssetId),\r\n hoverView: viewFor(\"hover\", node.states.hoverAssetId),\r\n pressedView: viewFor(\"pressed\", node.states.pressedAssetId),\r\n disabledView: viewFor(\"disabled\", node.states.disabledAssetId),\r\n });\r\n // Authoring-сцена инертна: FancyButton уже включил себе eventMode \"static\", снимаем его до applyEnabled.\r\n // Выделение и drag при этом не страдают: попадание ловит hitArea базового NodeView, а не это поддерево.\r\n if (this.interaction === \"authoring\") button.eventMode = \"none\";\r\n else if (this.audio !== undefined) {\r\n // Вьюха только объявляет, что произошло: играть или нет — решает подписчик шины (см. audio/bus.ts).\r\n button.onPress.connect(() => this.audio?.cue(\"button.press\", this.nodeId, this.soundAssetIds?.pressAssetId));\r\n button.onHover.connect(() => this.audio?.cue(\"button.hover\", this.nodeId, this.soundAssetIds?.hoverAssetId));\r\n }\r\n this.button = button;\r\n this.stateViews = stateViews;\r\n this.setContent(button);\r\n }\r\n\r\n /** In authoring mode `enabled` may only drive the visuals: `FancyButton` couples it to `eventMode`. */\r\n private applyEnabled(enabled: boolean): void {\r\n this.enabledState = enabled;\r\n if (this.interaction === \"runtime\") this.button.enabled = enabled;\r\n else this.button.setState(enabled ? \"default\" : \"disabled\");\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"]): void {\r\n if (node.type !== \"button\") return;\r\n this.soundAssetIds = node.sounds;\r\n const nineSlice = node.nineSlice;\r\n const normalTexture = this.textureFor(node.states.normalAssetId);\r\n\r\n // A state view's required *type* (Graphics/Sprite/NineSliceSprite) may no longer match what's\r\n // needed — nine-slice toggled, or a texture finished loading after this view had to fall back\r\n // to Graphics. FancyButton can't swap a view after construction, so that goes through a full\r\n // rebuild; everything else (texture identity, border values, size) updates the live views in\r\n // place, which is the path a nine-slice gizmo drag runs every frame.\r\n let needsRebuild = false;\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const assetId = node.states[`${state}AssetId`];\r\n const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;\r\n const view = this.stateViews[state];\r\n const wantsNineSlice = texture !== undefined && nineSlice !== undefined;\r\n const matches = texture === undefined ? view instanceof Graphics : wantsNineSlice ? view instanceof NineSliceSprite : view instanceof Sprite && !(view instanceof NineSliceSprite);\r\n if (!matches) { needsRebuild = true; break; }\r\n }\r\n\r\n if (needsRebuild) {\r\n this.buildButton(node, transform);\r\n } else {\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const view = this.stateViews[state];\r\n const assetId = node.states[`${state}AssetId`];\r\n const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;\r\n // Set the texture before the layout size: Sprite/NineSliceSprite preserve scale when their\r\n // texture changes, so sizing first would shift visual bounds for a differently-sized source.\r\n if (view instanceof NineSliceSprite) {\r\n if (texture !== undefined && view.texture !== texture) view.texture = texture;\r\n if (nineSlice !== undefined) {\r\n view.leftWidth = nineSlice.left;\r\n view.topHeight = nineSlice.top;\r\n view.rightWidth = nineSlice.right;\r\n view.bottomHeight = nineSlice.bottom;\r\n }\r\n view.setSize(transform.width, transform.height);\r\n } else if (view instanceof Sprite) {\r\n if (texture !== undefined && view.texture !== texture) view.texture = texture;\r\n view.setSize(transform.width, transform.height);\r\n } else if (view instanceof Graphics) {\r\n ButtonNodeView.paintPlaceholder(view, transform.width, transform.height);\r\n }\r\n ButtonNodeView.applyStateAppearance(view, node, state);\r\n }\r\n }\r\n\r\n // Только на изменение документа: иначе любой пересчёт layout сбрасывал бы transient preview state.\r\n if (node.enabled !== this.enabledState) this.applyEnabled(node.enabled);\r\n }\r\n\r\n /** Editor-only live preview of nine-slice border edits while dragging the canvas gizmo. */\r\n previewNineSlice(nineSlice: LayoutPadding): void {\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const view = this.stateViews[state];\r\n if (!(view instanceof NineSliceSprite)) continue;\r\n view.leftWidth = nineSlice.left;\r\n view.topHeight = nineSlice.top;\r\n view.rightWidth = nineSlice.right;\r\n view.bottomHeight = nineSlice.bottom;\r\n }\r\n }\r\n\r\n get enabled(): boolean {\r\n return this.enabledState;\r\n }\r\n\r\n set enabled(value: boolean) {\r\n this.applyEnabled(value);\r\n }\r\n\r\n get state(): ButtonStateKey {\r\n return KEY_BY_FANCY_STATE[this.button.state];\r\n }\r\n\r\n /** Forces a visual state without changing `enabled`, so a disabled button still emits no press. */\r\n setState(state: ButtonStateKey): void {\r\n this.button.setState(FANCY_STATE_BY_KEY[state]);\r\n }\r\n\r\n get onPress(): FancyButton[\"onPress\"] { return this.button.onPress; }\r\n get onDown(): FancyButton[\"onDown\"] { return this.button.onDown; }\r\n get onUp(): FancyButton[\"onUp\"] { return this.button.onUp; }\r\n get onHover(): FancyButton[\"onHover\"] { return this.button.onHover; }\r\n get onOut(): FancyButton[\"onOut\"] { return this.button.onOut; }\r\n}\r\n"]}
1
+ {"version":3,"file":"ButtonNodeView.js","sourceRoot":"","sources":["../../src/views/ButtonNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { BUTTON_STATE_KEYS, type ButtonStateKey, type LayoutPadding, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { FancyButton } from \"@pixi/ui\";\r\nimport { Container, Graphics, NineSliceSprite, Sprite, Texture } from \"pixi.js\";\r\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.js\";\r\nimport type { SceneAudio } from \"../audio/bus.js\";\r\n\r\nexport type ButtonNode = Extract<UINode, { type: \"button\" }>;\r\n\r\nconst FANCY_STATE_BY_KEY = { normal: \"default\", hover: \"hover\", pressed: \"pressed\", disabled: \"disabled\" } as const;\r\nconst KEY_BY_FANCY_STATE = { default: \"normal\", hover: \"hover\", pressed: \"pressed\", disabled: \"disabled\" } as const;\r\n\r\n/**\r\n * Adapts a button node to `@pixi/ui`'s `FancyButton`, which owns the pointer state machine —\r\n * this class never reimplements it. Optional states fall back to the normal image, and runtime\r\n * changes to `enabled` or the current state stay in the view: they never touch the document.\r\n *\r\n * `nineSlice`, when set, applies the same borders to all four state views (`NineSliceSprite`\r\n * instead of `Sprite`) — the button's frame shape is normally the same regardless of which state\r\n * image is currently shown.\r\n */\r\nexport class ButtonNodeView extends NodeView {\r\n private button!: FancyButton;\r\n private stateViews!: Record<ButtonStateKey, Container>;\r\n private readonly interaction: SceneInteractionMode;\r\n private readonly audio: SceneAudio | undefined;\r\n private readonly nodeId: string;\r\n private soundAssetIds: ButtonNode[\"sounds\"];\r\n private enabledState: boolean;\r\n\r\n constructor(node: ButtonNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, audio?: SceneAudio) {\r\n super(textures);\r\n this.interaction = interaction;\r\n this.audio = audio;\r\n this.nodeId = node.id;\r\n this.soundAssetIds = node.sounds;\r\n this.enabledState = node.enabled;\r\n this.buildButton(node);\r\n this.applyEnabled(node.enabled);\r\n }\r\n\r\n /**\r\n * Invisible (alpha 0) but still hit-testable: Pixi's `containsPoint` hit-tests the fill's geometry\r\n * regardless of its alpha. Painted with a real size *before* the view ever reaches `FancyButton`:\r\n * `FancyButton` reads `defaultView`'s bounds exactly once, synchronously during construction, to\r\n * freeze its own `hitArea` — it never re-reads them afterwards. A `Graphics` still at its default\r\n * (0, 0) size at that moment would freeze a zero-size, permanently unclickable hit area.\r\n */\r\n private static paintPlaceholder(graphics: Graphics, width: number, height: number): void {\r\n graphics.clear().rect(0, 0, width, height).fill({ color: 0x000000, alpha: 0 });\r\n }\r\n\r\n private static createStateView(texture: Texture | undefined, nineSlice: LayoutPadding | undefined, size: { width: number; height: number }): Container {\r\n if (texture === undefined) {\r\n const graphics = new Graphics();\r\n ButtonNodeView.paintPlaceholder(graphics, size.width, size.height);\r\n return graphics;\r\n }\r\n return nineSlice === undefined\r\n ? new Sprite(texture)\r\n : new NineSliceSprite({ texture, leftWidth: nineSlice.left, topHeight: nineSlice.top, rightWidth: nineSlice.right, bottomHeight: nineSlice.bottom });\r\n }\r\n\r\n private static applyStateAppearance(view: Container, node: ButtonNode, state: ButtonStateKey): void {\r\n view.tint = node.states[`${state}Tint`] ?? \"#ffffff\";\r\n view.alpha = node.states[`${state}Opacity`] ?? 1;\r\n }\r\n\r\n /**\r\n * (Re)builds `FancyButton` and its four state views. `FancyButton` has no API to replace a view\r\n * after construction, so any change to a view's *type* — nine-slice toggled, or an asset\r\n * finishing an async load — goes through here instead of `syncContent`'s cheap in-place path.\r\n *\r\n * `size` is the best size known *right now*: the resolved layout rectangle when called from\r\n * `syncContent`, or the authored transform when called from the constructor (before any layout\r\n * pass has run). Only feeds the initial placeholder paint above — see its doc comment for why.\r\n */\r\n private buildButton(node: ButtonNode, size?: { width: number; height: number }): void {\r\n // `FancyButton` always starts in `default`. An internal rebuild must stay invisible to hosts\r\n // and to the Inspector's transient state preview: otherwise rebuilding after a nine-slice or\r\n // asset-type change leaves the Inspector on (say) Hover while the canvas silently shows Normal.\r\n const previousState = this.button === undefined ? undefined : this.state;\r\n const nineSlice = node.nineSlice;\r\n const resolvedSize = size ?? { width: node.transform.width, height: node.transform.height };\r\n const normalTexture = this.textureFor(node.states.normalAssetId);\r\n const stateViews = {} as Record<ButtonStateKey, Container>;\r\n const viewFor = (state: ButtonStateKey, assetId: string | undefined): Container => {\r\n const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;\r\n const view = ButtonNodeView.createStateView(texture, nineSlice, resolvedSize);\r\n ButtonNodeView.applyStateAppearance(view, node, state);\r\n stateViews[state] = view;\r\n return view;\r\n };\r\n\r\n const button = new FancyButton({\r\n defaultView: viewFor(\"normal\", node.states.normalAssetId),\r\n hoverView: viewFor(\"hover\", node.states.hoverAssetId),\r\n pressedView: viewFor(\"pressed\", node.states.pressedAssetId),\r\n disabledView: viewFor(\"disabled\", node.states.disabledAssetId),\r\n });\r\n // Authoring-сцена инертна: FancyButton уже включил себе eventMode \"static\", снимаем его до applyEnabled.\r\n // Выделение и drag при этом не страдают: попадание ловит hitArea базового NodeView, а не это поддерево.\r\n if (this.interaction === \"authoring\") button.eventMode = \"none\";\r\n else if (this.audio !== undefined) {\r\n // Вьюха только объявляет, что произошло: играть или нет — решает подписчик шины (см. audio/bus.ts).\r\n button.onPress.connect(() => this.audio?.cue(\"button.press\", this.nodeId, this.soundAssetIds?.pressAssetId));\r\n button.onHover.connect(() => this.audio?.cue(\"button.hover\", this.nodeId, this.soundAssetIds?.hoverAssetId));\r\n }\r\n this.button = button;\r\n this.stateViews = stateViews;\r\n this.setContent(button);\r\n if (previousState !== undefined) {\r\n this.applyEnabled(this.enabledState);\r\n this.button.setState(FANCY_STATE_BY_KEY[previousState]);\r\n }\r\n }\r\n\r\n /** In authoring mode `enabled` may only drive the visuals: `FancyButton` couples it to `eventMode`. */\r\n private applyEnabled(enabled: boolean): void {\r\n this.enabledState = enabled;\r\n if (this.interaction === \"runtime\") this.button.enabled = enabled;\r\n else this.button.setState(enabled ? \"default\" : \"disabled\");\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"]): void {\r\n if (node.type !== \"button\") return;\r\n this.soundAssetIds = node.sounds;\r\n const nineSlice = node.nineSlice;\r\n const normalTexture = this.textureFor(node.states.normalAssetId);\r\n\r\n // A state view's required *type* (Graphics/Sprite/NineSliceSprite) may no longer match what's\r\n // needed — nine-slice toggled, or a texture finished loading after this view had to fall back\r\n // to Graphics. FancyButton can't swap a view after construction, so that goes through a full\r\n // rebuild; everything else (texture identity, border values, size) updates the live views in\r\n // place, which is the path a nine-slice gizmo drag runs every frame.\r\n let needsRebuild = false;\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const assetId = node.states[`${state}AssetId`];\r\n const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;\r\n const view = this.stateViews[state];\r\n const wantsNineSlice = texture !== undefined && nineSlice !== undefined;\r\n const matches = texture === undefined ? view instanceof Graphics : wantsNineSlice ? view instanceof NineSliceSprite : view instanceof Sprite && !(view instanceof NineSliceSprite);\r\n if (!matches) { needsRebuild = true; break; }\r\n }\r\n\r\n if (needsRebuild) {\r\n this.buildButton(node, transform);\r\n } else {\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const view = this.stateViews[state];\r\n const assetId = node.states[`${state}AssetId`];\r\n const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;\r\n // Set the texture before the layout size: Sprite/NineSliceSprite preserve scale when their\r\n // texture changes, so sizing first would shift visual bounds for a differently-sized source.\r\n if (view instanceof NineSliceSprite) {\r\n if (texture !== undefined && view.texture !== texture) view.texture = texture;\r\n if (nineSlice !== undefined) {\r\n view.leftWidth = nineSlice.left;\r\n view.topHeight = nineSlice.top;\r\n view.rightWidth = nineSlice.right;\r\n view.bottomHeight = nineSlice.bottom;\r\n }\r\n view.setSize(transform.width, transform.height);\r\n } else if (view instanceof Sprite) {\r\n if (texture !== undefined && view.texture !== texture) view.texture = texture;\r\n view.setSize(transform.width, transform.height);\r\n } else if (view instanceof Graphics) {\r\n ButtonNodeView.paintPlaceholder(view, transform.width, transform.height);\r\n }\r\n ButtonNodeView.applyStateAppearance(view, node, state);\r\n }\r\n // Re-activate the current view after changing its appearance. Besides keeping FancyButton's\r\n // visibility bookkeeping authoritative, this invalidates the shown branch immediately when\r\n // Inspector color/opacity previews update an already-built button.\r\n this.button.setState(this.button.state, true);\r\n }\r\n\r\n // Только на изменение документа: иначе любой пересчёт layout сбрасывал бы transient preview state.\r\n if (node.enabled !== this.enabledState) this.applyEnabled(node.enabled);\r\n }\r\n\r\n /** Editor-only live preview of nine-slice border edits while dragging the canvas gizmo. */\r\n previewNineSlice(nineSlice: LayoutPadding): void {\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const view = this.stateViews[state];\r\n if (!(view instanceof NineSliceSprite)) continue;\r\n view.leftWidth = nineSlice.left;\r\n view.topHeight = nineSlice.top;\r\n view.rightWidth = nineSlice.right;\r\n view.bottomHeight = nineSlice.bottom;\r\n }\r\n }\r\n\r\n get enabled(): boolean {\r\n return this.enabledState;\r\n }\r\n\r\n set enabled(value: boolean) {\r\n this.applyEnabled(value);\r\n }\r\n\r\n get state(): ButtonStateKey {\r\n return KEY_BY_FANCY_STATE[this.button.state];\r\n }\r\n\r\n /** Forces a visual state without changing `enabled`, so a disabled button still emits no press. */\r\n setState(state: ButtonStateKey): void {\r\n this.button.setState(FANCY_STATE_BY_KEY[state]);\r\n }\r\n\r\n get onPress(): FancyButton[\"onPress\"] { return this.button.onPress; }\r\n get onDown(): FancyButton[\"onDown\"] { return this.button.onDown; }\r\n get onUp(): FancyButton[\"onUp\"] { return this.button.onUp; }\r\n get onHover(): FancyButton[\"onHover\"] { return this.button.onHover; }\r\n get onOut(): FancyButton[\"onOut\"] { return this.button.onOut; }\r\n}\r\n"]}
@@ -18,7 +18,7 @@ export declare class SpineNodeView extends NodeView {
18
18
  private connectorBonesActive;
19
19
  /** Layout profile the view was last synced with; connector multipliers resolve against it. */
20
20
  private activeProfile;
21
- constructor(skeletonData: SkeletonData | undefined, animation: string | undefined, autoplay: boolean, loop: boolean, animationSpeed: number, initializeForAuthoring: boolean, referenceFrame?: SpineReferenceFrame, ticker?: Ticker);
21
+ constructor(skeletonData: SkeletonData | undefined, animation: string | undefined, autoplay: boolean, loop: boolean, animationSpeed: number, initializeForAuthoring: boolean, referenceFrame?: SpineReferenceFrame, ticker?: Ticker, animationMix?: number);
22
22
  /** Runtime switch used by game code; authored connector definitions are inactive by default. */
23
23
  get activeConnectorBones(): boolean;
24
24
  set activeConnectorBones(active: boolean);
@@ -1 +1 @@
1
- {"version":3,"file":"SpineNodeView.d.ts","sourceRoot":"","sources":["../../src/views/SpineNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACvH,OAAO,EAA2C,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,mBAAmB,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACnK,OAAO,EAAE,SAAS,EAAoB,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAEnE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,KAAK,gBAAgB,GAAG,cAAc,GAAG;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC;AAC/D,KAAK,uBAAuB,GAAG,gBAAgB,GAAG,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAqB9I,qBAAa,aAAc,SAAQ,QAAQ;IACzC,OAAO,CAAC,cAAc,CAAkC;IACxD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAU;IACjD,OAAO,CAAC,iBAAiB,CAAiC;IAC1D,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,oBAAoB,CAAS;IACrC,8FAA8F;IAC9F,OAAO,CAAC,aAAa,CAA8B;IAEnD,YAAY,YAAY,EAAE,YAAY,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,sBAAsB,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,mBAAmB,EAAE,MAAM,CAAC,EAAE,MAAM,EA6BlO;IAED,gGAAgG;IAChG,IAAI,oBAAoB,IAAI,OAAO,CAElC;IAED,IAAI,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAEvC;IAED,0FAA0F;IAC1F,iBAAiB,CAAC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,GAAG,IAAI,CAKpE;IAED,uBAAuB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAwC7C;IAED,8EAA8E;IAC9E,qBAAqB,IAAI,IAAI,CAkD5B;IAED,OAAO,CAAC,uBAAuB;IAiB/B,iBAAiB,CAAC,cAAc,EAAE,mBAAmB,GAAG,SAAS,GAAG,IAAI,CAEvE;IAED;;;;;OAKG;IACH,SAAS,CAAC,wBAAwB,IAAI,IAAI,CAEzC;IAED,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CAiClG;CACF"}
1
+ {"version":3,"file":"SpineNodeView.d.ts","sourceRoot":"","sources":["../../src/views/SpineNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACvH,OAAO,EAA2C,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,mBAAmB,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACnK,OAAO,EAAE,SAAS,EAAoB,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAEnE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,KAAK,gBAAgB,GAAG,cAAc,GAAG;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC;AAC/D,KAAK,uBAAuB,GAAG,gBAAgB,GAAG,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAqB9I,qBAAa,aAAc,SAAQ,QAAQ;IACzC,OAAO,CAAC,cAAc,CAAkC;IACxD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAU;IACjD,OAAO,CAAC,iBAAiB,CAAiC;IAC1D,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,oBAAoB,CAAS;IACrC,8FAA8F;IAC9F,OAAO,CAAC,aAAa,CAA8B;IAEnD,YAAY,YAAY,EAAE,YAAY,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,sBAAsB,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,mBAAmB,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,SAAI,EAkCpP;IAED,gGAAgG;IAChG,IAAI,oBAAoB,IAAI,OAAO,CAElC;IAED,IAAI,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAEvC;IAED,0FAA0F;IAC1F,iBAAiB,CAAC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,GAAG,IAAI,CAKpE;IAED,uBAAuB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAwC7C;IAED,8EAA8E;IAC9E,qBAAqB,IAAI,IAAI,CAkD5B;IAED,OAAO,CAAC,uBAAuB;IAiB/B,iBAAiB,CAAC,cAAc,EAAE,mBAAmB,GAAG,SAAS,GAAG,IAAI,CAEvE;IAED;;;;;OAKG;IACH,SAAS,CAAC,wBAAwB,IAAI,IAAI,CAEzC;IAED,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CAuClG;CACF"}
@@ -18,7 +18,7 @@ export class SpineNodeView extends NodeView {
18
18
  connectorBonesActive = false;
19
19
  /** Layout profile the view was last synced with; connector multipliers resolve against it. */
20
20
  activeProfile = "desktop";
21
- constructor(skeletonData, animation, autoplay, loop, animationSpeed, initializeForAuthoring, referenceFrame, ticker) {
21
+ constructor(skeletonData, animation, autoplay, loop, animationSpeed, initializeForAuthoring, referenceFrame, ticker, animationMix = 0) {
22
22
  super();
23
23
  this.referenceFrame = referenceFrame;
24
24
  this.initializeForAuthoring = initializeForAuthoring;
@@ -36,6 +36,11 @@ export class SpineNodeView extends NodeView {
36
36
  // the game touching `autoUpdate` itself.
37
37
  const spine = new Spine({ skeletonData, autoUpdate: initializeForAuthoring ? autoplay : true, ...(ticker === undefined ? {} : { ticker }) });
38
38
  spine.afterUpdateWorldTransforms = () => this.refreshConnectorBones();
39
+ // Кроссфейд между анимациями живёт на `AnimationStateData.defaultMix`, а не на конкретном
40
+ // треке: так плавность получают и переключения из инспектора, и любые `state.setAnimation`
41
+ // из игрового кода — без того, чтобы игра знала про авторскую настройку. 0 сохраняет прежний
42
+ // резкий переход.
43
+ spine.state.data.defaultMix = animationMix;
39
44
  // A configured animation always gets a track, posed to its own first frame — a skeleton left
40
45
  // without one instead renders Spine's setup/bind pose, which is almost never the intended "static"
41
46
  // look and was reported as a visibly broken/twitching pose (still-running physics/IK constraints
@@ -200,12 +205,19 @@ export class SpineNodeView extends NodeView {
200
205
  // never Spine's setup/bind pose.
201
206
  const playing = settings.autoplay || this.initializeForAuthoring;
202
207
  const desiredTimeScale = playing ? settings.animationSpeed : 0;
208
+ // Правка ползунка должна влиять на следующий переход, а не только на момент создания view.
209
+ this.content.state.data.defaultMix = settings.animationMix;
203
210
  if (settings.animation === undefined) {
204
211
  if (track !== null && track !== undefined)
205
212
  this.content.state.clearTrack(0);
206
213
  }
207
214
  else if ((animationChanged || loopChanged) && this.content.skeleton.data.findAnimation(settings.animation) !== null) {
208
- this.content.state.setAnimation(0, settings.animation, settings.loop).timeScale = desiredTimeScale;
215
+ const entry = this.content.state.setAnimation(0, settings.animation, settings.loop);
216
+ entry.timeScale = desiredTimeScale;
217
+ // Замороженный на кадре 0 скелет не проигрывает микс (mixTime двигается временем трека),
218
+ // и остался бы навсегда в полусмешанной позе — статичной ноде переход всегда мгновенный.
219
+ if (!playing)
220
+ entry.mixDuration = 0;
209
221
  }
210
222
  else if (track !== null && track !== undefined) {
211
223
  track.timeScale = desiredTimeScale;
@@ -1 +1 @@
1
- {"version":3,"file":"SpineNodeView.js","sourceRoot":"","sources":["../../src/views/SpineNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAqB,MAAM,iCAAiC,CAAC;AACvH,OAAO,EAAE,uCAAuC,EAAoF,MAAM,wBAAwB,CAAC;AACnK,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAe,MAAM,SAAS,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAgBzC,SAAS,oBAAoB,CAAC,OAAgC;IAC5D,IAAI,CAAC,OAAO,CAAC,QAAQ,KAAK,MAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAC,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxI,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;IACpE,CAAC;IACD,MAAM,QAAQ,GAAG,UAAU,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IACtE,OAAO,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACpH,CAAC;AAED,MAAM,OAAO,aAAc,SAAQ,QAAQ;IACjC,cAAc,CAAkC;IACvC,sBAAsB,CAAU;IACzC,iBAAiB,GAA8B,EAAE,CAAC;IAClD,gBAAgB,GAAsB,EAAE,CAAC;IACzC,oBAAoB,GAAG,KAAK,CAAC;IACrC,8FAA8F;IACtF,aAAa,GAAoB,SAAS,CAAC;IAEnD,YAAY,YAAsC,EAAE,SAA6B,EAAE,QAAiB,EAAE,IAAa,EAAE,cAAsB,EAAE,sBAA+B,EAAE,cAAoC,EAAE,MAAe;QACjO,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,sBAAsB,GAAG,sBAAsB,CAAC;QACrD,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC;YAChC,OAAO;QACT,CAAC;QACD,qFAAqF;QACrF,4FAA4F;QAC5F,0BAA0B;QAC1B,EAAE;QACF,yFAAyF;QACzF,yFAAyF;QACzF,8FAA8F;QAC9F,yCAAyC;QACzC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,sBAAsB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC7I,KAAK,CAAC,0BAA0B,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACtE,6FAA6F;QAC7F,mGAAmG;QACnG,iGAAiG;QACjG,iGAAiG;QACjG,+FAA+F;QAC/F,+EAA+E;QAC/E,IAAI,SAAS,KAAK,SAAS,IAAI,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC;YAC9E,MAAM,OAAO,GAAG,QAAQ,IAAI,sBAAsB,CAAC;YACnD,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;QACxF,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,gGAAgG;IAChG,IAAI,oBAAoB;QACtB,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACnC,CAAC;IAED,IAAI,oBAAoB,CAAC,MAAe;QACtC,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,0FAA0F;IAC1F,iBAAiB,CAAC,QAA4C;QAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC;QAC5C,IAAI,SAAS;YAAE,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC;QACnD,IAAI,CAAC,iBAAiB,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;QACvC,IAAI,SAAS;YAAE,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC;IAED,uBAAuB,CAAC,MAAe;QACrC,IAAI,MAAM,KAAK,IAAI,CAAC,oBAAoB;YAAE,OAAO;QACjD,IAAI,CAAC,oBAAoB,GAAG,MAAM,CAAC;QACnC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO;QAChC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC7C,MAAM,IAAI,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;YAC3C,IAAI,IAAI,KAAK,SAAS;gBAAE,SAAS;YACjC,IAAI,IAAI,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI;gBAAE,SAAS;YAC3I,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;YACrC,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,SAAS;gBAAE,SAAS;YAClD,MAAM,IAAI,GAAG,IAAI,SAAS,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAoB;gBAChC,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;gBAC9C,2BAA2B,EAAE,OAAO,CAAC,2BAA2B;gBAChE,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,MAAM;gBACN,KAAK,EAAE,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC;gBAC3C,QAAQ,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE;gBACxE,KAAK,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;gBAC/D,IAAI,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE;gBAC5D,KAAK,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;gBAC/D,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ;gBACjC,IAAI;aACL,CAAC;YACF,6FAA6F;YAC7F,+FAA+F;YAC/F,iDAAiD;YACjD,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACrB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC9B,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC;QACD,IAAI,CAAC,qBAAqB,EAAE,CAAC;IAC/B,CAAC;IAED,8EAA8E;IAC9E,qBAAqB;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO;QAChC,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC9C,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAChG,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC;YACtG,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,IAAI,SAAS,CAAC,MAAM,CAAC,SAAS;gBAAE,SAAS;YAChF,6FAA6F;YAC7F,yFAAyF;YACzF,8FAA8F;YAC9F,MAAM,UAAU,GAAG,IAAI,EAAE,UAAU,CAAC;YACpC,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YACzB,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YACzB,IAAI,UAAU,YAAY,eAAe,EAAE,CAAC;gBAC1C,MAAM,KAAK,GAAG,UAAU,CAAC,oBAAoB,CAAC,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,CAAC;gBACnE,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC;gBACjB,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC;YACnB,CAAC;iBAAM,IAAI,UAAU,YAAY,gBAAgB,EAAE,CAAC;gBAClD,MAAM,IAAI,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;gBACxD,MAAM,IAAI,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;YAC1D,CAAC;YACD,MAAM,UAAU,GAAG,KAAK,CAAC,kBAAkB,EAAE,CAAC;YAC9C,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;YAC1D,MAAM,WAAW,GAAG,UAAU,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;YAC9E,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,IAAI;gBAAE,SAAS;YAE5E,6FAA6F;YAC7F,4FAA4F;YAC5F,0DAA0D;YAC1D,MAAM,UAAU,GAAG,uCAAuC,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;YAE1F,4FAA4F;YAC5F,6FAA6F;YAC7F,yFAAyF;YACzF,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;YAC1F,MAAM,KAAK,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;YAC3F,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;YAC1F,MAAM,KAAK,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;YAC3F,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,MAAM,CACrC,KAAK,EACL,KAAK,EACL,KAAK,EACL,KAAK,EACL,MAAM,GAAG,UAAU,CAAC,CAAC,EACrB,MAAM,GAAG,UAAU,CAAC,CAAC,CACtB,CAAC,CAAC;YACH,SAAS,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,KAAK,IAAI;mBACjC,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3I,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAEO,uBAAuB;QAC7B,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC9C,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;YACrC,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAChE,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;gBACjC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAChE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACvD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACpD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACvD,MAAM,CAAC,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC;YACvC,CAAC;YACD,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;IAC7B,CAAC;IAED,iBAAiB,CAAC,cAA+C;QAC/D,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;IAED;;;;;OAKG;IACO,wBAAwB;QAChC,IAAI,IAAI,CAAC,oBAAoB;YAAE,IAAI,CAAC,qBAAqB,EAAE,CAAC;IAC9D,CAAC;IAES,WAAW,CAAC,IAAY,EAAE,SAA8B,EAAE,OAAwB;QAC1F,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;QAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;YAAE,IAAI,CAAC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;QAChG,IAAI,IAAI,CAAC,OAAO,YAAY,KAAK,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAC1B,MAAM,QAAQ,GAAG,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBACrD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC3C,MAAM,gBAAgB,GAAG,KAAK,EAAE,SAAS,EAAE,IAAI,KAAK,QAAQ,CAAC,SAAS,CAAC;gBACvE,MAAM,WAAW,GAAG,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC;gBAC1F,gGAAgG;gBAChG,0FAA0F;gBAC1F,iCAAiC;gBACjC,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,sBAAsB,CAAC;gBACjE,MAAM,gBAAgB,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/D,IAAI,QAAQ,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;oBACrC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;wBAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC9E,CAAC;qBAAM,IAAI,CAAC,gBAAgB,IAAI,WAAW,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC;oBACtH,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,GAAG,gBAAgB,CAAC;gBACrG,CAAC;qBAAM,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACjD,KAAK,CAAC,SAAS,GAAG,gBAAgB,CAAC;gBACrC,CAAC;YACH,CAAC;YACD,MAAM,GAAG,GAAG,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;YAC5F,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;gBAC/C,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;YAC1C,CAAC;YACD,wFAAwF;YACxF,0FAA0F;YAC1F,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;aAAM,IAAI,IAAI,CAAC,OAAO,YAAY,QAAQ,EAAE,CAAC;YAC5C,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;CACF","sourcesContent":["import { PointAttachment, RegionAttachment, Spine, Vector2, type SkeletonData } from \"@esotericsoftware/spine-pixi-v8\";\r\nimport { resolveSpineConnectorPositionMultiplier, type LayoutProfileId, type SpineConnector, type SpineReferenceFrame, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { Container, Graphics, Matrix, type Ticker } from \"pixi.js\";\r\nimport { fitSpineToTransform, resolveSpineSettings } from \"../layout.js\";\r\nimport { NodeView } from \"./NodeView.js\";\r\n\r\ntype ConnectorBinding = SpineConnector & { target: Container };\r\ntype RuntimeConnectorBinding = ConnectorBinding | ({ boneName: string; targetNodeId: string; target: Container } & Partial<ConnectorBinding>);\r\ntype ConnectorSnapshot = {\r\n target: Container;\r\n parent: Container;\r\n index: number;\r\n position: { x: number; y: number };\r\n scale: { x: number; y: number };\r\n skew: { x: number; y: number };\r\n pivot: { x: number; y: number };\r\n rotation: number;\r\n};\r\ntype ActiveConnector = ConnectorSnapshot & Pick<SpineConnector, \"partType\" | \"partName\" | \"positionMultiplier\" | \"positionMultiplierOverrides\"> & { host: Container };\r\n\r\nfunction resolveConnectorPart(binding: RuntimeConnectorBinding): Pick<SpineConnector, \"partType\" | \"partName\"> | undefined {\r\n if ((binding.partType === \"bone\" || binding.partType === \"slot\") && typeof binding.partName === \"string\" && binding.partName.length > 0) {\r\n return { partType: binding.partType, partName: binding.partName };\r\n }\r\n const boneName = \"boneName\" in binding ? binding.boneName : undefined;\r\n return typeof boneName === \"string\" && boneName.length > 0 ? { partType: \"bone\", partName: boneName } : undefined;\r\n}\r\n\r\nexport class SpineNodeView extends NodeView {\r\n private referenceFrame: SpineReferenceFrame | undefined;\r\n private readonly initializeForAuthoring: boolean;\r\n private connectorBindings: RuntimeConnectorBinding[] = [];\r\n private activeConnectors: ActiveConnector[] = [];\r\n private connectorBonesActive = false;\r\n /** Layout profile the view was last synced with; connector multipliers resolve against it. */\r\n private activeProfile: LayoutProfileId = \"desktop\";\r\n\r\n constructor(skeletonData: SkeletonData | undefined, animation: string | undefined, autoplay: boolean, loop: boolean, animationSpeed: number, initializeForAuthoring: boolean, referenceFrame?: SpineReferenceFrame, ticker?: Ticker) {\r\n super();\r\n this.referenceFrame = referenceFrame;\r\n this.initializeForAuthoring = initializeForAuthoring;\r\n if (skeletonData === undefined) {\r\n this.setContent(new Graphics());\r\n return;\r\n }\r\n // The host's own Application ticker, when it passed one: a Spine left on the default\r\n // `Ticker.shared` advances its skeleton in a second rAF loop, out of band with the renderer\r\n // that actually draws it.\r\n //\r\n // An authoring view starts at the node's own autoplay setting, so a scene full of paused\r\n // skeletons subscribes to no ticker at all — the editor toggles `autoUpdate` from there.\r\n // A runtime view always keeps it on: an animation game code starts later must advance without\r\n // the game touching `autoUpdate` itself.\r\n const spine = new Spine({ skeletonData, autoUpdate: initializeForAuthoring ? autoplay : true, ...(ticker === undefined ? {} : { ticker }) });\r\n spine.afterUpdateWorldTransforms = () => this.refreshConnectorBones();\r\n // A configured animation always gets a track, posed to its own first frame — a skeleton left\r\n // without one instead renders Spine's setup/bind pose, which is almost never the intended \"static\"\r\n // look and was reported as a visibly broken/twitching pose (still-running physics/IK constraints\r\n // have nothing to settle against without a driving animation). When not autoplaying, `timeScale`\r\n // is frozen at 0 so the track holds frame 0 forever without playing; game code starting a real\r\n // animation later just calls `state.setAnimation(...)` itself, same as before.\r\n if (animation !== undefined && skeletonData.findAnimation(animation) !== null) {\r\n const playing = autoplay || initializeForAuthoring;\r\n spine.state.setAnimation(0, animation, loop).timeScale = playing ? animationSpeed : 0;\r\n }\r\n this.setContent(spine);\r\n }\r\n\r\n /** Runtime switch used by game code; authored connector definitions are inactive by default. */\r\n get activeConnectorBones(): boolean {\r\n return this.connectorBonesActive;\r\n }\r\n\r\n set activeConnectorBones(active: boolean) {\r\n this.setConnectorBonesActive(active);\r\n }\r\n\r\n /** Replaces the scene-resolved connector targets, preserving the current active state. */\r\n setConnectorBones(bindings: readonly RuntimeConnectorBinding[]): void {\r\n const wasActive = this.connectorBonesActive;\r\n if (wasActive) this.setConnectorBonesActive(false);\r\n this.connectorBindings = [...bindings];\r\n if (wasActive) this.setConnectorBonesActive(true);\r\n }\r\n\r\n setConnectorBonesActive(active: boolean): void {\r\n if (active === this.connectorBonesActive) return;\r\n this.connectorBonesActive = active;\r\n if (!active) {\r\n this.restoreConnectorTargets();\r\n return;\r\n }\r\n\r\n const spine = this.getSpine();\r\n if (spine === undefined) return;\r\n for (const binding of this.connectorBindings) {\r\n const part = resolveConnectorPart(binding);\r\n if (part === undefined) continue;\r\n if (part.partType === \"bone\" ? spine.skeleton.findBone(part.partName) === null : spine.skeleton.findSlot(part.partName) === null) continue;\r\n const parent = binding.target.parent;\r\n if (parent === null || parent.destroyed) continue;\r\n const host = new Container();\r\n const snapshot: ActiveConnector = {\r\n partType: part.partType,\r\n partName: part.partName,\r\n positionMultiplier: binding.positionMultiplier,\r\n positionMultiplierOverrides: binding.positionMultiplierOverrides,\r\n target: binding.target,\r\n parent,\r\n index: parent.getChildIndex(binding.target),\r\n position: { x: binding.target.position.x, y: binding.target.position.y },\r\n scale: { x: binding.target.scale.x, y: binding.target.scale.y },\r\n skew: { x: binding.target.skew.x, y: binding.target.skew.y },\r\n pivot: { x: binding.target.pivot.x, y: binding.target.pivot.y },\r\n rotation: binding.target.rotation,\r\n host,\r\n };\r\n // The host genuinely belongs to the Spine view, so the authored skeleton offset inherits the\r\n // visual Spine fit. refreshConnectorBones compensates the host's linear transform only, so the\r\n // target keeps its original UI size/orientation.\r\n spine.addChild(host);\r\n host.addChild(binding.target);\r\n this.activeConnectors.push(snapshot);\r\n }\r\n this.refreshConnectorBones();\r\n }\r\n\r\n /** Reapplies bone matrices and the target's required zero local transform. */\r\n refreshConnectorBones(): void {\r\n const spine = this.getSpine();\r\n if (spine === undefined) return;\r\n for (const connector of this.activeConnectors) {\r\n const slot = connector.partType === \"slot\" ? spine.skeleton.findSlot(connector.partName) : null;\r\n const bone = connector.partType === \"bone\" ? spine.skeleton.findBone(connector.partName) : slot?.bone;\r\n if (bone === null || bone === undefined || connector.parent.destroyed) continue;\r\n // A slot itself has no transform beyond its bone, but a region attachment does: Spine stores\r\n // its authored Point offset in attachment.x/y. Project that attachment origin, otherwise\r\n // changing Point from e.g. -650 to -850 moves the visual attachment but not the UI connector.\r\n const attachment = slot?.attachment;\r\n let spineX = bone.worldX;\r\n let spineY = bone.worldY;\r\n if (attachment instanceof PointAttachment) {\r\n const point = attachment.computeWorldPosition(bone, new Vector2());\r\n spineX = point.x;\r\n spineY = point.y;\r\n } else if (attachment instanceof RegionAttachment) {\r\n spineX += attachment.x * bone.a + attachment.y * bone.b;\r\n spineY += attachment.x * bone.c + attachment.y * bone.d;\r\n }\r\n const spineWorld = spine.getGlobalTransform();\r\n const parentWorld = connector.parent.getGlobalTransform();\r\n const determinant = spineWorld.a * spineWorld.d - spineWorld.b * spineWorld.c;\r\n if (!Number.isFinite(determinant) || Math.abs(determinant) < 1e-8) continue;\r\n\r\n // Authored per-axis position multiplier (default 1): scales the projected part position from\r\n // the Spine node's origin before the parent transform compensation, so the target keeps its\r\n // own size/orientation and only its offset is multiplied.\r\n const multiplier = resolveSpineConnectorPositionMultiplier(connector, this.activeProfile);\r\n\r\n // The attachment position remains in original Spine source units and therefore inherits the\r\n // fitted Spine scale. For example, y=-650 at a 1/3 fit becomes roughly -217 on the UI scene.\r\n // Only the host's linear transform is compensated, so the target itself does not shrink.\r\n const hostA = (spineWorld.d * parentWorld.a - spineWorld.c * parentWorld.b) / determinant;\r\n const hostB = (-spineWorld.b * parentWorld.a + spineWorld.a * parentWorld.b) / determinant;\r\n const hostC = (spineWorld.d * parentWorld.c - spineWorld.c * parentWorld.d) / determinant;\r\n const hostD = (-spineWorld.b * parentWorld.c + spineWorld.a * parentWorld.d) / determinant;\r\n connector.host.setFromMatrix(new Matrix(\r\n hostA,\r\n hostB,\r\n hostC,\r\n hostD,\r\n spineX * multiplier.x,\r\n spineY * multiplier.y,\r\n ));\r\n connector.host.visible = slot === null\r\n || (spine.skeleton.drawOrder.includes(slot) && slot.attachment !== null && spine.alpha > 0 && spine.skeleton.color.a * slot.color.a > 0);\r\n connector.target.position.set(0, 0);\r\n }\r\n }\r\n\r\n private restoreConnectorTargets(): void {\r\n for (const connector of this.activeConnectors) {\r\n const { target, parent } = connector;\r\n if (!target.destroyed && !parent.destroyed) {\r\n const index = Math.min(connector.index, parent.children.length);\r\n parent.addChildAt(target, index);\r\n target.position.set(connector.position.x, connector.position.y);\r\n target.scale.set(connector.scale.x, connector.scale.y);\r\n target.skew.set(connector.skew.x, connector.skew.y);\r\n target.pivot.set(connector.pivot.x, connector.pivot.y);\r\n target.rotation = connector.rotation;\r\n }\r\n connector.host.destroy({ children: false });\r\n }\r\n this.activeConnectors = [];\r\n }\r\n\r\n setReferenceFrame(referenceFrame: SpineReferenceFrame | undefined): void {\r\n this.referenceFrame = referenceFrame;\r\n }\r\n\r\n /**\r\n * Every transform application (editor gesture previews, document commits, layout updates, anchor\r\n * resizes) recomputes active connector hosts immediately. The host's local matrix depends on the\r\n * spine's world transform — including the fitted width/height scale — so a resize of the spine\r\n * node must move its targets in the same pass, not on the next ticker frame or document commit.\r\n */\r\n protected onLayoutTransformApplied(): void {\r\n if (this.connectorBonesActive) this.refreshConnectorBones();\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"], profile: LayoutProfileId): void {\r\n this.activeProfile = profile;\r\n if (node.type === \"spine\" && this.content !== undefined) this.content.alpha = node.opacity ?? 1;\r\n if (this.content instanceof Spine) {\r\n if (node.type === \"spine\") {\r\n const settings = resolveSpineSettings(node, profile);\r\n const track = this.content.state.tracks[0];\r\n const animationChanged = track?.animation?.name !== settings.animation;\r\n const loopChanged = track !== null && track !== undefined && track.loop !== settings.loop;\r\n // Same \"always a track, frozen at frame 0 unless actually playing\" contract as the constructor:\r\n // a static (non-autoplay) skeleton stays posed to its configured animation's first frame,\r\n // never Spine's setup/bind pose.\r\n const playing = settings.autoplay || this.initializeForAuthoring;\r\n const desiredTimeScale = playing ? settings.animationSpeed : 0;\r\n if (settings.animation === undefined) {\r\n if (track !== null && track !== undefined) this.content.state.clearTrack(0);\r\n } else if ((animationChanged || loopChanged) && this.content.skeleton.data.findAnimation(settings.animation) !== null) {\r\n this.content.state.setAnimation(0, settings.animation, settings.loop).timeScale = desiredTimeScale;\r\n } else if (track !== null && track !== undefined) {\r\n track.timeScale = desiredTimeScale;\r\n }\r\n }\r\n const fit = fitSpineToTransform(this.content.skeleton.data, transform, this.referenceFrame);\r\n if (fit !== undefined) {\r\n this.content.scale.set(fit.scaleX, fit.scaleY);\r\n this.content.position.set(fit.x, fit.y);\r\n }\r\n // A paused Spine does not receive a ticker update. Refresh its world transforms after a\r\n // layout/viewport change so its displayed pose immediately matches the new fitted bounds.\r\n this.content.update(0);\r\n } else if (this.content instanceof Graphics) {\r\n this.content.clear().rect(0, 0, transform.width, transform.height).fill(0xff00ff);\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"SpineNodeView.js","sourceRoot":"","sources":["../../src/views/SpineNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAqB,MAAM,iCAAiC,CAAC;AACvH,OAAO,EAAE,uCAAuC,EAAoF,MAAM,wBAAwB,CAAC;AACnK,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAe,MAAM,SAAS,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAgBzC,SAAS,oBAAoB,CAAC,OAAgC;IAC5D,IAAI,CAAC,OAAO,CAAC,QAAQ,KAAK,MAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAC,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxI,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;IACpE,CAAC;IACD,MAAM,QAAQ,GAAG,UAAU,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IACtE,OAAO,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACpH,CAAC;AAED,MAAM,OAAO,aAAc,SAAQ,QAAQ;IACjC,cAAc,CAAkC;IACvC,sBAAsB,CAAU;IACzC,iBAAiB,GAA8B,EAAE,CAAC;IAClD,gBAAgB,GAAsB,EAAE,CAAC;IACzC,oBAAoB,GAAG,KAAK,CAAC;IACrC,8FAA8F;IACtF,aAAa,GAAoB,SAAS,CAAC;IAEnD,YAAY,YAAsC,EAAE,SAA6B,EAAE,QAAiB,EAAE,IAAa,EAAE,cAAsB,EAAE,sBAA+B,EAAE,cAAoC,EAAE,MAAe,EAAE,YAAY,GAAG,CAAC;QACnP,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,sBAAsB,GAAG,sBAAsB,CAAC;QACrD,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC;YAChC,OAAO;QACT,CAAC;QACD,qFAAqF;QACrF,4FAA4F;QAC5F,0BAA0B;QAC1B,EAAE;QACF,yFAAyF;QACzF,yFAAyF;QACzF,8FAA8F;QAC9F,yCAAyC;QACzC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,sBAAsB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC7I,KAAK,CAAC,0BAA0B,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACtE,0FAA0F;QAC1F,2FAA2F;QAC3F,6FAA6F;QAC7F,kBAAkB;QAClB,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,GAAG,YAAY,CAAC;QAC3C,6FAA6F;QAC7F,mGAAmG;QACnG,iGAAiG;QACjG,iGAAiG;QACjG,+FAA+F;QAC/F,+EAA+E;QAC/E,IAAI,SAAS,KAAK,SAAS,IAAI,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC;YAC9E,MAAM,OAAO,GAAG,QAAQ,IAAI,sBAAsB,CAAC;YACnD,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;QACxF,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,gGAAgG;IAChG,IAAI,oBAAoB;QACtB,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACnC,CAAC;IAED,IAAI,oBAAoB,CAAC,MAAe;QACtC,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,0FAA0F;IAC1F,iBAAiB,CAAC,QAA4C;QAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC;QAC5C,IAAI,SAAS;YAAE,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC;QACnD,IAAI,CAAC,iBAAiB,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;QACvC,IAAI,SAAS;YAAE,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC;IAED,uBAAuB,CAAC,MAAe;QACrC,IAAI,MAAM,KAAK,IAAI,CAAC,oBAAoB;YAAE,OAAO;QACjD,IAAI,CAAC,oBAAoB,GAAG,MAAM,CAAC;QACnC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO;QAChC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC7C,MAAM,IAAI,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;YAC3C,IAAI,IAAI,KAAK,SAAS;gBAAE,SAAS;YACjC,IAAI,IAAI,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI;gBAAE,SAAS;YAC3I,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;YACrC,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,SAAS;gBAAE,SAAS;YAClD,MAAM,IAAI,GAAG,IAAI,SAAS,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAoB;gBAChC,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;gBAC9C,2BAA2B,EAAE,OAAO,CAAC,2BAA2B;gBAChE,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,MAAM;gBACN,KAAK,EAAE,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC;gBAC3C,QAAQ,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE;gBACxE,KAAK,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;gBAC/D,IAAI,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE;gBAC5D,KAAK,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;gBAC/D,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ;gBACjC,IAAI;aACL,CAAC;YACF,6FAA6F;YAC7F,+FAA+F;YAC/F,iDAAiD;YACjD,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACrB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC9B,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC;QACD,IAAI,CAAC,qBAAqB,EAAE,CAAC;IAC/B,CAAC;IAED,8EAA8E;IAC9E,qBAAqB;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO;QAChC,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC9C,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAChG,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC;YACtG,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,IAAI,SAAS,CAAC,MAAM,CAAC,SAAS;gBAAE,SAAS;YAChF,6FAA6F;YAC7F,yFAAyF;YACzF,8FAA8F;YAC9F,MAAM,UAAU,GAAG,IAAI,EAAE,UAAU,CAAC;YACpC,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YACzB,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YACzB,IAAI,UAAU,YAAY,eAAe,EAAE,CAAC;gBAC1C,MAAM,KAAK,GAAG,UAAU,CAAC,oBAAoB,CAAC,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,CAAC;gBACnE,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC;gBACjB,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC;YACnB,CAAC;iBAAM,IAAI,UAAU,YAAY,gBAAgB,EAAE,CAAC;gBAClD,MAAM,IAAI,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;gBACxD,MAAM,IAAI,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;YAC1D,CAAC;YACD,MAAM,UAAU,GAAG,KAAK,CAAC,kBAAkB,EAAE,CAAC;YAC9C,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;YAC1D,MAAM,WAAW,GAAG,UAAU,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;YAC9E,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,IAAI;gBAAE,SAAS;YAE5E,6FAA6F;YAC7F,4FAA4F;YAC5F,0DAA0D;YAC1D,MAAM,UAAU,GAAG,uCAAuC,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;YAE1F,4FAA4F;YAC5F,6FAA6F;YAC7F,yFAAyF;YACzF,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;YAC1F,MAAM,KAAK,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;YAC3F,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;YAC1F,MAAM,KAAK,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;YAC3F,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,MAAM,CACrC,KAAK,EACL,KAAK,EACL,KAAK,EACL,KAAK,EACL,MAAM,GAAG,UAAU,CAAC,CAAC,EACrB,MAAM,GAAG,UAAU,CAAC,CAAC,CACtB,CAAC,CAAC;YACH,SAAS,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,KAAK,IAAI;mBACjC,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3I,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAEO,uBAAuB;QAC7B,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC9C,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;YACrC,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAChE,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;gBACjC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAChE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACvD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACpD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACvD,MAAM,CAAC,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC;YACvC,CAAC;YACD,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;IAC7B,CAAC;IAED,iBAAiB,CAAC,cAA+C;QAC/D,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;IAED;;;;;OAKG;IACO,wBAAwB;QAChC,IAAI,IAAI,CAAC,oBAAoB;YAAE,IAAI,CAAC,qBAAqB,EAAE,CAAC;IAC9D,CAAC;IAES,WAAW,CAAC,IAAY,EAAE,SAA8B,EAAE,OAAwB;QAC1F,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;QAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;YAAE,IAAI,CAAC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;QAChG,IAAI,IAAI,CAAC,OAAO,YAAY,KAAK,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAC1B,MAAM,QAAQ,GAAG,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBACrD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC3C,MAAM,gBAAgB,GAAG,KAAK,EAAE,SAAS,EAAE,IAAI,KAAK,QAAQ,CAAC,SAAS,CAAC;gBACvE,MAAM,WAAW,GAAG,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC;gBAC1F,gGAAgG;gBAChG,0FAA0F;gBAC1F,iCAAiC;gBACjC,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,sBAAsB,CAAC;gBACjE,MAAM,gBAAgB,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/D,2FAA2F;gBAC3F,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,YAAY,CAAC;gBAC3D,IAAI,QAAQ,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;oBACrC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;wBAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC9E,CAAC;qBAAM,IAAI,CAAC,gBAAgB,IAAI,WAAW,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC;oBACtH,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;oBACpF,KAAK,CAAC,SAAS,GAAG,gBAAgB,CAAC;oBACnC,yFAAyF;oBACzF,yFAAyF;oBACzF,IAAI,CAAC,OAAO;wBAAE,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC;gBACtC,CAAC;qBAAM,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACjD,KAAK,CAAC,SAAS,GAAG,gBAAgB,CAAC;gBACrC,CAAC;YACH,CAAC;YACD,MAAM,GAAG,GAAG,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;YAC5F,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;gBAC/C,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;YAC1C,CAAC;YACD,wFAAwF;YACxF,0FAA0F;YAC1F,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;aAAM,IAAI,IAAI,CAAC,OAAO,YAAY,QAAQ,EAAE,CAAC;YAC5C,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;CACF","sourcesContent":["import { PointAttachment, RegionAttachment, Spine, Vector2, type SkeletonData } from \"@esotericsoftware/spine-pixi-v8\";\r\nimport { resolveSpineConnectorPositionMultiplier, type LayoutProfileId, type SpineConnector, type SpineReferenceFrame, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { Container, Graphics, Matrix, type Ticker } from \"pixi.js\";\r\nimport { fitSpineToTransform, resolveSpineSettings } from \"../layout.js\";\r\nimport { NodeView } from \"./NodeView.js\";\r\n\r\ntype ConnectorBinding = SpineConnector & { target: Container };\r\ntype RuntimeConnectorBinding = ConnectorBinding | ({ boneName: string; targetNodeId: string; target: Container } & Partial<ConnectorBinding>);\r\ntype ConnectorSnapshot = {\r\n target: Container;\r\n parent: Container;\r\n index: number;\r\n position: { x: number; y: number };\r\n scale: { x: number; y: number };\r\n skew: { x: number; y: number };\r\n pivot: { x: number; y: number };\r\n rotation: number;\r\n};\r\ntype ActiveConnector = ConnectorSnapshot & Pick<SpineConnector, \"partType\" | \"partName\" | \"positionMultiplier\" | \"positionMultiplierOverrides\"> & { host: Container };\r\n\r\nfunction resolveConnectorPart(binding: RuntimeConnectorBinding): Pick<SpineConnector, \"partType\" | \"partName\"> | undefined {\r\n if ((binding.partType === \"bone\" || binding.partType === \"slot\") && typeof binding.partName === \"string\" && binding.partName.length > 0) {\r\n return { partType: binding.partType, partName: binding.partName };\r\n }\r\n const boneName = \"boneName\" in binding ? binding.boneName : undefined;\r\n return typeof boneName === \"string\" && boneName.length > 0 ? { partType: \"bone\", partName: boneName } : undefined;\r\n}\r\n\r\nexport class SpineNodeView extends NodeView {\r\n private referenceFrame: SpineReferenceFrame | undefined;\r\n private readonly initializeForAuthoring: boolean;\r\n private connectorBindings: RuntimeConnectorBinding[] = [];\r\n private activeConnectors: ActiveConnector[] = [];\r\n private connectorBonesActive = false;\r\n /** Layout profile the view was last synced with; connector multipliers resolve against it. */\r\n private activeProfile: LayoutProfileId = \"desktop\";\r\n\r\n constructor(skeletonData: SkeletonData | undefined, animation: string | undefined, autoplay: boolean, loop: boolean, animationSpeed: number, initializeForAuthoring: boolean, referenceFrame?: SpineReferenceFrame, ticker?: Ticker, animationMix = 0) {\r\n super();\r\n this.referenceFrame = referenceFrame;\r\n this.initializeForAuthoring = initializeForAuthoring;\r\n if (skeletonData === undefined) {\r\n this.setContent(new Graphics());\r\n return;\r\n }\r\n // The host's own Application ticker, when it passed one: a Spine left on the default\r\n // `Ticker.shared` advances its skeleton in a second rAF loop, out of band with the renderer\r\n // that actually draws it.\r\n //\r\n // An authoring view starts at the node's own autoplay setting, so a scene full of paused\r\n // skeletons subscribes to no ticker at all — the editor toggles `autoUpdate` from there.\r\n // A runtime view always keeps it on: an animation game code starts later must advance without\r\n // the game touching `autoUpdate` itself.\r\n const spine = new Spine({ skeletonData, autoUpdate: initializeForAuthoring ? autoplay : true, ...(ticker === undefined ? {} : { ticker }) });\r\n spine.afterUpdateWorldTransforms = () => this.refreshConnectorBones();\r\n // Кроссфейд между анимациями живёт на `AnimationStateData.defaultMix`, а не на конкретном\r\n // треке: так плавность получают и переключения из инспектора, и любые `state.setAnimation`\r\n // из игрового кода — без того, чтобы игра знала про авторскую настройку. 0 сохраняет прежний\r\n // резкий переход.\r\n spine.state.data.defaultMix = animationMix;\r\n // A configured animation always gets a track, posed to its own first frame — a skeleton left\r\n // without one instead renders Spine's setup/bind pose, which is almost never the intended \"static\"\r\n // look and was reported as a visibly broken/twitching pose (still-running physics/IK constraints\r\n // have nothing to settle against without a driving animation). When not autoplaying, `timeScale`\r\n // is frozen at 0 so the track holds frame 0 forever without playing; game code starting a real\r\n // animation later just calls `state.setAnimation(...)` itself, same as before.\r\n if (animation !== undefined && skeletonData.findAnimation(animation) !== null) {\r\n const playing = autoplay || initializeForAuthoring;\r\n spine.state.setAnimation(0, animation, loop).timeScale = playing ? animationSpeed : 0;\r\n }\r\n this.setContent(spine);\r\n }\r\n\r\n /** Runtime switch used by game code; authored connector definitions are inactive by default. */\r\n get activeConnectorBones(): boolean {\r\n return this.connectorBonesActive;\r\n }\r\n\r\n set activeConnectorBones(active: boolean) {\r\n this.setConnectorBonesActive(active);\r\n }\r\n\r\n /** Replaces the scene-resolved connector targets, preserving the current active state. */\r\n setConnectorBones(bindings: readonly RuntimeConnectorBinding[]): void {\r\n const wasActive = this.connectorBonesActive;\r\n if (wasActive) this.setConnectorBonesActive(false);\r\n this.connectorBindings = [...bindings];\r\n if (wasActive) this.setConnectorBonesActive(true);\r\n }\r\n\r\n setConnectorBonesActive(active: boolean): void {\r\n if (active === this.connectorBonesActive) return;\r\n this.connectorBonesActive = active;\r\n if (!active) {\r\n this.restoreConnectorTargets();\r\n return;\r\n }\r\n\r\n const spine = this.getSpine();\r\n if (spine === undefined) return;\r\n for (const binding of this.connectorBindings) {\r\n const part = resolveConnectorPart(binding);\r\n if (part === undefined) continue;\r\n if (part.partType === \"bone\" ? spine.skeleton.findBone(part.partName) === null : spine.skeleton.findSlot(part.partName) === null) continue;\r\n const parent = binding.target.parent;\r\n if (parent === null || parent.destroyed) continue;\r\n const host = new Container();\r\n const snapshot: ActiveConnector = {\r\n partType: part.partType,\r\n partName: part.partName,\r\n positionMultiplier: binding.positionMultiplier,\r\n positionMultiplierOverrides: binding.positionMultiplierOverrides,\r\n target: binding.target,\r\n parent,\r\n index: parent.getChildIndex(binding.target),\r\n position: { x: binding.target.position.x, y: binding.target.position.y },\r\n scale: { x: binding.target.scale.x, y: binding.target.scale.y },\r\n skew: { x: binding.target.skew.x, y: binding.target.skew.y },\r\n pivot: { x: binding.target.pivot.x, y: binding.target.pivot.y },\r\n rotation: binding.target.rotation,\r\n host,\r\n };\r\n // The host genuinely belongs to the Spine view, so the authored skeleton offset inherits the\r\n // visual Spine fit. refreshConnectorBones compensates the host's linear transform only, so the\r\n // target keeps its original UI size/orientation.\r\n spine.addChild(host);\r\n host.addChild(binding.target);\r\n this.activeConnectors.push(snapshot);\r\n }\r\n this.refreshConnectorBones();\r\n }\r\n\r\n /** Reapplies bone matrices and the target's required zero local transform. */\r\n refreshConnectorBones(): void {\r\n const spine = this.getSpine();\r\n if (spine === undefined) return;\r\n for (const connector of this.activeConnectors) {\r\n const slot = connector.partType === \"slot\" ? spine.skeleton.findSlot(connector.partName) : null;\r\n const bone = connector.partType === \"bone\" ? spine.skeleton.findBone(connector.partName) : slot?.bone;\r\n if (bone === null || bone === undefined || connector.parent.destroyed) continue;\r\n // A slot itself has no transform beyond its bone, but a region attachment does: Spine stores\r\n // its authored Point offset in attachment.x/y. Project that attachment origin, otherwise\r\n // changing Point from e.g. -650 to -850 moves the visual attachment but not the UI connector.\r\n const attachment = slot?.attachment;\r\n let spineX = bone.worldX;\r\n let spineY = bone.worldY;\r\n if (attachment instanceof PointAttachment) {\r\n const point = attachment.computeWorldPosition(bone, new Vector2());\r\n spineX = point.x;\r\n spineY = point.y;\r\n } else if (attachment instanceof RegionAttachment) {\r\n spineX += attachment.x * bone.a + attachment.y * bone.b;\r\n spineY += attachment.x * bone.c + attachment.y * bone.d;\r\n }\r\n const spineWorld = spine.getGlobalTransform();\r\n const parentWorld = connector.parent.getGlobalTransform();\r\n const determinant = spineWorld.a * spineWorld.d - spineWorld.b * spineWorld.c;\r\n if (!Number.isFinite(determinant) || Math.abs(determinant) < 1e-8) continue;\r\n\r\n // Authored per-axis position multiplier (default 1): scales the projected part position from\r\n // the Spine node's origin before the parent transform compensation, so the target keeps its\r\n // own size/orientation and only its offset is multiplied.\r\n const multiplier = resolveSpineConnectorPositionMultiplier(connector, this.activeProfile);\r\n\r\n // The attachment position remains in original Spine source units and therefore inherits the\r\n // fitted Spine scale. For example, y=-650 at a 1/3 fit becomes roughly -217 on the UI scene.\r\n // Only the host's linear transform is compensated, so the target itself does not shrink.\r\n const hostA = (spineWorld.d * parentWorld.a - spineWorld.c * parentWorld.b) / determinant;\r\n const hostB = (-spineWorld.b * parentWorld.a + spineWorld.a * parentWorld.b) / determinant;\r\n const hostC = (spineWorld.d * parentWorld.c - spineWorld.c * parentWorld.d) / determinant;\r\n const hostD = (-spineWorld.b * parentWorld.c + spineWorld.a * parentWorld.d) / determinant;\r\n connector.host.setFromMatrix(new Matrix(\r\n hostA,\r\n hostB,\r\n hostC,\r\n hostD,\r\n spineX * multiplier.x,\r\n spineY * multiplier.y,\r\n ));\r\n connector.host.visible = slot === null\r\n || (spine.skeleton.drawOrder.includes(slot) && slot.attachment !== null && spine.alpha > 0 && spine.skeleton.color.a * slot.color.a > 0);\r\n connector.target.position.set(0, 0);\r\n }\r\n }\r\n\r\n private restoreConnectorTargets(): void {\r\n for (const connector of this.activeConnectors) {\r\n const { target, parent } = connector;\r\n if (!target.destroyed && !parent.destroyed) {\r\n const index = Math.min(connector.index, parent.children.length);\r\n parent.addChildAt(target, index);\r\n target.position.set(connector.position.x, connector.position.y);\r\n target.scale.set(connector.scale.x, connector.scale.y);\r\n target.skew.set(connector.skew.x, connector.skew.y);\r\n target.pivot.set(connector.pivot.x, connector.pivot.y);\r\n target.rotation = connector.rotation;\r\n }\r\n connector.host.destroy({ children: false });\r\n }\r\n this.activeConnectors = [];\r\n }\r\n\r\n setReferenceFrame(referenceFrame: SpineReferenceFrame | undefined): void {\r\n this.referenceFrame = referenceFrame;\r\n }\r\n\r\n /**\r\n * Every transform application (editor gesture previews, document commits, layout updates, anchor\r\n * resizes) recomputes active connector hosts immediately. The host's local matrix depends on the\r\n * spine's world transform — including the fitted width/height scale — so a resize of the spine\r\n * node must move its targets in the same pass, not on the next ticker frame or document commit.\r\n */\r\n protected onLayoutTransformApplied(): void {\r\n if (this.connectorBonesActive) this.refreshConnectorBones();\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"], profile: LayoutProfileId): void {\r\n this.activeProfile = profile;\r\n if (node.type === \"spine\" && this.content !== undefined) this.content.alpha = node.opacity ?? 1;\r\n if (this.content instanceof Spine) {\r\n if (node.type === \"spine\") {\r\n const settings = resolveSpineSettings(node, profile);\r\n const track = this.content.state.tracks[0];\r\n const animationChanged = track?.animation?.name !== settings.animation;\r\n const loopChanged = track !== null && track !== undefined && track.loop !== settings.loop;\r\n // Same \"always a track, frozen at frame 0 unless actually playing\" contract as the constructor:\r\n // a static (non-autoplay) skeleton stays posed to its configured animation's first frame,\r\n // never Spine's setup/bind pose.\r\n const playing = settings.autoplay || this.initializeForAuthoring;\r\n const desiredTimeScale = playing ? settings.animationSpeed : 0;\r\n // Правка ползунка должна влиять на следующий переход, а не только на момент создания view.\r\n this.content.state.data.defaultMix = settings.animationMix;\r\n if (settings.animation === undefined) {\r\n if (track !== null && track !== undefined) this.content.state.clearTrack(0);\r\n } else if ((animationChanged || loopChanged) && this.content.skeleton.data.findAnimation(settings.animation) !== null) {\r\n const entry = this.content.state.setAnimation(0, settings.animation, settings.loop);\r\n entry.timeScale = desiredTimeScale;\r\n // Замороженный на кадре 0 скелет не проигрывает микс (mixTime двигается временем трека),\r\n // и остался бы навсегда в полусмешанной позе — статичной ноде переход всегда мгновенный.\r\n if (!playing) entry.mixDuration = 0;\r\n } else if (track !== null && track !== undefined) {\r\n track.timeScale = desiredTimeScale;\r\n }\r\n }\r\n const fit = fitSpineToTransform(this.content.skeleton.data, transform, this.referenceFrame);\r\n if (fit !== undefined) {\r\n this.content.scale.set(fit.scaleX, fit.scaleY);\r\n this.content.position.set(fit.x, fit.y);\r\n }\r\n // A paused Spine does not receive a ticker update. Refresh its world transforms after a\r\n // layout/viewport change so its displayed pose immediately matches the new fitted bounds.\r\n this.content.update(0);\r\n } else if (this.content instanceof Graphics) {\r\n this.content.clear().rect(0, 0, transform.width, transform.height).fill(0xff00ff);\r\n }\r\n }\r\n}\r\n"]}
@@ -40,7 +40,7 @@ export function createNodeView(node, interaction, textures, spines, hasPrefab, f
40
40
  case "bitmap-text":
41
41
  return new BitmapTextNodeView(bitmapFonts);
42
42
  case "spine":
43
- return new SpineNodeView(spines?.get(node.assetId), node.animation, node.autoplay ?? true, node.loop ?? true, node.animationSpeed ?? 1, interaction === "authoring", spineReferenceFrame, ticker);
43
+ return new SpineNodeView(spines?.get(node.assetId), node.animation, node.autoplay ?? true, node.loop ?? true, node.animationSpeed ?? 1, interaction === "authoring", spineReferenceFrame, ticker, node.animationMix ?? 0);
44
44
  case "button":
45
45
  return new ButtonNodeView(node, textures, interaction, audio);
46
46
  case "staged-button":
@@ -1 +1 @@
1
- {"version":3,"file":"createNodeView.js","sourceRoot":"","sources":["../../src/views/createNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { BUTTON_STATE_KEYS, CHECKBOX_STATE_KEYS, type ParticleEffectDefinition, type SpineReferenceFrame, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { type SkeletonData } from \"@esotericsoftware/spine-pixi-v8\";\r\nimport { Container, Texture, type Ticker } from \"pixi.js\";\r\nimport { ButtonNodeView } from \"./ButtonNodeView.js\";\r\nimport { CheckboxNodeView } from \"./CheckboxNodeView.js\";\r\nimport { BitmapTextNodeView, ContainerNodeView, ImageNodeView, LayoutGroupNodeView, MaskNodeView, OpacityGroupNodeView, PrefabInstanceNodeView, TextNodeView } from \"./basic.js\";\r\nimport { InputNodeView } from \"./InputNodeView.js\";\r\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.js\";\r\nimport type { SceneAudio } from \"../audio/bus.js\";\r\nimport { ItemTableNodeView } from \"./ItemTableNodeView.js\";\r\nimport { PageGroupNodeView } from \"./PageGroupNodeView.js\";\r\nimport { PaginationNodeView } from \"./PaginationNodeView.js\";\r\nimport { ScrollViewNodeView } from \"./ScrollViewNodeView.js\";\r\nimport { SpineNodeView } from \"./SpineNodeView.js\";\r\nimport { StagedButtonNodeView } from \"./StagedButtonNodeView.js\";\r\nimport { ProgressBarNodeView, SliderNodeView } from \"./ValueControlNodeViews.js\";\r\nimport { ParticleEmitterNodeView } from \"./ParticleEmitterNodeView.js\";\r\n\r\n/**\r\n * `hasPrefab` только сообщает, существует ли определение пресета: содержимое инстанса приходит его\r\n * обычными детьми из общего резолвера иерархии, а не отдельной веткой сборки.\r\n */\r\nexport function createNodeView(node: UINode, interaction: SceneInteractionMode, textures?: ReadonlyMap<string, Texture>, spines?: ReadonlyMap<string, SkeletonData>, hasPrefab?: (prefabId: string) => boolean, fonts?: ReadonlyMap<string, string>, audio?: SceneAudio, effect?: ParticleEffectDefinition, spineReferenceFrame?: SpineReferenceFrame, ticker?: Ticker, bitmapFonts?: ReadonlyMap<string, string>): NodeView {\r\n switch (node.type) {\r\n case \"container\":\r\n return new ContainerNodeView();\r\n case \"mask\":\r\n return new MaskNodeView();\r\n case \"opacity-group\":\r\n return new OpacityGroupNodeView(interaction);\r\n case \"horizontal-layout\":\r\n case \"vertical-layout\":\r\n case \"grid-layout\":\r\n return new LayoutGroupNodeView(textures);\r\n case \"scroll-view\":\r\n return new ScrollViewNodeView(node, textures, interaction);\r\n case \"page-group\":\r\n return new PageGroupNodeView(node, textures);\r\n case \"item-table\":\r\n return new ItemTableNodeView();\r\n case \"image\":\r\n return new ImageNodeView(node.assetId, textures, node.nineSlice);\r\n case \"text\":\r\n return new TextNodeView(node.text, fonts);\r\n case \"bitmap-text\":\r\n return new BitmapTextNodeView(bitmapFonts);\r\n case \"spine\":\r\n return new SpineNodeView(spines?.get(node.assetId), node.animation, node.autoplay ?? true, node.loop ?? true, node.animationSpeed ?? 1, interaction === \"authoring\", spineReferenceFrame, ticker);\r\n case \"button\":\r\n return new ButtonNodeView(node, textures, interaction, audio);\r\n case \"staged-button\":\r\n return new StagedButtonNodeView(node, textures, interaction, audio);\r\n case \"checkbox\":\r\n return new CheckboxNodeView(node, textures, interaction, audio);\r\n case \"input\":\r\n return new InputNodeView(node, textures, interaction, fonts);\r\n case \"slider\":\r\n return new SliderNodeView(node, textures, interaction, fonts);\r\n case \"progress-bar\":\r\n return new ProgressBarNodeView(node, textures);\r\n case \"pagination\":\r\n return new PaginationNodeView(node, textures, interaction, fonts);\r\n case \"particle-emitter\":\r\n return effect === undefined ? new ContainerNodeView() : new ParticleEmitterNodeView(effect, textures);\r\n case \"prefab-instance\":\r\n return new PrefabInstanceNodeView(hasPrefab?.(node.prefabId) ?? false);\r\n }\r\n}\r\n\r\n/**\r\n * Every asset a node references: the image, the Spine data, or each of a button's state images.\r\n * Single source of truth for \"which assets does this node use\" — texture loading and the editor's\r\n * usage count both read it, so a new node type can never silently drop out of one of them.\r\n */\r\nexport function collectNodeAssetIds(node: UINode): string[] {\r\n switch (node.type) {\r\n case \"image\":\r\n return node.assetId === undefined ? [] : [node.assetId];\r\n case \"spine\":\r\n return [node.assetId];\r\n case \"button\":\r\n return [\r\n ...BUTTON_STATE_KEYS\r\n .map((state) => node.states[`${state}AssetId`])\r\n .filter((assetId): assetId is string => assetId !== undefined),\r\n ...[node.sounds?.pressAssetId, node.sounds?.hoverAssetId].filter((assetId): assetId is string => assetId !== undefined),\r\n ];\r\n case \"staged-button\":\r\n return [...new Set([\r\n ...node.stages.flatMap((stage) => BUTTON_STATE_KEYS.map((state) => stage.states[`${state}AssetId`])),\r\n node.sounds?.pressAssetId,\r\n node.sounds?.hoverAssetId,\r\n ].filter((assetId): assetId is string => assetId !== undefined))];\r\n case \"checkbox\":\r\n return [\r\n ...CHECKBOX_STATE_KEYS\r\n .map((state) => node.states[`${state}AssetId`])\r\n .filter((assetId): assetId is string => assetId !== undefined),\r\n ...[node.sounds?.checkAssetId, node.sounds?.uncheckAssetId].filter((assetId): assetId is string => assetId !== undefined),\r\n ];\r\n case \"container\":\r\n case \"mask\":\r\n case \"opacity-group\":\r\n case \"item-table\":\r\n case \"prefab-instance\":\r\n return [];\r\n case \"horizontal-layout\":\r\n case \"vertical-layout\":\r\n case \"grid-layout\": {\r\n const backgroundAssetId = node.backgroundAssetId;\r\n return backgroundAssetId === undefined ? [] : [backgroundAssetId];\r\n }\r\n case \"scroll-view\":\r\n case \"page-group\":\r\n return [];\r\n case \"text\":\r\n return [...new Set([\r\n node.style?.fontAssetId,\r\n node.textStyleOverrides?.desktop?.fontAssetId,\r\n node.textStyleOverrides?.mobile?.fontAssetId,\r\n ].filter((assetId): assetId is string => assetId !== undefined))];\r\n case \"bitmap-text\":\r\n return [...new Set([node.assetId, node.bitmapTextOverrides?.desktop?.assetId, node.bitmapTextOverrides?.mobile?.assetId].filter((assetId): assetId is string => assetId !== undefined))];\r\n case \"input\": {\r\n const ids: string[] = [];\r\n if (node.backgroundAssetId !== undefined) ids.push(node.backgroundAssetId);\r\n if (node.textStyle.fontAssetId !== undefined) ids.push(node.textStyle.fontAssetId);\r\n return ids;\r\n }\r\n case \"slider\": {\r\n const ids = [node.backgroundAssetId, node.fillAssetId, node.handleAssetId];\r\n if (node.valueTextStyle?.fontAssetId !== undefined) ids.push(node.valueTextStyle.fontAssetId);\r\n return ids;\r\n }\r\n case \"progress-bar\":\r\n return [node.backgroundAssetId, node.fillAssetId];\r\n case \"pagination\":\r\n return [node.activeAssetId, node.inactiveAssetId, node.numberStyle?.fontAssetId].filter((assetId): assetId is string => assetId !== undefined);\r\n case \"particle-emitter\":\r\n return [];\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"createNodeView.js","sourceRoot":"","sources":["../../src/views/createNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { BUTTON_STATE_KEYS, CHECKBOX_STATE_KEYS, type ParticleEffectDefinition, type SpineReferenceFrame, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { type SkeletonData } from \"@esotericsoftware/spine-pixi-v8\";\r\nimport { Container, Texture, type Ticker } from \"pixi.js\";\r\nimport { ButtonNodeView } from \"./ButtonNodeView.js\";\r\nimport { CheckboxNodeView } from \"./CheckboxNodeView.js\";\r\nimport { BitmapTextNodeView, ContainerNodeView, ImageNodeView, LayoutGroupNodeView, MaskNodeView, OpacityGroupNodeView, PrefabInstanceNodeView, TextNodeView } from \"./basic.js\";\r\nimport { InputNodeView } from \"./InputNodeView.js\";\r\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.js\";\r\nimport type { SceneAudio } from \"../audio/bus.js\";\r\nimport { ItemTableNodeView } from \"./ItemTableNodeView.js\";\r\nimport { PageGroupNodeView } from \"./PageGroupNodeView.js\";\r\nimport { PaginationNodeView } from \"./PaginationNodeView.js\";\r\nimport { ScrollViewNodeView } from \"./ScrollViewNodeView.js\";\r\nimport { SpineNodeView } from \"./SpineNodeView.js\";\r\nimport { StagedButtonNodeView } from \"./StagedButtonNodeView.js\";\r\nimport { ProgressBarNodeView, SliderNodeView } from \"./ValueControlNodeViews.js\";\r\nimport { ParticleEmitterNodeView } from \"./ParticleEmitterNodeView.js\";\r\n\r\n/**\r\n * `hasPrefab` только сообщает, существует ли определение пресета: содержимое инстанса приходит его\r\n * обычными детьми из общего резолвера иерархии, а не отдельной веткой сборки.\r\n */\r\nexport function createNodeView(node: UINode, interaction: SceneInteractionMode, textures?: ReadonlyMap<string, Texture>, spines?: ReadonlyMap<string, SkeletonData>, hasPrefab?: (prefabId: string) => boolean, fonts?: ReadonlyMap<string, string>, audio?: SceneAudio, effect?: ParticleEffectDefinition, spineReferenceFrame?: SpineReferenceFrame, ticker?: Ticker, bitmapFonts?: ReadonlyMap<string, string>): NodeView {\r\n switch (node.type) {\r\n case \"container\":\r\n return new ContainerNodeView();\r\n case \"mask\":\r\n return new MaskNodeView();\r\n case \"opacity-group\":\r\n return new OpacityGroupNodeView(interaction);\r\n case \"horizontal-layout\":\r\n case \"vertical-layout\":\r\n case \"grid-layout\":\r\n return new LayoutGroupNodeView(textures);\r\n case \"scroll-view\":\r\n return new ScrollViewNodeView(node, textures, interaction);\r\n case \"page-group\":\r\n return new PageGroupNodeView(node, textures);\r\n case \"item-table\":\r\n return new ItemTableNodeView();\r\n case \"image\":\r\n return new ImageNodeView(node.assetId, textures, node.nineSlice);\r\n case \"text\":\r\n return new TextNodeView(node.text, fonts);\r\n case \"bitmap-text\":\r\n return new BitmapTextNodeView(bitmapFonts);\r\n case \"spine\":\r\n return new SpineNodeView(spines?.get(node.assetId), node.animation, node.autoplay ?? true, node.loop ?? true, node.animationSpeed ?? 1, interaction === \"authoring\", spineReferenceFrame, ticker, node.animationMix ?? 0);\r\n case \"button\":\r\n return new ButtonNodeView(node, textures, interaction, audio);\r\n case \"staged-button\":\r\n return new StagedButtonNodeView(node, textures, interaction, audio);\r\n case \"checkbox\":\r\n return new CheckboxNodeView(node, textures, interaction, audio);\r\n case \"input\":\r\n return new InputNodeView(node, textures, interaction, fonts);\r\n case \"slider\":\r\n return new SliderNodeView(node, textures, interaction, fonts);\r\n case \"progress-bar\":\r\n return new ProgressBarNodeView(node, textures);\r\n case \"pagination\":\r\n return new PaginationNodeView(node, textures, interaction, fonts);\r\n case \"particle-emitter\":\r\n return effect === undefined ? new ContainerNodeView() : new ParticleEmitterNodeView(effect, textures);\r\n case \"prefab-instance\":\r\n return new PrefabInstanceNodeView(hasPrefab?.(node.prefabId) ?? false);\r\n }\r\n}\r\n\r\n/**\r\n * Every asset a node references: the image, the Spine data, or each of a button's state images.\r\n * Single source of truth for \"which assets does this node use\" — texture loading and the editor's\r\n * usage count both read it, so a new node type can never silently drop out of one of them.\r\n */\r\nexport function collectNodeAssetIds(node: UINode): string[] {\r\n switch (node.type) {\r\n case \"image\":\r\n return node.assetId === undefined ? [] : [node.assetId];\r\n case \"spine\":\r\n return [node.assetId];\r\n case \"button\":\r\n return [\r\n ...BUTTON_STATE_KEYS\r\n .map((state) => node.states[`${state}AssetId`])\r\n .filter((assetId): assetId is string => assetId !== undefined),\r\n ...[node.sounds?.pressAssetId, node.sounds?.hoverAssetId].filter((assetId): assetId is string => assetId !== undefined),\r\n ];\r\n case \"staged-button\":\r\n return [...new Set([\r\n ...node.stages.flatMap((stage) => BUTTON_STATE_KEYS.map((state) => stage.states[`${state}AssetId`])),\r\n node.sounds?.pressAssetId,\r\n node.sounds?.hoverAssetId,\r\n ].filter((assetId): assetId is string => assetId !== undefined))];\r\n case \"checkbox\":\r\n return [\r\n ...CHECKBOX_STATE_KEYS\r\n .map((state) => node.states[`${state}AssetId`])\r\n .filter((assetId): assetId is string => assetId !== undefined),\r\n ...[node.sounds?.checkAssetId, node.sounds?.uncheckAssetId].filter((assetId): assetId is string => assetId !== undefined),\r\n ];\r\n case \"container\":\r\n case \"mask\":\r\n case \"opacity-group\":\r\n case \"item-table\":\r\n case \"prefab-instance\":\r\n return [];\r\n case \"horizontal-layout\":\r\n case \"vertical-layout\":\r\n case \"grid-layout\": {\r\n const backgroundAssetId = node.backgroundAssetId;\r\n return backgroundAssetId === undefined ? [] : [backgroundAssetId];\r\n }\r\n case \"scroll-view\":\r\n case \"page-group\":\r\n return [];\r\n case \"text\":\r\n return [...new Set([\r\n node.style?.fontAssetId,\r\n node.textStyleOverrides?.desktop?.fontAssetId,\r\n node.textStyleOverrides?.mobile?.fontAssetId,\r\n ].filter((assetId): assetId is string => assetId !== undefined))];\r\n case \"bitmap-text\":\r\n return [...new Set([node.assetId, node.bitmapTextOverrides?.desktop?.assetId, node.bitmapTextOverrides?.mobile?.assetId].filter((assetId): assetId is string => assetId !== undefined))];\r\n case \"input\": {\r\n const ids: string[] = [];\r\n if (node.backgroundAssetId !== undefined) ids.push(node.backgroundAssetId);\r\n if (node.textStyle.fontAssetId !== undefined) ids.push(node.textStyle.fontAssetId);\r\n return ids;\r\n }\r\n case \"slider\": {\r\n const ids = [node.backgroundAssetId, node.fillAssetId, node.handleAssetId];\r\n if (node.valueTextStyle?.fontAssetId !== undefined) ids.push(node.valueTextStyle.fontAssetId);\r\n return ids;\r\n }\r\n case \"progress-bar\":\r\n return [node.backgroundAssetId, node.fillAssetId];\r\n case \"pagination\":\r\n return [node.activeAssetId, node.inactiveAssetId, node.numberStyle?.fontAssetId].filter((assetId): assetId is string => assetId !== undefined);\r\n case \"particle-emitter\":\r\n return [];\r\n }\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixi-ui-editor/runtime-pixi",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "PixiJS runtime that renders Pixi UI Editor scene documents in a game.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -30,7 +30,7 @@
30
30
  "pixi.js": "^8.19.0",
31
31
  "typed-signals": "^2.5.0",
32
32
  "yoga-layout": "^3.2.1",
33
- "@pixi-ui-editor/schema": "0.20.0"
33
+ "@pixi-ui-editor/schema": "0.21.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^26.2.0"