@pixi-ui-editor/runtime-pixi 0.5.1 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/controls.d.ts +19 -0
  2. package/dist/controls.d.ts.map +1 -1
  3. package/dist/controls.js +40 -0
  4. package/dist/controls.js.map +1 -1
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +3 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/layoutGroups.js.map +1 -1
  10. package/dist/pageGroup.d.ts +17 -0
  11. package/dist/pageGroup.d.ts.map +1 -0
  12. package/dist/pageGroup.js +20 -0
  13. package/dist/pageGroup.js.map +1 -0
  14. package/dist/particles.d.ts +5 -2
  15. package/dist/particles.d.ts.map +1 -1
  16. package/dist/particles.js +57 -12
  17. package/dist/particles.js.map +1 -1
  18. package/dist/scene.d.ts.map +1 -1
  19. package/dist/scene.js +43 -2
  20. package/dist/scene.js.map +1 -1
  21. package/dist/views/NodeView.d.ts +2 -2
  22. package/dist/views/NodeView.d.ts.map +1 -1
  23. package/dist/views/NodeView.js.map +1 -1
  24. package/dist/views/PageGroupNodeView.d.ts +42 -0
  25. package/dist/views/PageGroupNodeView.d.ts.map +1 -0
  26. package/dist/views/PageGroupNodeView.js +72 -0
  27. package/dist/views/PageGroupNodeView.js.map +1 -0
  28. package/dist/views/PaginationNodeView.d.ts +59 -0
  29. package/dist/views/PaginationNodeView.d.ts.map +1 -0
  30. package/dist/views/PaginationNodeView.js +238 -0
  31. package/dist/views/PaginationNodeView.js.map +1 -0
  32. package/dist/views/ParticleEmitterNodeView.d.ts +13 -0
  33. package/dist/views/ParticleEmitterNodeView.d.ts.map +1 -1
  34. package/dist/views/ParticleEmitterNodeView.js +164 -32
  35. package/dist/views/ParticleEmitterNodeView.js.map +1 -1
  36. package/dist/views/SpineNodeView.d.ts +23 -2
  37. package/dist/views/SpineNodeView.d.ts.map +1 -1
  38. package/dist/views/SpineNodeView.js +131 -2
  39. package/dist/views/SpineNodeView.js.map +1 -1
  40. package/dist/views/basic.d.ts.map +1 -1
  41. package/dist/views/basic.js +3 -1
  42. package/dist/views/basic.js.map +1 -1
  43. package/dist/views/createNodeView.d.ts.map +1 -1
  44. package/dist/views/createNodeView.js +9 -0
  45. package/dist/views/createNodeView.js.map +1 -1
  46. package/package.json +5 -3
  47. package/dist/assets/spine.test.d.ts +0 -2
  48. package/dist/assets/spine.test.d.ts.map +0 -1
  49. package/dist/assets/spine.test.js +0 -42
  50. package/dist/assets/spine.test.js.map +0 -1
  51. package/dist/index.test.d.ts +0 -2
  52. package/dist/index.test.d.ts.map +0 -1
  53. package/dist/index.test.js +0 -485
  54. package/dist/index.test.js.map +0 -1
  55. package/dist/particles.test.d.ts +0 -2
  56. package/dist/particles.test.d.ts.map +0 -1
  57. package/dist/particles.test.js +0 -210
  58. package/dist/particles.test.js.map +0 -1
  59. package/dist/test.setup.d.ts +0 -2
  60. package/dist/test.setup.d.ts.map +0 -1
  61. package/dist/test.setup.js +0 -6
  62. package/dist/test.setup.js.map +0 -1
  63. package/dist/views/ParticleEmitterNodeView.test.d.ts +0 -2
  64. package/dist/views/ParticleEmitterNodeView.test.d.ts.map +0 -1
  65. package/dist/views/ParticleEmitterNodeView.test.js +0 -148
  66. package/dist/views/ParticleEmitterNodeView.test.js.map +0 -1
@@ -111,11 +111,13 @@ export class ImageNodeView extends NodeView {
111
111
  this.setContent(new Graphics());
112
112
  const graphics = this.content.clear().rect(0, 0, transform.width, transform.height);
113
113
  if (node.assetId === undefined)
114
- graphics.fill(0xffffff);
114
+ graphics.fill(node.tint ?? 0xffffff);
115
115
  else
116
116
  graphics.fill(0x4a5568).stroke({ width: 1, color: 0x94a3b8 });
117
117
  }
118
118
  this.content.alpha = node.opacity ?? 1;
119
+ if (this.content instanceof Sprite || this.content instanceof NineSliceSprite)
120
+ this.content.tint = node.tint ?? 0xffffff;
119
121
  }
120
122
  /**
121
123
  * Editor-only live preview of border edits while dragging the canvas nine-slice gizmo; the
@@ -1 +1 @@
1
- {"version":3,"file":"basic.js","sourceRoot":"","sources":["../../src/views/basic.ts"],"names":[],"mappings":"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","sourcesContent":["import { type BitmapTextNode, type LayoutPadding, type LayoutProfileId, type TextNode, type TextStyleDefinition, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { BitmapText, Container, Graphics, NineSliceSprite, Sprite, Text, Texture } from \"pixi.js\";\r\nimport { NodeView } from \"./NodeView.js\";\r\nimport { resolveTextStyle } from \"../layout.js\";\r\n\r\nexport class ContainerNodeView extends NodeView {\r\n protected syncContent(): void {}\r\n}\r\n\r\n/** Clips every authored child to the node's resolved rectangular layout area. */\r\nexport class MaskNodeView extends NodeView {\r\n private readonly maskShape = new Graphics();\r\n\r\n constructor() {\r\n super();\r\n this.addChild(this.maskShape);\r\n // A Graphics mask keeps the shape GPU-native and avoids the offscreen texture pass of alpha masks.\r\n // Pixi's regular mask contract also preserves correct clipping through rotation and transformed parents.\r\n this.mask = this.maskShape;\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"]): void {\r\n if (node.type !== \"mask\") return;\r\n this.maskShape.clear().rect(0, 0, transform.width, transform.height).fill(0xffffff);\r\n }\r\n}\r\n\r\n/** Layout groups may optionally paint one image behind their managed children. No asset means no content/view at all. */\r\nexport class LayoutGroupNodeView extends NodeView {\r\n private readonly layoutContent = new Container();\r\n private background?: Sprite;\r\n\r\n constructor(textures: ReadonlyMap<string, Texture> | undefined) {\r\n super(textures);\r\n // Yoga owns this inner container only. The NodeView itself retains the authored transform,\r\n // pivot and grab rectangle used by both editor gizmos and runtime interaction.\r\n super.addChild(this.layoutContent);\r\n }\r\n\r\n get layoutTarget(): Container { return this.layoutContent; }\r\n\r\n addLayoutChild<T extends Container[]>(...children: T): T[0] {\r\n return this.layoutContent.addChild(...children);\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"]): void {\r\n if (node.type !== \"horizontal-layout\" && node.type !== \"vertical-layout\" && node.type !== \"grid-layout\") return;\r\n const texture = node.backgroundAssetId === undefined ? undefined : this.textureFor(node.backgroundAssetId);\r\n if (texture === undefined) {\r\n if (this.background !== undefined) { super.removeChild(this.background); this.background.destroy(); this.background = undefined; }\r\n return;\r\n }\r\n if (this.background === undefined) { this.background = new Sprite(texture); super.addChildAt(this.background, 0); }\r\n else if (this.background.texture !== texture) this.background.texture = texture;\r\n this.background.setSize(transform.width, transform.height);\r\n }\r\n}\r\n\r\n/**\r\n * Ноде-картинке источник не обязателен: без `assetId` она рисует белый прямоугольник своего размера,\r\n * а серо-синяя заглушка остаётся признаком того, что назначенный ассет не загрузился.\r\n *\r\n * `nineSlice` переключает контент на `NineSliceSprite`: углы источника остаются нерастянутыми, а\r\n * растягиваются только края/середина — то же 9-slice, что уже использует Slider/ProgressBar через\r\n * `@pixi/ui`'s `fillPaddings`, только здесь это применяется напрямую к содержимому Image-ноды.\r\n */\r\nexport class ImageNodeView extends NodeView {\r\n constructor(assetId: string | undefined, textures: ReadonlyMap<string, Texture> | undefined, nineSlice?: LayoutPadding) {\r\n super(textures);\r\n const texture = assetId === undefined ? undefined : this.textureFor(assetId);\r\n this.setContent(ImageNodeView.createSpriteContent(texture, nineSlice));\r\n }\r\n\r\n private static createSpriteContent(texture: Texture | undefined, nineSlice: LayoutPadding | undefined): Container {\r\n if (texture === undefined) return new Graphics();\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 protected syncContent(node: UINode, transform: UINode[\"transform\"]): void {\r\n if (node.type !== \"image\") return;\r\n const texture = node.assetId === undefined ? undefined : this.textureFor(node.assetId);\r\n const nineSlice = node.nineSlice;\r\n // Sprite ↔ NineSliceSprite ↔ Graphics меняются местами прямо здесь: структурный ключ сцены не\r\n // включает assetId/nineSlice, поэтому переключение (в том числе на None) не пересобирает сцену.\r\n if (texture !== undefined && nineSlice !== undefined) {\r\n if (!(this.content instanceof NineSliceSprite)) this.setContent(ImageNodeView.createSpriteContent(texture, nineSlice));\r\n const sprite = this.content as NineSliceSprite;\r\n // Keep the NineSliceSprite and its layout rectangle stable when its image asset/borders change.\r\n if (sprite.texture !== texture) sprite.texture = texture;\r\n sprite.leftWidth = nineSlice.left;\r\n sprite.topHeight = nineSlice.top;\r\n sprite.rightWidth = nineSlice.right;\r\n sprite.bottomHeight = nineSlice.bottom;\r\n sprite.setSize(transform.width, transform.height);\r\n } else if (texture !== undefined) {\r\n // `NineSliceSprite` is a Sprite sibling, not a subclass, so this rebuilds when switching back from it.\r\n if (!(this.content instanceof Sprite)) this.setContent(new Sprite(texture));\r\n const sprite = this.content as Sprite;\r\n // Keep the Sprite and its layout rectangle stable when its image asset changes.\r\n if (sprite.texture !== texture) sprite.texture = texture;\r\n sprite.setSize(transform.width, transform.height);\r\n } else {\r\n if (!(this.content instanceof Graphics)) this.setContent(new Graphics());\r\n const graphics = (this.content as Graphics).clear().rect(0, 0, transform.width, transform.height);\r\n if (node.assetId === undefined) graphics.fill(0xffffff);\r\n else graphics.fill(0x4a5568).stroke({ width: 1, color: 0x94a3b8 });\r\n }\r\n this.content!.alpha = node.opacity ?? 1;\r\n }\r\n\r\n /**\r\n * Editor-only live preview of border edits while dragging the canvas nine-slice gizmo; the\r\n * document is only written once, on drag release. A no-op without a `NineSliceSprite` content —\r\n * e.g. mid-drag right after the asset was cleared, before the next document sync catches up.\r\n */\r\n previewNineSlice(nineSlice: LayoutPadding): void {\r\n if (!(this.content instanceof NineSliceSprite)) return;\r\n this.content.leftWidth = nineSlice.left;\r\n this.content.topHeight = nineSlice.top;\r\n this.content.rightWidth = nineSlice.right;\r\n this.content.bottomHeight = nineSlice.bottom;\r\n }\r\n}\r\n\r\nexport class TextNodeView extends NodeView {\r\n /**\r\n * Строка, применённая локализацией поверх авторской. Она переживает `updateNodeView`: без неё\r\n * любая синхронизация документа возвращала бы fallback `node.text` вместо текущего перевода.\r\n */\r\n private localizedText?: string;\r\n /** Последний применённый прямоугольник и стиль — их же переиспользует инкрементальный `setText`. */\r\n private lastTransform?: UINode[\"transform\"];\r\n private lastStyle?: TextStyleDefinition;\r\n\r\n constructor(text: string, private readonly fonts?: ReadonlyMap<string, string>) {\r\n super();\r\n this.setContent(new Text({ text, style: { fontFamily: \"Arial\", fontSize: 24, fill: 0xffffff } }));\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"], profile: LayoutProfileId): void {\r\n if (node.type !== \"text\" || !(this.content instanceof Text)) return;\r\n const text = this.localizedText ?? node.text;\r\n if (this.content.text !== text) this.content.text = text;\r\n const style = resolveTextStyle(node, profile);\r\n this.lastTransform = transform;\r\n this.lastStyle = style;\r\n if (style === undefined) return;\r\n this.applyFittedStyle(this.content, node, style, transform);\r\n this.align();\r\n }\r\n\r\n /**\r\n * Applies the resolved style at the largest font size (down to `minFontSize`) that keeps the\r\n * rendered text inside `transform`, when `autoSize` is on — the same \"shrink, never grow past the\r\n * authored size\" contract as `BitmapTextNodeView.applyFittedStyle` / Unity legacy Text's Best Fit.\r\n * A binary search over candidate sizes rather than a closed-form scale, because word-wrapped text\r\n * re-flows at every size: a smaller font fits more words per line, so height doesn't shrink linearly\r\n * with font size the way unwrapped bounds would — the same reasoning `measureOverflow` follows.\r\n */\r\n private applyFittedStyle(text: Text, node: TextNode, style: TextStyleDefinition, transform: UINode[\"transform\"]): void {\r\n const baseStyle = { fontFamily: style.fontAssetId === undefined ? style.fontFamily : this.fonts?.get(style.fontAssetId) ?? style.fontFamily, fontWeight: style.fontWeight, fontStyle: style.fontStyle, fill: style.fill, align: style.align, wordWrap: style.wordWrap, breakWords: style.breakWords, wordWrapWidth: transform.width, lineHeight: style.lineHeight, letterSpacing: style.letterSpacing, stroke: style.stroke === undefined ? undefined : { color: style.stroke.color, width: style.stroke.width } };\r\n const fits = (fontSize: number): boolean => {\r\n text.style = { ...baseStyle, fontSize };\r\n // Headless loaders and schema tests have no browser canvas to measure against; they keep the\r\n // authored fontSize, same boundary `align()` already respects.\r\n if (typeof globalThis.document === \"undefined\") return true;\r\n const bounds = text.getLocalBounds();\r\n const tolerance = 0.5;\r\n return style.wordWrap\r\n ? bounds.height <= transform.height + tolerance\r\n : bounds.width <= transform.width + tolerance && bounds.height <= transform.height + tolerance;\r\n };\r\n // Always runs at least once, applying `baseStyle` at the authored size as a side effect — not\r\n // just the shrink-check's fast path. Written as `||` short-circuit, `fits(style.fontSize)` would\r\n // never execute while `autoSize` is off, leaving `text.style` frozen at whatever the constructor\r\n // set it to and silently dropping every later font/color/align/wrap edit (see the identical fix\r\n // in `BitmapTextNodeView.applyFittedStyle`).\r\n const fitsAtAuthoredSize = fits(style.fontSize);\r\n if (node.autoSize !== true || fitsAtAuthoredSize) return;\r\n const minFontSize = Math.min(node.minFontSize ?? 1, style.fontSize);\r\n if (!fits(minFontSize)) return; // Best effort: even the floor overflows, so it stays at the floor.\r\n let lo = minFontSize, hi = style.fontSize;\r\n for (let i = 0; i < 8; i++) {\r\n const mid = (lo + hi) / 2;\r\n if (fits(mid)) lo = mid; else hi = mid;\r\n }\r\n fits(lo); // Leaves `text.style` applied at the converged, fitting size.\r\n }\r\n\r\n /**\r\n * Инкрементальная смена строки: та же строка не делает работы вообще, новая — только переизмеряет\r\n * и выравнивает текст в текущем authored rectangle. `TextStyle` не пересоздаётся, а сам view\r\n * сохраняет identity, поэтому смена локали не трогает ни сцену, ни GPU-ресурсы стиля.\r\n */\r\n setText(text: string): void {\r\n if (!(this.content instanceof Text) || this.content.text === text) return;\r\n this.content.text = text;\r\n this.align();\r\n }\r\n\r\n /** `undefined` возвращает ноду к авторской строке при следующей синхронизации документа. */\r\n setLocalizedText(text: string | undefined): void {\r\n this.localizedText = text;\r\n if (text !== undefined) this.setText(text);\r\n }\r\n\r\n /**\r\n * Rasterizes the canvas-based `Text` at a higher pixel density than the renderer's own backing\r\n * resolution, so authoring-camera zoom doesn't magnify an already-rasterized bitmap past its\r\n * source resolution. `Application.resolution` (see `resolveCanvasResolution`) only matches the\r\n * *display's* pixel density — it knows nothing about the editor's independent camera zoom, which\r\n * can reach 8x (`MAX_ZOOM`). Without this, zooming in to inspect a text node (exactly what\r\n * `autoSize`/shrink-to-fit users do, since it converges to a smaller font) reads as soft/blurred\r\n * even on a display this app already renders crisply on. A no-op if unchanged: assigning\r\n * `.resolution` always re-rasterizes, so skip it when the caller (the authoring canvas, on every\r\n * camera-zoom tick) passes back the same value.\r\n */\r\n setContentResolution(resolution: number): void {\r\n if (!(this.content instanceof Text) || this.content.resolution === resolution) return;\r\n this.content.resolution = resolution;\r\n }\r\n\r\n /**\r\n * Вылезает ли фактически отрисованный текст за логический прямоугольник ноды.\r\n *\r\n * Меряется уже готовый `Text`, а не длина строки: перенос по словам, шрифт и обводка известны\r\n * только рендеру. Без `wordWrap` переполнение возможно по ширине, с ним — по высоте, потому что\r\n * перенос сам удерживает ширину в пределах `wordWrapWidth`. Диагностика transient: она ничего не\r\n * пишет ни в документ, ни в view.\r\n */\r\n measureOverflow(): boolean {\r\n const transform = this.lastTransform;\r\n if (!(this.content instanceof Text) || transform === undefined || typeof globalThis.document === \"undefined\") return false;\r\n const bounds = this.content.getLocalBounds();\r\n const tolerance = 0.5;\r\n return this.lastStyle?.wordWrap === true\r\n ? bounds.height > transform.height + tolerance\r\n : bounds.width > transform.width + tolerance || bounds.height > transform.height + tolerance;\r\n }\r\n\r\n private align(): void {\r\n const transform = this.lastTransform;\r\n const style = this.lastStyle;\r\n if (!(this.content instanceof Text) || transform === undefined || style === undefined) return;\r\n // Headless loaders and schema tests intentionally have no browser canvas. In that boundary\r\n // text still owns its authored rectangle; browser rendering keeps the precise measurement.\r\n const bounds = typeof globalThis.document === \"undefined\" ? { x: 0, y: 0, width: 0, height: 0 } : this.content.getLocalBounds();\r\n this.content.x = style.align === \"center\" ? (transform.width - bounds.width) / 2 - bounds.x : style.align === \"right\" ? transform.width - bounds.width - bounds.x : -bounds.x;\r\n this.content.y = style.verticalAlign === \"middle\" ? (transform.height - bounds.height) / 2 - bounds.y : style.verticalAlign === \"bottom\" ? transform.height - bounds.height - bounds.y : -bounds.y;\r\n }\r\n}\r\n\r\n/**\r\n * A bitmap font's rendered glyphs come from its texture, not an arbitrary system/TTF face, so unlike\r\n * `TextNodeView` there is no style-driven fallback: without a loaded font (asset deleted, still\r\n * loading, or failed to parse) this draws the same missing-asset placeholder `ImageNodeView` does.\r\n */\r\nexport class BitmapTextNodeView extends NodeView {\r\n private lastTransform?: UINode[\"transform\"];\r\n private lastAlign: \"left\" | \"center\" | \"right\" = \"left\";\r\n private lastVerticalAlign: \"top\" | \"middle\" | \"bottom\" = \"top\";\r\n\r\n constructor(private readonly fonts?: ReadonlyMap<string, string>) {\r\n super();\r\n this.setContent(new Graphics());\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"]): void {\r\n if (node.type !== \"bitmap-text\") return;\r\n this.lastTransform = transform;\r\n this.lastAlign = node.align;\r\n this.lastVerticalAlign = node.verticalAlign;\r\n const family = this.fonts?.get(node.assetId);\r\n if (family === undefined) {\r\n if (!(this.content instanceof Graphics)) this.setContent(new Graphics());\r\n (this.content as Graphics).clear().rect(0, 0, transform.width, transform.height).fill(0x4a5568).stroke({ width: 1, color: 0x94a3b8 });\r\n return;\r\n }\r\n if (!(this.content instanceof BitmapText)) this.setContent(new BitmapText({ text: node.text, style: { fontFamily: family, fontSize: node.fontSize, fill: node.fill } }));\r\n const bitmapText = this.content as BitmapText;\r\n if (bitmapText.text !== node.text) bitmapText.text = node.text;\r\n this.applyFittedStyle(bitmapText, node, family, transform);\r\n this.align();\r\n }\r\n\r\n /**\r\n * Applies the node's style at the largest font size (down to `minFontSize`) that keeps the text\r\n * inside `transform`, when `autoSize` is on — the same \"shrink, never grow past the authored size\"\r\n * contract as Unity legacy Text's Best Fit. A binary search over candidate sizes rather than a\r\n * closed-form scale, because word-wrapped text re-flows at every size: a smaller font can fit more\r\n * words per line, so height doesn't shrink linearly with font size the way unwrapped bounds would.\r\n */\r\n private applyFittedStyle(bitmapText: BitmapText, node: BitmapTextNode, family: string, transform: UINode[\"transform\"]): void {\r\n const baseStyle = { fontFamily: family, fill: node.fill, align: node.align, letterSpacing: node.letterSpacing, wordWrap: node.wordWrap, wordWrapWidth: transform.width };\r\n const fits = (fontSize: number): boolean => {\r\n bitmapText.style = { ...baseStyle, fontSize };\r\n // Headless loaders and schema tests have no browser canvas to measure against; they keep the\r\n // authored fontSize, same boundary `align()` already respects.\r\n if (typeof globalThis.document === \"undefined\") return true;\r\n const bounds = bitmapText.getLocalBounds();\r\n const tolerance = 0.5;\r\n return node.wordWrap\r\n ? bounds.height <= transform.height + tolerance\r\n : bounds.width <= transform.width + tolerance && bounds.height <= transform.height + tolerance;\r\n };\r\n // Always runs at least once, applying `baseStyle` at the authored size as a side effect — not\r\n // just the shrink-check's fast path. Written as `||` short-circuit, `fits(node.fontSize)` would\r\n // never execute while `autoSize` is off, leaving `bitmapText.style` frozen at whatever the\r\n // constructor set it to and silently dropping every later fill/align/letterSpacing/wordWrap edit.\r\n const fitsAtAuthoredSize = fits(node.fontSize);\r\n if (node.autoSize !== true || fitsAtAuthoredSize) return;\r\n const minFontSize = Math.min(node.minFontSize ?? 1, node.fontSize);\r\n if (!fits(minFontSize)) return; // Best effort: even the floor overflows, so it stays at the floor.\r\n let lo = minFontSize, hi = node.fontSize;\r\n for (let i = 0; i < 8; i++) {\r\n const mid = (lo + hi) / 2;\r\n if (fits(mid)) lo = mid; else hi = mid;\r\n }\r\n fits(lo); // Leaves `bitmapText.style` applied at the converged, fitting size.\r\n }\r\n\r\n /**\r\n * Positions via PixiJS's own `anchor`, not a manual `getLocalBounds()` computation like\r\n * `TextNodeView.align()` uses: `BitmapText.updateBounds()` reports a coarse line-metrics box\r\n * (built from the font's `lineHeight`/`baseLineOffset`), not the tight pixel bounds a canvas\r\n * `Text` or `Sprite` reports. Its own glyphs are drawn with an additional baseline-derived offset\r\n * that box doesn't account for, so computing `-bounds.y`-style positions from it lands text\r\n * slightly (but consistently, for every vertical setting) off — `anchor` is the one code path\r\n * PixiJS keeps in sync with how it actually renders the glyphs.\r\n */\r\n private align(): void {\r\n const transform = this.lastTransform;\r\n if (!(this.content instanceof BitmapText) || transform === undefined) return;\r\n const anchorX = this.lastAlign === \"center\" ? 0.5 : this.lastAlign === \"right\" ? 1 : 0;\r\n const anchorY = this.lastVerticalAlign === \"middle\" ? 0.5 : this.lastVerticalAlign === \"bottom\" ? 1 : 0;\r\n this.content.anchor.set(anchorX, anchorY);\r\n this.content.x = anchorX * transform.width;\r\n this.content.y = anchorY * transform.height;\r\n }\r\n}\r\n\r\n/**\r\n * Содержимое инстанса приходит обычными детьми из общего резолвера иерархии. Собственный контент\r\n * нужен только как заметная заглушка, когда определение пресета отсутствует в документе.\r\n */\r\nexport class PrefabInstanceNodeView extends NodeView {\r\n constructor(resolved: boolean) {\r\n super();\r\n if (!resolved) this.setContent(new Graphics());\r\n }\r\n\r\n protected syncContent(_node: UINode, transform: UINode[\"transform\"]): void {\r\n if (this.content instanceof Graphics) this.content.clear().rect(0, 0, transform.width, transform.height).fill(0xff00ff);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"basic.js","sourceRoot":"","sources":["../../src/views/basic.ts"],"names":[],"mappings":"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","sourcesContent":["import { type BitmapTextNode, type LayoutPadding, type LayoutProfileId, type TextNode, type TextStyleDefinition, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { BitmapText, Container, Graphics, NineSliceSprite, Sprite, Text, Texture } from \"pixi.js\";\r\nimport { NodeView } from \"./NodeView.js\";\r\nimport { resolveTextStyle } from \"../layout.js\";\r\n\r\nexport class ContainerNodeView extends NodeView {\r\n protected syncContent(): void {}\r\n}\r\n\r\n/** Clips every authored child to the node's resolved rectangular layout area. */\r\nexport class MaskNodeView extends NodeView {\r\n private readonly maskShape = new Graphics();\r\n\r\n constructor() {\r\n super();\r\n this.addChild(this.maskShape);\r\n // A Graphics mask keeps the shape GPU-native and avoids the offscreen texture pass of alpha masks.\r\n // Pixi's regular mask contract also preserves correct clipping through rotation and transformed parents.\r\n this.mask = this.maskShape;\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"]): void {\r\n if (node.type !== \"mask\") return;\r\n this.maskShape.clear().rect(0, 0, transform.width, transform.height).fill(0xffffff);\r\n }\r\n}\r\n\r\n/** Layout groups may optionally paint one image behind their managed children. No asset means no content/view at all. */\r\nexport class LayoutGroupNodeView extends NodeView {\r\n private readonly layoutContent = new Container();\r\n private background?: Sprite;\r\n\r\n constructor(textures: ReadonlyMap<string, Texture> | undefined) {\r\n super(textures);\r\n // Yoga owns this inner container only. The NodeView itself retains the authored transform,\r\n // pivot and grab rectangle used by both editor gizmos and runtime interaction.\r\n super.addChild(this.layoutContent);\r\n }\r\n\r\n get layoutTarget(): Container { return this.layoutContent; }\r\n\r\n addLayoutChild<T extends Container[]>(...children: T): T[0] {\r\n return this.layoutContent.addChild(...children);\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"]): void {\r\n if (node.type !== \"horizontal-layout\" && node.type !== \"vertical-layout\" && node.type !== \"grid-layout\") return;\r\n const texture = node.backgroundAssetId === undefined ? undefined : this.textureFor(node.backgroundAssetId);\r\n if (texture === undefined) {\r\n if (this.background !== undefined) { super.removeChild(this.background); this.background.destroy(); this.background = undefined; }\r\n return;\r\n }\r\n if (this.background === undefined) { this.background = new Sprite(texture); super.addChildAt(this.background, 0); }\r\n else if (this.background.texture !== texture) this.background.texture = texture;\r\n this.background.setSize(transform.width, transform.height);\r\n }\r\n}\r\n\r\n/**\r\n * Ноде-картинке источник не обязателен: без `assetId` она рисует белый прямоугольник своего размера,\r\n * а серо-синяя заглушка остаётся признаком того, что назначенный ассет не загрузился.\r\n *\r\n * `nineSlice` переключает контент на `NineSliceSprite`: углы источника остаются нерастянутыми, а\r\n * растягиваются только края/середина — то же 9-slice, что уже использует Slider/ProgressBar через\r\n * `@pixi/ui`'s `fillPaddings`, только здесь это применяется напрямую к содержимому Image-ноды.\r\n */\r\nexport class ImageNodeView extends NodeView {\r\n constructor(assetId: string | undefined, textures: ReadonlyMap<string, Texture> | undefined, nineSlice?: LayoutPadding) {\r\n super(textures);\r\n const texture = assetId === undefined ? undefined : this.textureFor(assetId);\r\n this.setContent(ImageNodeView.createSpriteContent(texture, nineSlice));\r\n }\r\n\r\n private static createSpriteContent(texture: Texture | undefined, nineSlice: LayoutPadding | undefined): Container {\r\n if (texture === undefined) return new Graphics();\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 protected syncContent(node: UINode, transform: UINode[\"transform\"]): void {\r\n if (node.type !== \"image\") return;\r\n const texture = node.assetId === undefined ? undefined : this.textureFor(node.assetId);\r\n const nineSlice = node.nineSlice;\r\n // Sprite ↔ NineSliceSprite ↔ Graphics меняются местами прямо здесь: структурный ключ сцены не\r\n // включает assetId/nineSlice, поэтому переключение (в том числе на None) не пересобирает сцену.\r\n if (texture !== undefined && nineSlice !== undefined) {\r\n if (!(this.content instanceof NineSliceSprite)) this.setContent(ImageNodeView.createSpriteContent(texture, nineSlice));\r\n const sprite = this.content as NineSliceSprite;\r\n // Keep the NineSliceSprite and its layout rectangle stable when its image asset/borders change.\r\n if (sprite.texture !== texture) sprite.texture = texture;\r\n sprite.leftWidth = nineSlice.left;\r\n sprite.topHeight = nineSlice.top;\r\n sprite.rightWidth = nineSlice.right;\r\n sprite.bottomHeight = nineSlice.bottom;\r\n sprite.setSize(transform.width, transform.height);\r\n } else if (texture !== undefined) {\r\n // `NineSliceSprite` is a Sprite sibling, not a subclass, so this rebuilds when switching back from it.\r\n if (!(this.content instanceof Sprite)) this.setContent(new Sprite(texture));\r\n const sprite = this.content as Sprite;\r\n // Keep the Sprite and its layout rectangle stable when its image asset changes.\r\n if (sprite.texture !== texture) sprite.texture = texture;\r\n sprite.setSize(transform.width, transform.height);\r\n } else {\r\n if (!(this.content instanceof Graphics)) this.setContent(new Graphics());\r\n const graphics = (this.content as Graphics).clear().rect(0, 0, transform.width, transform.height);\r\n if (node.assetId === undefined) graphics.fill(node.tint ?? 0xffffff);\n else graphics.fill(0x4a5568).stroke({ width: 1, color: 0x94a3b8 });\n }\n this.content!.alpha = node.opacity ?? 1;\n if (this.content instanceof Sprite || this.content instanceof NineSliceSprite) this.content.tint = node.tint ?? 0xffffff;\n }\r\n\r\n /**\r\n * Editor-only live preview of border edits while dragging the canvas nine-slice gizmo; the\r\n * document is only written once, on drag release. A no-op without a `NineSliceSprite` content —\r\n * e.g. mid-drag right after the asset was cleared, before the next document sync catches up.\r\n */\r\n previewNineSlice(nineSlice: LayoutPadding): void {\n if (!(this.content instanceof NineSliceSprite)) return;\r\n this.content.leftWidth = nineSlice.left;\r\n this.content.topHeight = nineSlice.top;\r\n this.content.rightWidth = nineSlice.right;\r\n this.content.bottomHeight = nineSlice.bottom;\n }\n\n}\n\r\nexport class TextNodeView extends NodeView {\r\n /**\r\n * Строка, применённая локализацией поверх авторской. Она переживает `updateNodeView`: без неё\r\n * любая синхронизация документа возвращала бы fallback `node.text` вместо текущего перевода.\r\n */\r\n private localizedText?: string;\r\n /** Последний применённый прямоугольник и стиль — их же переиспользует инкрементальный `setText`. */\r\n private lastTransform?: UINode[\"transform\"];\r\n private lastStyle?: TextStyleDefinition;\r\n\r\n constructor(text: string, private readonly fonts?: ReadonlyMap<string, string>) {\r\n super();\r\n this.setContent(new Text({ text, style: { fontFamily: \"Arial\", fontSize: 24, fill: 0xffffff } }));\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"], profile: LayoutProfileId): void {\r\n if (node.type !== \"text\" || !(this.content instanceof Text)) return;\r\n const text = this.localizedText ?? node.text;\r\n if (this.content.text !== text) this.content.text = text;\r\n const style = resolveTextStyle(node, profile);\r\n this.lastTransform = transform;\r\n this.lastStyle = style;\r\n if (style === undefined) return;\r\n this.applyFittedStyle(this.content, node, style, transform);\r\n this.align();\r\n }\r\n\r\n /**\r\n * Applies the resolved style at the largest font size (down to `minFontSize`) that keeps the\r\n * rendered text inside `transform`, when `autoSize` is on — the same \"shrink, never grow past the\r\n * authored size\" contract as `BitmapTextNodeView.applyFittedStyle` / Unity legacy Text's Best Fit.\r\n * A binary search over candidate sizes rather than a closed-form scale, because word-wrapped text\r\n * re-flows at every size: a smaller font fits more words per line, so height doesn't shrink linearly\r\n * with font size the way unwrapped bounds would — the same reasoning `measureOverflow` follows.\r\n */\r\n private applyFittedStyle(text: Text, node: TextNode, style: TextStyleDefinition, transform: UINode[\"transform\"]): void {\r\n const baseStyle = { fontFamily: style.fontAssetId === undefined ? style.fontFamily : this.fonts?.get(style.fontAssetId) ?? style.fontFamily, fontWeight: style.fontWeight, fontStyle: style.fontStyle, fill: style.fill, align: style.align, wordWrap: style.wordWrap, breakWords: style.breakWords, wordWrapWidth: transform.width, lineHeight: style.lineHeight, letterSpacing: style.letterSpacing, stroke: style.stroke === undefined ? undefined : { color: style.stroke.color, width: style.stroke.width } };\r\n const fits = (fontSize: number): boolean => {\r\n text.style = { ...baseStyle, fontSize };\r\n // Headless loaders and schema tests have no browser canvas to measure against; they keep the\r\n // authored fontSize, same boundary `align()` already respects.\r\n if (typeof globalThis.document === \"undefined\") return true;\r\n const bounds = text.getLocalBounds();\r\n const tolerance = 0.5;\r\n return style.wordWrap\r\n ? bounds.height <= transform.height + tolerance\r\n : bounds.width <= transform.width + tolerance && bounds.height <= transform.height + tolerance;\r\n };\r\n // Always runs at least once, applying `baseStyle` at the authored size as a side effect — not\r\n // just the shrink-check's fast path. Written as `||` short-circuit, `fits(style.fontSize)` would\r\n // never execute while `autoSize` is off, leaving `text.style` frozen at whatever the constructor\r\n // set it to and silently dropping every later font/color/align/wrap edit (see the identical fix\r\n // in `BitmapTextNodeView.applyFittedStyle`).\r\n const fitsAtAuthoredSize = fits(style.fontSize);\r\n if (node.autoSize !== true || fitsAtAuthoredSize) return;\r\n const minFontSize = Math.min(node.minFontSize ?? 1, style.fontSize);\r\n if (!fits(minFontSize)) return; // Best effort: even the floor overflows, so it stays at the floor.\r\n let lo = minFontSize, hi = style.fontSize;\r\n for (let i = 0; i < 8; i++) {\r\n const mid = (lo + hi) / 2;\r\n if (fits(mid)) lo = mid; else hi = mid;\r\n }\r\n fits(lo); // Leaves `text.style` applied at the converged, fitting size.\r\n }\r\n\r\n /**\r\n * Инкрементальная смена строки: та же строка не делает работы вообще, новая — только переизмеряет\r\n * и выравнивает текст в текущем authored rectangle. `TextStyle` не пересоздаётся, а сам view\r\n * сохраняет identity, поэтому смена локали не трогает ни сцену, ни GPU-ресурсы стиля.\r\n */\r\n setText(text: string): void {\r\n if (!(this.content instanceof Text) || this.content.text === text) return;\r\n this.content.text = text;\r\n this.align();\r\n }\r\n\r\n /** `undefined` возвращает ноду к авторской строке при следующей синхронизации документа. */\r\n setLocalizedText(text: string | undefined): void {\r\n this.localizedText = text;\r\n if (text !== undefined) this.setText(text);\r\n }\r\n\r\n /**\r\n * Rasterizes the canvas-based `Text` at a higher pixel density than the renderer's own backing\r\n * resolution, so authoring-camera zoom doesn't magnify an already-rasterized bitmap past its\r\n * source resolution. `Application.resolution` (see `resolveCanvasResolution`) only matches the\r\n * *display's* pixel density — it knows nothing about the editor's independent camera zoom, which\r\n * can reach 8x (`MAX_ZOOM`). Without this, zooming in to inspect a text node (exactly what\r\n * `autoSize`/shrink-to-fit users do, since it converges to a smaller font) reads as soft/blurred\r\n * even on a display this app already renders crisply on. A no-op if unchanged: assigning\r\n * `.resolution` always re-rasterizes, so skip it when the caller (the authoring canvas, on every\r\n * camera-zoom tick) passes back the same value.\r\n */\r\n setContentResolution(resolution: number): void {\r\n if (!(this.content instanceof Text) || this.content.resolution === resolution) return;\r\n this.content.resolution = resolution;\r\n }\r\n\r\n /**\r\n * Вылезает ли фактически отрисованный текст за логический прямоугольник ноды.\r\n *\r\n * Меряется уже готовый `Text`, а не длина строки: перенос по словам, шрифт и обводка известны\r\n * только рендеру. Без `wordWrap` переполнение возможно по ширине, с ним — по высоте, потому что\r\n * перенос сам удерживает ширину в пределах `wordWrapWidth`. Диагностика transient: она ничего не\r\n * пишет ни в документ, ни в view.\r\n */\r\n measureOverflow(): boolean {\r\n const transform = this.lastTransform;\r\n if (!(this.content instanceof Text) || transform === undefined || typeof globalThis.document === \"undefined\") return false;\r\n const bounds = this.content.getLocalBounds();\r\n const tolerance = 0.5;\r\n return this.lastStyle?.wordWrap === true\r\n ? bounds.height > transform.height + tolerance\r\n : bounds.width > transform.width + tolerance || bounds.height > transform.height + tolerance;\r\n }\r\n\r\n private align(): void {\r\n const transform = this.lastTransform;\r\n const style = this.lastStyle;\r\n if (!(this.content instanceof Text) || transform === undefined || style === undefined) return;\r\n // Headless loaders and schema tests intentionally have no browser canvas. In that boundary\r\n // text still owns its authored rectangle; browser rendering keeps the precise measurement.\r\n const bounds = typeof globalThis.document === \"undefined\" ? { x: 0, y: 0, width: 0, height: 0 } : this.content.getLocalBounds();\r\n this.content.x = style.align === \"center\" ? (transform.width - bounds.width) / 2 - bounds.x : style.align === \"right\" ? transform.width - bounds.width - bounds.x : -bounds.x;\r\n this.content.y = style.verticalAlign === \"middle\" ? (transform.height - bounds.height) / 2 - bounds.y : style.verticalAlign === \"bottom\" ? transform.height - bounds.height - bounds.y : -bounds.y;\r\n }\r\n}\r\n\r\n/**\r\n * A bitmap font's rendered glyphs come from its texture, not an arbitrary system/TTF face, so unlike\r\n * `TextNodeView` there is no style-driven fallback: without a loaded font (asset deleted, still\r\n * loading, or failed to parse) this draws the same missing-asset placeholder `ImageNodeView` does.\r\n */\r\nexport class BitmapTextNodeView extends NodeView {\r\n private lastTransform?: UINode[\"transform\"];\r\n private lastAlign: \"left\" | \"center\" | \"right\" = \"left\";\r\n private lastVerticalAlign: \"top\" | \"middle\" | \"bottom\" = \"top\";\r\n\r\n constructor(private readonly fonts?: ReadonlyMap<string, string>) {\r\n super();\r\n this.setContent(new Graphics());\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"]): void {\r\n if (node.type !== \"bitmap-text\") return;\r\n this.lastTransform = transform;\r\n this.lastAlign = node.align;\r\n this.lastVerticalAlign = node.verticalAlign;\r\n const family = this.fonts?.get(node.assetId);\r\n if (family === undefined) {\r\n if (!(this.content instanceof Graphics)) this.setContent(new Graphics());\r\n (this.content as Graphics).clear().rect(0, 0, transform.width, transform.height).fill(0x4a5568).stroke({ width: 1, color: 0x94a3b8 });\r\n return;\r\n }\r\n if (!(this.content instanceof BitmapText)) this.setContent(new BitmapText({ text: node.text, style: { fontFamily: family, fontSize: node.fontSize, fill: node.fill } }));\r\n const bitmapText = this.content as BitmapText;\r\n if (bitmapText.text !== node.text) bitmapText.text = node.text;\r\n this.applyFittedStyle(bitmapText, node, family, transform);\r\n this.align();\r\n }\r\n\r\n /**\r\n * Applies the node's style at the largest font size (down to `minFontSize`) that keeps the text\r\n * inside `transform`, when `autoSize` is on — the same \"shrink, never grow past the authored size\"\r\n * contract as Unity legacy Text's Best Fit. A binary search over candidate sizes rather than a\r\n * closed-form scale, because word-wrapped text re-flows at every size: a smaller font can fit more\r\n * words per line, so height doesn't shrink linearly with font size the way unwrapped bounds would.\r\n */\r\n private applyFittedStyle(bitmapText: BitmapText, node: BitmapTextNode, family: string, transform: UINode[\"transform\"]): void {\r\n const baseStyle = { fontFamily: family, fill: node.fill, align: node.align, letterSpacing: node.letterSpacing, wordWrap: node.wordWrap, wordWrapWidth: transform.width };\r\n const fits = (fontSize: number): boolean => {\r\n bitmapText.style = { ...baseStyle, fontSize };\r\n // Headless loaders and schema tests have no browser canvas to measure against; they keep the\r\n // authored fontSize, same boundary `align()` already respects.\r\n if (typeof globalThis.document === \"undefined\") return true;\r\n const bounds = bitmapText.getLocalBounds();\r\n const tolerance = 0.5;\r\n return node.wordWrap\r\n ? bounds.height <= transform.height + tolerance\r\n : bounds.width <= transform.width + tolerance && bounds.height <= transform.height + tolerance;\r\n };\r\n // Always runs at least once, applying `baseStyle` at the authored size as a side effect — not\r\n // just the shrink-check's fast path. Written as `||` short-circuit, `fits(node.fontSize)` would\r\n // never execute while `autoSize` is off, leaving `bitmapText.style` frozen at whatever the\r\n // constructor set it to and silently dropping every later fill/align/letterSpacing/wordWrap edit.\r\n const fitsAtAuthoredSize = fits(node.fontSize);\r\n if (node.autoSize !== true || fitsAtAuthoredSize) return;\r\n const minFontSize = Math.min(node.minFontSize ?? 1, node.fontSize);\r\n if (!fits(minFontSize)) return; // Best effort: even the floor overflows, so it stays at the floor.\r\n let lo = minFontSize, hi = node.fontSize;\r\n for (let i = 0; i < 8; i++) {\r\n const mid = (lo + hi) / 2;\r\n if (fits(mid)) lo = mid; else hi = mid;\r\n }\r\n fits(lo); // Leaves `bitmapText.style` applied at the converged, fitting size.\r\n }\r\n\r\n /**\r\n * Positions via PixiJS's own `anchor`, not a manual `getLocalBounds()` computation like\r\n * `TextNodeView.align()` uses: `BitmapText.updateBounds()` reports a coarse line-metrics box\r\n * (built from the font's `lineHeight`/`baseLineOffset`), not the tight pixel bounds a canvas\r\n * `Text` or `Sprite` reports. Its own glyphs are drawn with an additional baseline-derived offset\r\n * that box doesn't account for, so computing `-bounds.y`-style positions from it lands text\r\n * slightly (but consistently, for every vertical setting) off — `anchor` is the one code path\r\n * PixiJS keeps in sync with how it actually renders the glyphs.\r\n */\r\n private align(): void {\r\n const transform = this.lastTransform;\r\n if (!(this.content instanceof BitmapText) || transform === undefined) return;\r\n const anchorX = this.lastAlign === \"center\" ? 0.5 : this.lastAlign === \"right\" ? 1 : 0;\r\n const anchorY = this.lastVerticalAlign === \"middle\" ? 0.5 : this.lastVerticalAlign === \"bottom\" ? 1 : 0;\r\n this.content.anchor.set(anchorX, anchorY);\r\n this.content.x = anchorX * transform.width;\r\n this.content.y = anchorY * transform.height;\r\n }\r\n}\r\n\r\n/**\r\n * Содержимое инстанса приходит обычными детьми из общего резолвера иерархии. Собственный контент\r\n * нужен только как заметная заглушка, когда определение пресета отсутствует в документе.\r\n */\r\nexport class PrefabInstanceNodeView extends NodeView {\r\n constructor(resolved: boolean) {\r\n super();\r\n if (!resolved) this.setContent(new Graphics());\r\n }\r\n\r\n protected syncContent(_node: UINode, transform: UINode[\"transform\"]): void {\r\n if (this.content instanceof Graphics) this.content.clear().rect(0, 0, transform.width, transform.height).fill(0xff00ff);\r\n }\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"createNodeView.d.ts","sourceRoot":"","sources":["../../src/views/createNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,KAAK,wBAAwB,EAAE,KAAK,mBAAmB,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACtJ,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAa,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAK1D,OAAO,EAAE,QAAQ,EAAE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAOpE;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,oBAAoB,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,EAAE,KAAK,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,EAAE,wBAAwB,EAAE,mBAAmB,CAAC,EAAE,mBAAmB,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,QAAQ,CAqC5a;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA8D1D"}
1
+ {"version":3,"file":"createNodeView.d.ts","sourceRoot":"","sources":["../../src/views/createNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,KAAK,wBAAwB,EAAE,KAAK,mBAAmB,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACtJ,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAa,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAK1D,OAAO,EAAE,QAAQ,EAAE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AASpE;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,oBAAoB,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,EAAE,KAAK,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,EAAE,wBAAwB,EAAE,mBAAmB,CAAC,EAAE,mBAAmB,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,QAAQ,CAyC5a;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAiE1D"}
@@ -3,6 +3,8 @@ import { ButtonNodeView } from "./ButtonNodeView.js";
3
3
  import { CheckboxNodeView } from "./CheckboxNodeView.js";
4
4
  import { BitmapTextNodeView, ContainerNodeView, ImageNodeView, LayoutGroupNodeView, MaskNodeView, PrefabInstanceNodeView, TextNodeView } from "./basic.js";
5
5
  import { InputNodeView } from "./InputNodeView.js";
6
+ import { PageGroupNodeView } from "./PageGroupNodeView.js";
7
+ import { PaginationNodeView } from "./PaginationNodeView.js";
6
8
  import { ScrollViewNodeView } from "./ScrollViewNodeView.js";
7
9
  import { SpineNodeView } from "./SpineNodeView.js";
8
10
  import { StagedButtonNodeView } from "./StagedButtonNodeView.js";
@@ -24,6 +26,8 @@ export function createNodeView(node, interaction, textures, spines, hasPrefab, f
24
26
  return new LayoutGroupNodeView(textures);
25
27
  case "scroll-view":
26
28
  return new ScrollViewNodeView(node, textures, interaction);
29
+ case "page-group":
30
+ return new PageGroupNodeView(node, textures);
27
31
  case "image":
28
32
  return new ImageNodeView(node.assetId, textures, node.nineSlice);
29
33
  case "text":
@@ -44,6 +48,8 @@ export function createNodeView(node, interaction, textures, spines, hasPrefab, f
44
48
  return new SliderNodeView(node, textures, interaction, fonts);
45
49
  case "progress-bar":
46
50
  return new ProgressBarNodeView(node, textures);
51
+ case "pagination":
52
+ return new PaginationNodeView(node, textures, interaction, fonts);
47
53
  case "particle-emitter":
48
54
  return effect === undefined ? new ContainerNodeView() : new ParticleEmitterNodeView(effect, textures);
49
55
  case "prefab-instance":
@@ -92,6 +98,7 @@ export function collectNodeAssetIds(node) {
92
98
  return backgroundAssetId === undefined ? [] : [backgroundAssetId];
93
99
  }
94
100
  case "scroll-view":
101
+ case "page-group":
95
102
  return [];
96
103
  case "text":
97
104
  return [...new Set([
@@ -117,6 +124,8 @@ export function collectNodeAssetIds(node) {
117
124
  }
118
125
  case "progress-bar":
119
126
  return [node.backgroundAssetId, node.fillAssetId];
127
+ case "pagination":
128
+ return [node.activeAssetId, node.inactiveAssetId, node.numberStyle?.fontAssetId, node.numberActiveBackgroundAssetId].filter((assetId) => assetId !== undefined);
120
129
  case "particle-emitter":
121
130
  return [];
122
131
  }
@@ -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 type { Sound } from \"@pixi/sound\";\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, PrefabInstanceNodeView, TextNodeView } from \"./basic.js\";\r\nimport { InputNodeView } from \"./InputNodeView.js\";\r\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.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>, sounds?: ReadonlyMap<string, Sound>, 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 \"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 \"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, sounds);\r\n case \"staged-button\":\r\n return new StagedButtonNodeView(node, textures, interaction, sounds);\r\n case \"checkbox\":\r\n return new CheckboxNodeView(node, textures, interaction, sounds);\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 \"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 \"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 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 [node.assetId];\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 \"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 type { Sound } from \"@pixi/sound\";\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, PrefabInstanceNodeView, TextNodeView } from \"./basic.js\";\r\nimport { InputNodeView } from \"./InputNodeView.js\";\r\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.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>, sounds?: ReadonlyMap<string, Sound>, 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 \"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 \"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, sounds);\r\n case \"staged-button\":\r\n return new StagedButtonNodeView(node, textures, interaction, sounds);\r\n case \"checkbox\":\r\n return new CheckboxNodeView(node, textures, interaction, sounds);\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 \"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 [node.assetId];\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, node.numberActiveBackgroundAssetId].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.5.1",
3
+ "version": "0.6.1",
4
4
  "description": "PixiJS runtime that renders Pixi UI Editor scene documents in a game.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -12,7 +12,9 @@
12
12
  "access": "public"
13
13
  },
14
14
  "files": [
15
- "dist"
15
+ "dist",
16
+ "!dist/**/*.test.*",
17
+ "!dist/test.setup.*"
16
18
  ],
17
19
  "exports": {
18
20
  ".": {
@@ -28,7 +30,7 @@
28
30
  "pixi.js": "^8.19.0",
29
31
  "typed-signals": "^2.5.0",
30
32
  "yoga-layout": "^3.2.1",
31
- "@pixi-ui-editor/schema": "0.5.1"
33
+ "@pixi-ui-editor/schema": "0.6.1"
32
34
  },
33
35
  "scripts": {
34
36
  "build": "tsc -p tsconfig.json",
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=spine.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"spine.test.d.ts","sourceRoot":"","sources":["../../src/assets/spine.test.ts"],"names":[],"mappings":""}
@@ -1,42 +0,0 @@
1
- import { readFileSync } from "node:fs";
2
- import { describe, expect, it } from "vitest";
3
- import { AtlasAttachmentLoader, MeshAttachment, PathConstraintData, SkeletonJson, TextureAtlas } from "@esotericsoftware/spine-pixi-v8";
4
- import { Texture } from "pixi.js";
5
- import { assignAtlasPageTextures } from "./spine.js";
6
- const fixtureUrl = (name) => new URL(`./fixtures/${name}`, import.meta.url);
7
- const readFixture = (name) => readFileSync(fixtureUrl(name), "utf8");
8
- /**
9
- * Guards the Spine runtime major against the export format the project's assets actually use.
10
- *
11
- * Spine 4.3 renamed the linked-mesh `parent` field to `source` and merged the per-type `ik`/
12
- * `transform`/`path` constraint arrays into a single `constraints` array. Reading a 4.0-4.2 export
13
- * with a 4.3 runtime therefore misses the linked-mesh branch and dereferences the absent `uvs`,
14
- * which surfaced in the editor as "Cannot read properties of undefined (reading 'length')".
15
- * Skeletons without linked meshes or path constraints parse either way, so only some assets broke.
16
- */
17
- describe("Spine skeleton format", () => {
18
- function parseFixture() {
19
- const atlas = new TextureAtlas(readFixture("legacy-skeleton.atlas"));
20
- assignAtlasPageTextures(atlas, new Map([["legacy-skeleton.png", Texture.WHITE]]));
21
- return new SkeletonJson(new AtlasAttachmentLoader(atlas)).readSkeletonData(readFixture("legacy-skeleton.json"));
22
- }
23
- it("reads a Spine 4.1 export with a linked mesh and a path constraint", () => {
24
- const skeletonData = parseFixture();
25
- expect(skeletonData.bones.map((bone) => bone.name)).toEqual(["root", "spine"]);
26
- expect(skeletonData.findAnimation("idle")).not.toBeNull();
27
- });
28
- it("resolves a linked mesh declared through the pre-4.3 'parent' field", () => {
29
- const source = parseFixture().findSkin("default")?.getAttachment(0, "body");
30
- const linked = parseFixture().findSkin("default")?.getAttachment(0, "body-flash");
31
- // A linked mesh carries no geometry of its own; it inherits the source mesh's triangles and UVs.
32
- expect(linked).toBeInstanceOf(MeshAttachment);
33
- expect(Array.from(linked.triangles)).toEqual(Array.from(source.triangles));
34
- expect(linked.worldVerticesLength).toBe(source.worldVerticesLength);
35
- });
36
- it("keeps path constraints and their animation timelines", () => {
37
- const skeletonData = parseFixture();
38
- expect(skeletonData.findPathConstraint("trail")).toBeInstanceOf(PathConstraintData);
39
- expect(skeletonData.findAnimation("idle")?.timelines.length).toBe(3);
40
- });
41
- });
42
- //# sourceMappingURL=spine.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"spine.test.js","sourceRoot":"","sources":["../../src/assets/spine.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,kBAAkB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACxI,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,cAAc,IAAI,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACpF,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;AAE7E;;;;;;;;GAQG;AACH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,SAAS,YAAY;QACnB,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,WAAW,CAAC,uBAAuB,CAAC,CAAC,CAAC;QACrE,uBAAuB,CAAC,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,qBAAqB,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAClF,OAAO,IAAI,YAAY,CAAC,IAAI,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,WAAW,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAClH,CAAC;IAED,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,YAAY,GAAG,YAAY,EAAE,CAAC;QAEpC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QAC/E,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,MAAM,CAAmB,CAAC;QAC9F,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,YAAY,CAAmB,CAAC;QAEpG,iGAAiG;QACjG,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QAC3E,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,YAAY,GAAG,YAAY,EAAE,CAAC;QAEpC,MAAM,CAAC,YAAY,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC;QACpF,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { describe, expect, it } from \"vitest\";\nimport { AtlasAttachmentLoader, MeshAttachment, PathConstraintData, SkeletonJson, TextureAtlas } from \"@esotericsoftware/spine-pixi-v8\";\nimport { Texture } from \"pixi.js\";\nimport { assignAtlasPageTextures } from \"./spine.js\";\n\nconst fixtureUrl = (name: string) => new URL(`./fixtures/${name}`, import.meta.url);\nconst readFixture = (name: string) => readFileSync(fixtureUrl(name), \"utf8\");\n\n/**\n * Guards the Spine runtime major against the export format the project's assets actually use.\n *\n * Spine 4.3 renamed the linked-mesh `parent` field to `source` and merged the per-type `ik`/\n * `transform`/`path` constraint arrays into a single `constraints` array. Reading a 4.0-4.2 export\n * with a 4.3 runtime therefore misses the linked-mesh branch and dereferences the absent `uvs`,\n * which surfaced in the editor as \"Cannot read properties of undefined (reading 'length')\".\n * Skeletons without linked meshes or path constraints parse either way, so only some assets broke.\n */\ndescribe(\"Spine skeleton format\", () => {\n function parseFixture() {\n const atlas = new TextureAtlas(readFixture(\"legacy-skeleton.atlas\"));\n assignAtlasPageTextures(atlas, new Map([[\"legacy-skeleton.png\", Texture.WHITE]]));\n return new SkeletonJson(new AtlasAttachmentLoader(atlas)).readSkeletonData(readFixture(\"legacy-skeleton.json\"));\n }\n\n it(\"reads a Spine 4.1 export with a linked mesh and a path constraint\", () => {\n const skeletonData = parseFixture();\n\n expect(skeletonData.bones.map((bone) => bone.name)).toEqual([\"root\", \"spine\"]);\n expect(skeletonData.findAnimation(\"idle\")).not.toBeNull();\n });\n\n it(\"resolves a linked mesh declared through the pre-4.3 'parent' field\", () => {\n const source = parseFixture().findSkin(\"default\")?.getAttachment(0, \"body\") as MeshAttachment;\n const linked = parseFixture().findSkin(\"default\")?.getAttachment(0, \"body-flash\") as MeshAttachment;\n\n // A linked mesh carries no geometry of its own; it inherits the source mesh's triangles and UVs.\n expect(linked).toBeInstanceOf(MeshAttachment);\n expect(Array.from(linked.triangles)).toEqual(Array.from(source.triangles));\n expect(linked.worldVerticesLength).toBe(source.worldVerticesLength);\n });\n\n it(\"keeps path constraints and their animation timelines\", () => {\n const skeletonData = parseFixture();\n\n expect(skeletonData.findPathConstraint(\"trail\")).toBeInstanceOf(PathConstraintData);\n expect(skeletonData.findAnimation(\"idle\")?.timelines.length).toBe(3);\n });\n});\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=index.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}