@pixi-ui-editor/runtime-pixi 0.11.0 → 0.12.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.
@@ -1,10 +1,26 @@
1
1
  import "@pixi/layout";
2
- import { type LayoutGroupNode, type LayoutProfileId, type UINode } from "@pixi-ui-editor/schema";
2
+ import { type GridLayoutSettings, type LayoutGroupNode, type LayoutProfileId, type UINode } from "@pixi-ui-editor/schema";
3
3
  import { Container } from "pixi.js";
4
4
  import { type LayoutSize } from "./layout.js";
5
5
  import { NodeView } from "./views/NodeView.js";
6
6
  /** Importing @pixi/layout installs its renderer extension. Kept as a shared explicit contract for every host. */
7
7
  export declare function initializePixiLayout(): void;
8
+ /**
9
+ * Направление заполнения сетки, выведенное из startCorner/startAxis/constraint. Единственный
10
+ * источник правды: рантайм задаёт по нему Yoga-флексбокс, а редактор считает по нему же рамки
11
+ * выделения, поэтому расходиться этим двум расчётам негде.
12
+ */
13
+ export type GridFlow = {
14
+ /** Строки являются линиями переноса (иначе линии — это колонки). */
15
+ readonly fillsByRow: boolean;
16
+ /** Главная ось (порядок внутри линии) идёт справа налево / снизу вверх. */
17
+ readonly mainReversed: boolean;
18
+ /** Поперечная ось (порядок линий) идёт снизу вверх / справа налево. */
19
+ readonly crossReversed: boolean;
20
+ /** Фиксированный constraint переносит линии явными разрывами, а не переполнением. */
21
+ readonly usesLineBreaks: boolean;
22
+ };
23
+ export declare function resolveGridFlow(grid: GridLayoutSettings): GridFlow;
8
24
  /** Applies one declarative document group to Pixi Layout; no computed Yoga data crosses the document boundary. */
9
25
  export declare function applyLayoutGroup(view: Container, node: LayoutGroupNode, profile: LayoutProfileId, parentSize?: LayoutSize, managedSize?: LayoutSize): void;
10
26
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"layoutGroups.d.ts","sourceRoot":"","sources":["../src/layoutGroups.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,EAAmE,KAAK,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAClK,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAqD,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAEjG,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,iHAAiH;AACjH,wBAAgB,oBAAoB,IAAI,IAAI,CAAkE;AAe9G,kHAAkH;AAClH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,UAAU,GAAG,IAAI,CAkC1J;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;IAKpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ;IAAE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;IAJ1E,OAAO,CAAC,IAAI,CAAC,CAAS;IACtB,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,YAAY,CAAuC;IAE3D,YAAqB,QAAQ,EAAE,QAAQ,EAAmB,eAAe,CAAC,GAAE,MAAM,IAAI,aAAA,EAIrF;IAED,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,UAAU,GAAG,IAAI,CAM3E;IAED,OAAO,CAAC,iBAAiB;CAU1B;AAED,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CA+BhI;AAED,mIAAmI;AACnI,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,EAAE;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC,EAAE,OAAO,EAAE,eAAe,GAAG,SAAS,GAAG,SAAS,CAQ9I;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAEpF"}
1
+ {"version":3,"file":"layoutGroups.d.ts","sourceRoot":"","sources":["../src/layoutGroups.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,EAA6C,KAAK,kBAAkB,EAAwB,KAAK,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC3L,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAqD,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAEjG,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,iHAAiH;AACjH,wBAAgB,oBAAoB,IAAI,IAAI,CAAkE;AAU9G;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,oEAAoE;IACpE,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,uEAAuE;IACvE,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,qFAAqF;IACrF,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC,CAAC;AAEF,wBAAgB,eAAe,CAAC,IAAI,EAAE,kBAAkB,GAAG,QAAQ,CAUlE;AAOD,kHAAkH;AAClH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,UAAU,GAAG,IAAI,CAqC1J;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;IAKpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ;IAAE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;IAJ1E,OAAO,CAAC,IAAI,CAAC,CAAS;IACtB,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,YAAY,CAAuC;IAE3D,YAAqB,QAAQ,EAAE,QAAQ,EAAmB,eAAe,CAAC,GAAE,MAAM,IAAI,aAAA,EAIrF;IAED,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,UAAU,GAAG,IAAI,CAM3E;IAED,OAAO,CAAC,iBAAiB;CAU1B;AAED,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CA+BhI;AAED,mIAAmI;AACnI,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,EAAE;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC,EAAE,OAAO,EAAE,eAAe,GAAG,SAAS,GAAG,SAAS,CAS9I;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAEpF"}
@@ -12,6 +12,17 @@ function alignmentParts(alignment) {
12
12
  vertical: vertical === "upper" ? "flex-start" : vertical === "lower" ? "flex-end" : "center",
13
13
  };
14
14
  }
15
+ export function resolveGridFlow(grid) {
16
+ const reverseX = grid.startCorner.endsWith("right");
17
+ const reverseY = grid.startCorner.startsWith("lower");
18
+ const fillsByRow = grid.constraint === "fixed-column-count" || (grid.constraint === "flexible" && grid.startAxis === "horizontal");
19
+ return {
20
+ fillsByRow,
21
+ mainReversed: fillsByRow ? reverseX : reverseY,
22
+ crossReversed: fillsByRow ? reverseY : reverseX,
23
+ usesLineBreaks: grid.constraint !== "flexible" && grid.constraintCount !== undefined,
24
+ };
25
+ }
15
26
  function layoutSize(node, profile, parentSize) {
16
27
  const transform = resolveAnchoredTransform(resolveProfileTransform(node, profile).transform, parentSize);
17
28
  return { width: transform.width, height: transform.height };
@@ -36,19 +47,22 @@ export function applyLayoutGroup(view, node, profile, parentSize, managedSize) {
36
47
  return;
37
48
  }
38
49
  const grid = settings;
39
- const reverseX = grid.startCorner.endsWith("right");
40
- const reverseY = grid.startCorner.startsWith("lower");
41
- const fillsByRow = grid.constraint === "fixed-column-count" || (grid.constraint === "flexible" && grid.startAxis === "horizontal");
50
+ const flow = resolveGridFlow(grid);
42
51
  const target = view instanceof LayoutGroupNodeView ? view.layoutTarget : view;
43
52
  const alignment = alignmentParts(grid.childAlignment);
53
+ // justify-content при flex-wrap выравнивает КАЖДУЮ линию отдельно, поэтому неполная последняя
54
+ // строка центрируется сама по себе. Это и есть per-row alignment, отдельного поля не нужно.
44
55
  target.layout = {
45
56
  ...common,
46
- justifyContent: fillsByRow ? alignment.horizontal : alignment.vertical,
47
- alignItems: fillsByRow ? alignment.vertical : alignment.horizontal,
48
- alignContent: fillsByRow ? alignment.vertical : alignment.horizontal,
49
- flexDirection: fillsByRow ? (reverseX ? "row-reverse" : "row") : (reverseY ? "column-reverse" : "column"),
50
- flexWrap: reverseY && fillsByRow ? "wrap-reverse" : "wrap",
51
- columnGap: grid.spacingX, rowGap: grid.spacingY,
57
+ justifyContent: flow.fillsByRow ? alignment.horizontal : alignment.vertical,
58
+ alignItems: flow.fillsByRow ? alignment.vertical : alignment.horizontal,
59
+ alignContent: flow.fillsByRow ? alignment.vertical : alignment.horizontal,
60
+ flexDirection: flow.fillsByRow ? (flow.mainReversed ? "row-reverse" : "row") : (flow.mainReversed ? "column-reverse" : "column"),
61
+ flexWrap: flow.crossReversed ? "wrap-reverse" : "wrap",
62
+ // Разрыв строки занимает собственную линию, поэтому поперечный зазор пришёл бы дважды: до
63
+ // разрыва и после него. Зазор перенесён в размер самого разрыва, а gutter обнулён.
64
+ columnGap: flow.usesLineBreaks && !flow.fillsByRow ? 0 : grid.spacingX,
65
+ rowGap: flow.usesLineBreaks && flow.fillsByRow ? 0 : grid.spacingY,
52
66
  paddingLeft: grid.padding.left, paddingRight: grid.padding.right, paddingTop: grid.padding.top, paddingBottom: grid.padding.bottom,
53
67
  };
54
68
  }
@@ -128,9 +142,10 @@ export function createGridLineBreak(parent, profile) {
128
142
  if (grid.constraint === "flexible" || grid.constraintCount === undefined)
129
143
  return undefined;
130
144
  const lineBreak = new Container({ label: "__layout-grid-line-break__" });
145
+ // Поперечный зазор между линиями живёт здесь, а не в rowGap/columnGap группы: см. applyLayoutGroup.
131
146
  lineBreak.layout = (grid.constraint === "fixed-column-count"
132
- ? { flexBasis: "100%", width: "100%", height: 0 }
133
- : { flexBasis: "100%", height: "100%", width: 0 });
147
+ ? { flexBasis: "100%", width: "100%", height: grid.spacingY, flexShrink: 0 }
148
+ : { flexBasis: "100%", height: "100%", width: grid.spacingX, flexShrink: 0 });
134
149
  return lineBreak;
135
150
  }
136
151
  export function isLayoutManagedChild(node, nodes) {
@@ -1 +1 @@
1
- {"version":3,"file":"layoutGroups.js","sourceRoot":"","sources":["../src/layoutGroups.ts"],"names":[],"mappings":"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","sourcesContent":["import \"@pixi/layout\";\r\nimport { isLayoutGroup, resolveLayoutGroupSettings, type LayoutAlignment, type LayoutGroupNode, type LayoutProfileId, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { Container } from \"pixi.js\";\r\nimport { resolveAnchoredTransform, resolveProfileTransform, type LayoutSize } from \"./layout.js\";\r\nimport { LayoutGroupNodeView } from \"./views/basic.js\";\r\nimport { NodeView } from \"./views/NodeView.js\";\r\n\r\n/** Importing @pixi/layout installs its renderer extension. Kept as a shared explicit contract for every host. */\r\nexport function initializePixiLayout(): void { /* @pixi/layout is installed by this module's side effect. */ }\r\n\r\nfunction alignmentParts(alignment: LayoutAlignment) {\r\n const [vertical, horizontal] = alignment.split(\"-\") as [\"upper\" | \"middle\" | \"lower\", \"left\" | \"center\" | \"right\"];\r\n return {\r\n horizontal: horizontal === \"left\" ? \"flex-start\" : horizontal === \"right\" ? \"flex-end\" : \"center\",\r\n vertical: vertical === \"upper\" ? \"flex-start\" : vertical === \"lower\" ? \"flex-end\" : \"center\",\r\n };\r\n}\r\n\r\nfunction layoutSize(node: UINode, profile: LayoutProfileId, parentSize?: LayoutSize): LayoutSize {\n const transform = resolveAnchoredTransform(resolveProfileTransform(node, profile).transform, parentSize);\n return { width: transform.width, height: transform.height };\n}\n\n/** Applies one declarative document group to Pixi Layout; no computed Yoga data crosses the document boundary. */\nexport function applyLayoutGroup(view: Container, node: LayoutGroupNode, profile: LayoutProfileId, parentSize?: LayoutSize, managedSize?: LayoutSize): void {\n const settings = resolveLayoutGroupSettings(node, profile) as LayoutGroupNode[\"layoutGroup\"][\"base\"];\n const size = managedSize ?? layoutSize(node, profile, parentSize);\n const common = { width: size.width, height: size.height, display: \"flex\" as const };\r\n if (node.type === \"horizontal-layout\" || node.type === \"vertical-layout\") {\r\n const linear = settings as Extract<LayoutGroupNode, { type: \"horizontal-layout\" | \"vertical-layout\" }> [\"layoutGroup\"][\"base\"];\r\n const target = view instanceof LayoutGroupNodeView ? view.layoutTarget : view;\r\n const alignment = alignmentParts(linear.childAlignment);\r\n target.layout = {\r\n ...common,\r\n justifyContent: node.type === \"horizontal-layout\" ? alignment.horizontal : alignment.vertical,\r\n alignItems: node.type === \"horizontal-layout\" ? alignment.vertical : alignment.horizontal,\r\n flexDirection: node.type === \"horizontal-layout\" ? (linear.reverseOrder ? \"row-reverse\" : \"row\") : (linear.reverseOrder ? \"column-reverse\" : \"column\"),\r\n gap: linear.spacing,\r\n paddingLeft: linear.padding.left, paddingRight: linear.padding.right, paddingTop: linear.padding.top, paddingBottom: linear.padding.bottom,\r\n } as never;\r\n return;\r\n }\r\n const grid = settings as Extract<LayoutGroupNode, { type: \"grid-layout\" }> [\"layoutGroup\"][\"base\"];\r\n const reverseX = grid.startCorner.endsWith(\"right\");\r\n const reverseY = grid.startCorner.startsWith(\"lower\");\r\n const fillsByRow = grid.constraint === \"fixed-column-count\" || (grid.constraint === \"flexible\" && grid.startAxis === \"horizontal\");\r\n const target = view instanceof LayoutGroupNodeView ? view.layoutTarget : view;\r\n const alignment = alignmentParts(grid.childAlignment);\r\n target.layout = {\r\n ...common,\r\n justifyContent: fillsByRow ? alignment.horizontal : alignment.vertical,\r\n alignItems: fillsByRow ? alignment.vertical : alignment.horizontal,\r\n alignContent: fillsByRow ? alignment.vertical : alignment.horizontal,\r\n flexDirection: fillsByRow ? (reverseX ? \"row-reverse\" : \"row\") : (reverseY ? \"column-reverse\" : \"column\"),\r\n flexWrap: reverseY && fillsByRow ? \"wrap-reverse\" : \"wrap\",\r\n columnGap: grid.spacingX, rowGap: grid.spacingY,\n paddingLeft: grid.padding.left, paddingRight: grid.padding.right, paddingTop: grid.padding.top, paddingBottom: grid.padding.bottom,\r\n } as never;\r\n}\r\n\r\n/**\r\n * Runtime-only Yoga owner for one direct child. The wrapper receives Yoga coordinates while the\r\n * serializable NodeView keeps the shared pivot/rotation/scale/content/hit-test contract.\r\n */\r\nexport class LayoutItemContainer extends Container {\r\n private node?: UINode;\r\n private profile: LayoutProfileId = \"desktop\";\r\n private fallbackSize: LayoutSize = { width: 0, height: 0 };\r\n\r\n constructor(readonly nodeView: NodeView, private readonly onLayoutChanged?: () => void) {\r\n super();\r\n super.addChild(nodeView);\r\n this.onLayout = () => this.applyComputedSize();\r\n }\r\n\r\n sync(node: UINode, profile: LayoutProfileId, fallbackSize: LayoutSize): void {\r\n this.node = node;\r\n this.profile = profile;\r\n this.fallbackSize = fallbackSize;\r\n this.visible = resolveProfileTransform(node, profile).visible;\r\n this.applyComputedSize();\r\n }\r\n\r\n private applyComputedSize(): void {\r\n if (this.node === undefined) return;\r\n const computed = this.layout?.computedLayout;\r\n const size = computed === undefined || computed.width <= 0 || computed.height <= 0\r\n ? this.fallbackSize\r\n : { width: computed.width, height: computed.height };\r\n if (isLayoutGroup(this.node)) applyLayoutGroup(this.nodeView, this.node, this.profile, undefined, size);\n this.nodeView.updateManaged(this.node, this.profile, size);\r\n this.onLayoutChanged?.();\r\n }\r\n}\r\n\r\n/** Marks a direct child's technical wrapper as layout-managed. */\r\nexport function applyLayoutItem(view: LayoutItemContainer, node: UINode, parent: LayoutGroupNode, profile: LayoutProfileId): void {\r\n // Anchors belong to authored positioning and are deliberately ignored while a parent layout owns\r\n // the rectangle. Width/height remain the child's logical intrinsic size, never Pixi content bounds.\r\n const transform = resolveProfileTransform(node, profile).transform;\r\n const own = { width: transform.width, height: transform.height };\r\n const item = node.layoutItem;\r\n const settings = resolveLayoutGroupSettings(parent, profile);\r\n const base = { position: \"relative\" as const, flexGrow: item?.flexGrow ?? 0, flexShrink: item?.flexShrink ?? 0, flexBasis: item?.flexBasis, alignSelf: item?.alignSelf };\r\n view.sync(node, profile, own);\r\n if (parent.type === \"grid-layout\") {\n const grid = settings as Extract<LayoutGroupNode, { type: \"grid-layout\" }> [\"layoutGroup\"][\"base\"];\n view.layout = { ...base, width: grid.cellWidth, height: grid.cellHeight } as never;\n return;\n }\n const linear = settings as Extract<LayoutGroupNode, { type: \"horizontal-layout\" | \"vertical-layout\" }> [\"layoutGroup\"][\"base\"];\r\n const horizontal = parent.type === \"horizontal-layout\";\r\n const expandsMain = horizontal\r\n ? linear.controlChildWidth && linear.forceExpandWidth\r\n : linear.controlChildHeight && linear.forceExpandHeight;\r\n const expandsCross = horizontal\r\n ? linear.controlChildHeight && linear.forceExpandHeight\r\n : linear.controlChildWidth && linear.forceExpandWidth;\r\n view.layout = {\r\n ...base,\r\n // The schema has no separate min/preferred size yet, so the logical authored rect is the safe\r\n // intrinsic fallback for both control modes. Force-expand may then replace the relevant axis.\r\n width: expandsCross && !horizontal ? undefined : own.width,\r\n height: expandsCross && horizontal ? undefined : own.height,\r\n ...(expandsMain ? { flexGrow: Math.max(1, item?.flexGrow ?? 0) } : {}),\r\n ...(expandsCross ? { alignSelf: item?.alignSelf ?? \"stretch\" } : {}),\r\n } as never;\r\n}\r\n\r\n/** A zero-visual Yoga flex item. Fixed Unity grid constraints need explicit line breaks; this is still solved entirely by Yoga. */\r\nexport function createGridLineBreak(parent: Extract<LayoutGroupNode, { type: \"grid-layout\" }>, profile: LayoutProfileId): Container | undefined {\r\n const grid = resolveLayoutGroupSettings(parent, profile) as Extract<LayoutGroupNode, { type: \"grid-layout\" }> [\"layoutGroup\"][\"base\"];\r\n if (grid.constraint === \"flexible\" || grid.constraintCount === undefined) return undefined;\r\n const lineBreak = new Container({ label: \"__layout-grid-line-break__\" });\r\n lineBreak.layout = (grid.constraint === \"fixed-column-count\"\r\n ? { flexBasis: \"100%\", width: \"100%\", height: 0 }\r\n : { flexBasis: \"100%\", height: \"100%\", width: 0 }) as never;\r\n return lineBreak;\r\n}\r\n\r\nexport function isLayoutManagedChild(node: UINode, nodes: readonly UINode[]): boolean {\r\n return node.parentId !== null && isLayoutGroup(nodes.find((candidate) => candidate.id === node.parentId) ?? node) && nodes.some((candidate) => candidate.id === node.parentId && isLayoutGroup(candidate));\r\n}\r\n"]}
1
+ {"version":3,"file":"layoutGroups.js","sourceRoot":"","sources":["../src/layoutGroups.ts"],"names":[],"mappings":"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","sourcesContent":["import \"@pixi/layout\";\r\nimport { isLayoutGroup, resolveLayoutGroupSettings, type GridLayoutSettings, type LayoutAlignment, type LayoutGroupNode, type LayoutProfileId, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { Container } from \"pixi.js\";\r\nimport { resolveAnchoredTransform, resolveProfileTransform, type LayoutSize } from \"./layout.js\";\r\nimport { LayoutGroupNodeView } from \"./views/basic.js\";\r\nimport { NodeView } from \"./views/NodeView.js\";\r\n\r\n/** Importing @pixi/layout installs its renderer extension. Kept as a shared explicit contract for every host. */\r\nexport function initializePixiLayout(): void { /* @pixi/layout is installed by this module's side effect. */ }\r\n\r\nfunction alignmentParts(alignment: LayoutAlignment) {\r\n const [vertical, horizontal] = alignment.split(\"-\") as [\"upper\" | \"middle\" | \"lower\", \"left\" | \"center\" | \"right\"];\r\n return {\r\n horizontal: horizontal === \"left\" ? \"flex-start\" : horizontal === \"right\" ? \"flex-end\" : \"center\",\r\n vertical: vertical === \"upper\" ? \"flex-start\" : vertical === \"lower\" ? \"flex-end\" : \"center\",\r\n };\r\n}\r\n\r\n/**\r\n * Направление заполнения сетки, выведенное из startCorner/startAxis/constraint. Единственный\r\n * источник правды: рантайм задаёт по нему Yoga-флексбокс, а редактор считает по нему же рамки\r\n * выделения, поэтому расходиться этим двум расчётам негде.\r\n */\r\nexport type GridFlow = {\r\n /** Строки являются линиями переноса (иначе линии — это колонки). */\r\n readonly fillsByRow: boolean;\r\n /** Главная ось (порядок внутри линии) идёт справа налево / снизу вверх. */\r\n readonly mainReversed: boolean;\r\n /** Поперечная ось (порядок линий) идёт снизу вверх / справа налево. */\r\n readonly crossReversed: boolean;\r\n /** Фиксированный constraint переносит линии явными разрывами, а не переполнением. */\r\n readonly usesLineBreaks: boolean;\r\n};\r\n\r\nexport function resolveGridFlow(grid: GridLayoutSettings): GridFlow {\r\n const reverseX = grid.startCorner.endsWith(\"right\");\r\n const reverseY = grid.startCorner.startsWith(\"lower\");\r\n const fillsByRow = grid.constraint === \"fixed-column-count\" || (grid.constraint === \"flexible\" && grid.startAxis === \"horizontal\");\r\n return {\r\n fillsByRow,\r\n mainReversed: fillsByRow ? reverseX : reverseY,\r\n crossReversed: fillsByRow ? reverseY : reverseX,\r\n usesLineBreaks: grid.constraint !== \"flexible\" && grid.constraintCount !== undefined,\r\n };\r\n}\r\n\r\nfunction layoutSize(node: UINode, profile: LayoutProfileId, parentSize?: LayoutSize): LayoutSize {\r\n const transform = resolveAnchoredTransform(resolveProfileTransform(node, profile).transform, parentSize);\r\n return { width: transform.width, height: transform.height };\r\n}\r\n\r\n/** Applies one declarative document group to Pixi Layout; no computed Yoga data crosses the document boundary. */\r\nexport function applyLayoutGroup(view: Container, node: LayoutGroupNode, profile: LayoutProfileId, parentSize?: LayoutSize, managedSize?: LayoutSize): void {\r\n const settings = resolveLayoutGroupSettings(node, profile) as LayoutGroupNode[\"layoutGroup\"][\"base\"];\r\n const size = managedSize ?? layoutSize(node, profile, parentSize);\r\n const common = { width: size.width, height: size.height, display: \"flex\" as const };\r\n if (node.type === \"horizontal-layout\" || node.type === \"vertical-layout\") {\r\n const linear = settings as Extract<LayoutGroupNode, { type: \"horizontal-layout\" | \"vertical-layout\" }> [\"layoutGroup\"][\"base\"];\r\n const target = view instanceof LayoutGroupNodeView ? view.layoutTarget : view;\r\n const alignment = alignmentParts(linear.childAlignment);\r\n target.layout = {\r\n ...common,\r\n justifyContent: node.type === \"horizontal-layout\" ? alignment.horizontal : alignment.vertical,\r\n alignItems: node.type === \"horizontal-layout\" ? alignment.vertical : alignment.horizontal,\r\n flexDirection: node.type === \"horizontal-layout\" ? (linear.reverseOrder ? \"row-reverse\" : \"row\") : (linear.reverseOrder ? \"column-reverse\" : \"column\"),\r\n gap: linear.spacing,\r\n paddingLeft: linear.padding.left, paddingRight: linear.padding.right, paddingTop: linear.padding.top, paddingBottom: linear.padding.bottom,\r\n } as never;\r\n return;\r\n }\r\n const grid = settings as Extract<LayoutGroupNode, { type: \"grid-layout\" }> [\"layoutGroup\"][\"base\"];\r\n const flow = resolveGridFlow(grid);\r\n const target = view instanceof LayoutGroupNodeView ? view.layoutTarget : view;\r\n const alignment = alignmentParts(grid.childAlignment);\r\n // justify-content при flex-wrap выравнивает КАЖДУЮ линию отдельно, поэтому неполная последняя\r\n // строка центрируется сама по себе. Это и есть per-row alignment, отдельного поля не нужно.\r\n target.layout = {\r\n ...common,\r\n justifyContent: flow.fillsByRow ? alignment.horizontal : alignment.vertical,\r\n alignItems: flow.fillsByRow ? alignment.vertical : alignment.horizontal,\r\n alignContent: flow.fillsByRow ? alignment.vertical : alignment.horizontal,\r\n flexDirection: flow.fillsByRow ? (flow.mainReversed ? \"row-reverse\" : \"row\") : (flow.mainReversed ? \"column-reverse\" : \"column\"),\r\n flexWrap: flow.crossReversed ? \"wrap-reverse\" : \"wrap\",\r\n // Разрыв строки занимает собственную линию, поэтому поперечный зазор пришёл бы дважды: до\r\n // разрыва и после него. Зазор перенесён в размер самого разрыва, а gutter обнулён.\r\n columnGap: flow.usesLineBreaks && !flow.fillsByRow ? 0 : grid.spacingX,\r\n rowGap: flow.usesLineBreaks && flow.fillsByRow ? 0 : grid.spacingY,\r\n paddingLeft: grid.padding.left, paddingRight: grid.padding.right, paddingTop: grid.padding.top, paddingBottom: grid.padding.bottom,\r\n } as never;\r\n}\r\n\r\n/**\r\n * Runtime-only Yoga owner for one direct child. The wrapper receives Yoga coordinates while the\r\n * serializable NodeView keeps the shared pivot/rotation/scale/content/hit-test contract.\r\n */\r\nexport class LayoutItemContainer extends Container {\r\n private node?: UINode;\r\n private profile: LayoutProfileId = \"desktop\";\r\n private fallbackSize: LayoutSize = { width: 0, height: 0 };\r\n\r\n constructor(readonly nodeView: NodeView, private readonly onLayoutChanged?: () => void) {\r\n super();\r\n super.addChild(nodeView);\r\n this.onLayout = () => this.applyComputedSize();\r\n }\r\n\r\n sync(node: UINode, profile: LayoutProfileId, fallbackSize: LayoutSize): void {\r\n this.node = node;\r\n this.profile = profile;\r\n this.fallbackSize = fallbackSize;\r\n this.visible = resolveProfileTransform(node, profile).visible;\r\n this.applyComputedSize();\r\n }\r\n\r\n private applyComputedSize(): void {\r\n if (this.node === undefined) return;\r\n const computed = this.layout?.computedLayout;\r\n const size = computed === undefined || computed.width <= 0 || computed.height <= 0\r\n ? this.fallbackSize\r\n : { width: computed.width, height: computed.height };\r\n if (isLayoutGroup(this.node)) applyLayoutGroup(this.nodeView, this.node, this.profile, undefined, size);\r\n this.nodeView.updateManaged(this.node, this.profile, size);\r\n this.onLayoutChanged?.();\r\n }\r\n}\r\n\r\n/** Marks a direct child's technical wrapper as layout-managed. */\r\nexport function applyLayoutItem(view: LayoutItemContainer, node: UINode, parent: LayoutGroupNode, profile: LayoutProfileId): void {\r\n // Anchors belong to authored positioning and are deliberately ignored while a parent layout owns\r\n // the rectangle. Width/height remain the child's logical intrinsic size, never Pixi content bounds.\r\n const transform = resolveProfileTransform(node, profile).transform;\r\n const own = { width: transform.width, height: transform.height };\r\n const item = node.layoutItem;\r\n const settings = resolveLayoutGroupSettings(parent, profile);\r\n const base = { position: \"relative\" as const, flexGrow: item?.flexGrow ?? 0, flexShrink: item?.flexShrink ?? 0, flexBasis: item?.flexBasis, alignSelf: item?.alignSelf };\r\n view.sync(node, profile, own);\r\n if (parent.type === \"grid-layout\") {\r\n const grid = settings as Extract<LayoutGroupNode, { type: \"grid-layout\" }> [\"layoutGroup\"][\"base\"];\r\n view.layout = { ...base, width: grid.cellWidth, height: grid.cellHeight } as never;\r\n return;\r\n }\r\n const linear = settings as Extract<LayoutGroupNode, { type: \"horizontal-layout\" | \"vertical-layout\" }> [\"layoutGroup\"][\"base\"];\r\n const horizontal = parent.type === \"horizontal-layout\";\r\n const expandsMain = horizontal\r\n ? linear.controlChildWidth && linear.forceExpandWidth\r\n : linear.controlChildHeight && linear.forceExpandHeight;\r\n const expandsCross = horizontal\r\n ? linear.controlChildHeight && linear.forceExpandHeight\r\n : linear.controlChildWidth && linear.forceExpandWidth;\r\n view.layout = {\r\n ...base,\r\n // The schema has no separate min/preferred size yet, so the logical authored rect is the safe\r\n // intrinsic fallback for both control modes. Force-expand may then replace the relevant axis.\r\n width: expandsCross && !horizontal ? undefined : own.width,\r\n height: expandsCross && horizontal ? undefined : own.height,\r\n ...(expandsMain ? { flexGrow: Math.max(1, item?.flexGrow ?? 0) } : {}),\r\n ...(expandsCross ? { alignSelf: item?.alignSelf ?? \"stretch\" } : {}),\r\n } as never;\r\n}\r\n\r\n/** A zero-visual Yoga flex item. Fixed Unity grid constraints need explicit line breaks; this is still solved entirely by Yoga. */\r\nexport function createGridLineBreak(parent: Extract<LayoutGroupNode, { type: \"grid-layout\" }>, profile: LayoutProfileId): Container | undefined {\r\n const grid = resolveLayoutGroupSettings(parent, profile) as Extract<LayoutGroupNode, { type: \"grid-layout\" }> [\"layoutGroup\"][\"base\"];\r\n if (grid.constraint === \"flexible\" || grid.constraintCount === undefined) return undefined;\r\n const lineBreak = new Container({ label: \"__layout-grid-line-break__\" });\r\n // Поперечный зазор между линиями живёт здесь, а не в rowGap/columnGap группы: см. applyLayoutGroup.\r\n lineBreak.layout = (grid.constraint === \"fixed-column-count\"\r\n ? { flexBasis: \"100%\", width: \"100%\", height: grid.spacingY, flexShrink: 0 }\r\n : { flexBasis: \"100%\", height: \"100%\", width: grid.spacingX, flexShrink: 0 }) as never;\r\n return lineBreak;\r\n}\r\n\r\nexport function isLayoutManagedChild(node: UINode, nodes: readonly UINode[]): boolean {\r\n return node.parentId !== null && isLayoutGroup(nodes.find((candidate) => candidate.id === node.parentId) ?? node) && nodes.some((candidate) => candidate.id === node.parentId && isLayoutGroup(candidate));\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"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"}
package/dist/scene.js CHANGED
@@ -72,11 +72,20 @@ export function buildSceneView(document, sceneId, profile, options) {
72
72
  // иначе они не отслеживают изменение Cell width/height и якорятся относительно устаревшего размера.
73
73
  const gridParent = node.parentId === null ? undefined : nodesById.get(node.parentId);
74
74
  const gridCell = gridParent?.type === "grid-layout" ? resolveLayoutGroupSettings(gridParent, profile) : undefined;
75
+ // Та же логика для прямого ребёнка page-group (страницы): `PageItemContainer`/`updateManaged`
76
+ // растягивают её на весь resolved rectangle группы независимо от собственных anchors ноды
77
+ // (см. NodeView.applyResolvedTransform, managedByLayout). Здесь `node` — сама страница, поэтому
78
+ // это переопределённый размер, который она фактически получит, — `parentSize`, уже разрешённый
79
+ // как rectangle page-group. Без этой ветки дети страницы якорились бы относительно её
80
+ // anchor-resolved authored-размера, который может расходиться с фактическим rectangle группы,
81
+ // особенно в другом layout-профиле.
75
82
  const childSize = node.parentId === null
76
83
  ? rootSize
77
84
  : gridCell !== undefined
78
85
  ? { width: gridCell.cellWidth, height: gridCell.cellHeight }
79
- : { width: transform.width, height: transform.height };
86
+ : gridParent?.type === "page-group"
87
+ ? parentSize
88
+ : { width: transform.width, height: transform.height };
80
89
  for (const [childIndex, childId] of node.children.entries()) {
81
90
  const childNode = nodesById.get(childId);
82
91
  const childView = buildNode(childId, childSize);
@@ -167,6 +176,9 @@ function wireNodeReferences(nodes, nodeViews, interaction) {
167
176
  else if (node.type === "pagination" && view instanceof PaginationNodeView && interaction === "runtime") {
168
177
  view.setArrows({ previous: arrowView(node.prevButtonNodeId), next: arrowView(node.nextButtonNodeId) });
169
178
  }
179
+ else if (node.type === "page-group" && view instanceof PageGroupNodeView && interaction === "runtime") {
180
+ view.setArrows({ up: arrowView(node.pageUpButtonNodeId), down: arrowView(node.pageDownButtonNodeId) });
181
+ }
170
182
  }
171
183
  }
172
184
  /**
package/dist/scene.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"scene.js","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"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","sourcesContent":["import { type SkeletonData } from \"@esotericsoftware/spine-pixi-v8\";\nimport { createStableId, isLayoutGroup, isParticleEffect, resolveLayoutGroupSettings, resolveOwnerNodeGraph, type EffectDefinition, type GridLayoutSettings, type LayoutProfileId, type ProjectDocument, type Scene, type SpineReferenceFrame, type UINode } from \"@pixi-ui-editor/schema\";\nimport { Container, Texture, type Ticker } from \"pixi.js\";\nimport { loadSceneSpines } from \"./assets/spine.js\";\nimport { loadSceneTextures, type FileUrlResolver } from \"./assets/textures.js\";\nimport { loadSceneFonts } from \"./assets/fonts.js\";\nimport { loadSceneBitmapFonts } from \"./assets/bitmapFonts.js\";\nimport type { SceneAssetCache } from \"./assets/cache.js\";\nimport { getCanvasLogicalSize, getCanvasScale, resolveAnchoredTransform, resolveProfileTransform, type LayoutSize } from \"./layout.js\";\nimport { NodeView, type SceneInteractionMode } from \"./views/NodeView.js\";\nimport { CheckboxNodeView } from \"./views/CheckboxNodeView.js\";\nimport { createNodeView } from \"./views/createNodeView.js\";\nimport { applyLayoutGroup, applyLayoutItem, createGridLineBreak, initializePixiLayout, LayoutItemContainer } from \"./layoutGroups.js\";\nimport { LayoutGroupNodeView } from \"./views/basic.js\";\nimport { PageItemContainer } from \"./pageGroup.js\";\nimport { PageGroupNodeView } from \"./views/PageGroupNodeView.js\";\nimport { PaginationNodeView, type PaginationArrow } from \"./views/PaginationNodeView.js\";\nimport { ItemTableNodeView } from \"./views/ItemTableNodeView.js\";\nimport { ButtonNodeView } from \"./views/ButtonNodeView.js\";\nimport { StagedButtonNodeView } from \"./views/StagedButtonNodeView.js\";\nimport { ScrollItemContainer } from \"./scrollView.js\";\nimport { ScrollViewNodeView } from \"./views/ScrollViewNodeView.js\";\nimport { SpineNodeView } from \"./views/SpineNodeView.js\";\nimport { ParticleEmitterNodeView } from \"./views/ParticleEmitterNodeView.js\";\nimport { SceneLocalization, type SceneLocalizationOptions } from \"./localization.js\";\nimport { SceneViewport } from \"./SceneViewport.js\";\nimport type { Sound } from \"@pixi/sound\";\n\nexport type BuildSceneViewOptions = {\n /** Explicit: an editor canvas must pass \"authoring\", Preview and the consuming app \"runtime\". */\n interaction: SceneInteractionMode;\n textures?: ReadonlyMap<string, Texture>;\n spines?: ReadonlyMap<string, SkeletonData>;\n fonts?: ReadonlyMap<string, string>;\n bitmapFonts?: ReadonlyMap<string, string>;\n sounds?: ReadonlyMap<string, Sound>;\n /**\n * The host's own Application ticker, driving self-updating content such as Spine skeletons.\n * Without it they fall back to `Ticker.shared`, which runs a second rAF loop independent of the\n * renderer that draws them — see the same rule as `updateParticleEmitters`.\n */\n ticker?: Ticker;\n /** Called after Yoga changes a managed rectangle; authoring hosts use it to refresh overlays. */\n onLayout?: () => void;\n /**\n * Начальное состояние локализации. Опция необязательна: при наличии `Text.textKey` base locale\n * каталога применяется и без неё, а документ без ключей выглядит ровно как раньше.\n */\n localization?: SceneLocalizationOptions;\n /** Internal host boundary override: prefab views are spawnable content, not screen viewports. */\n clipToViewport?: boolean;\n};\n\nexport type SceneViewResult = { root: SceneViewport; nodeViews: Map<string, Container>; localization: SceneLocalization };\nconst particleEmitterRegistry = new WeakMap<Container, readonly ParticleEmitterNodeView[]>();\n\nfunction spineReferenceFrameFor(document: ProjectDocument, node: UINode): SpineReferenceFrame | undefined {\n if (node.type !== \"spine\") return undefined;\n const asset = document.assets.find((candidate) => candidate.id === node.assetId);\n return asset?.type === \"spine\" ? asset.referenceFrame : undefined;\n}\n\n/** Builds a PixiJS display tree for a scene without depending on DOM or editor state. */\nexport function buildSceneView(\n document: ProjectDocument,\n sceneId: string,\n profile: LayoutProfileId,\n options: BuildSceneViewOptions,\n): SceneViewResult {\n initializePixiLayout();\n const { interaction, textures, spines, fonts, bitmapFonts, sounds, ticker, onLayout } = options;\n const scene = document.scenes.find((candidate) => candidate.id === sceneId);\n\n if (scene === undefined) {\n throw new Error(`Scene '${sceneId}' does not exist in the project document.`);\n }\n\n const nodeViews = new Map<string, Container>();\n const particleEmitters: ParticleEmitterNodeView[] = [];\n\n // Materialized prefab children use instance-scoped IDs, so authoring and runtime can address\n // multiple instances independently without changing canonical definition IDs.\n const screenSize = scene.layout.referenceViewports[profile];\n const referenceResolution = scene.layout.preferredViewports[profile];\n const canvasScale = getCanvasScale(screenSize, referenceResolution);\n const canvasSize = getCanvasLogicalSize(screenSize, referenceResolution);\n\n // Единый резолвер иерархии: тот же граф, что видит редактор, включая вложенные пресеты.\n const owner = resolveOwnerNodeGraph(document, scene);\n const prefabIds = new Set(document.prefabs.map((prefab) => prefab.id));\n\n const buildOwner = (rootSize: LayoutSize): Container => {\n const nodesById = new Map(owner.nodes.map((node) => [node.id, node]));\n\n const buildNode = (nodeId: string, parentSize: LayoutSize): NodeView => {\n const node = nodesById.get(nodeId);\n\n if (node === undefined) {\n throw new Error(`Scene '${sceneId}' references missing node '${nodeId}'.`);\n }\n\n const resolved = resolveProfileTransform(node, profile);\n const transform = resolveAnchoredTransform(resolved.transform, parentSize);\n const view = createNodeView(node, interaction, textures, spines, (prefabId) => prefabIds.has(prefabId), fonts, sounds, node.type === \"particle-emitter\" ? document.effects.find((effect) => effect.id === node.effectId && isParticleEffect(effect)) : undefined, spineReferenceFrameFor(document, node), ticker, bitmapFonts);\n if (isLayoutGroup(node)) applyLayoutGroup(view, node, profile, parentSize);\n // Yoga owns only the group's inner layoutContent; the outer NodeView keeps authored transform.\n view.update(node, profile, parentSize);\n nodeViews.set(node.id, view);\n if (view instanceof ParticleEmitterNodeView) particleEmitters.push(view);\n\n // Прямые дети корня сцены разрешают якоря относительно логического Canvas, а не размера корня.\n // Прямой ребёнок grid-layout (сам `node` здесь) не владеет своим отрисованным размером: Unity-подобная\n // фиксированная ячейка полностью переопределяет authored transform (см. applyLayoutItem). Его\n // собственным потомкам нужен именно cellWidth/cellHeight, а не anchor-resolved authored-размер —\n // иначе они не отслеживают изменение Cell width/height и якорятся относительно устаревшего размера.\n const gridParent = node.parentId === null ? undefined : nodesById.get(node.parentId);\n const gridCell = gridParent?.type === \"grid-layout\" ? resolveLayoutGroupSettings<GridLayoutSettings>(gridParent, profile) : undefined;\n const childSize = node.parentId === null\n ? rootSize\n : gridCell !== undefined\n ? { width: gridCell.cellWidth, height: gridCell.cellHeight }\n : { width: transform.width, height: transform.height };\n for (const [childIndex, childId] of node.children.entries()) {\n const childNode = nodesById.get(childId);\n const childView = buildNode(childId, childSize);\n if (isLayoutGroup(node) && childNode !== undefined && view instanceof LayoutGroupNodeView) {\n const layoutItem = new LayoutItemContainer(childView, onLayout);\n applyLayoutItem(layoutItem, childNode, node, profile);\n view.addLayoutChild(layoutItem);\n } else if (node.type === \"scroll-view\" && childNode !== undefined && view instanceof ScrollViewNodeView) {\n const scrollItem = new ScrollItemContainer(childView, onLayout);\n // Как и у layout-item: собственный (не растянутый якорями) размер ребёнка — List не\n // предоставляет per-item override размера, в отличие от Yoga flexGrow/cellSize.\n const own = resolveProfileTransform(childNode, profile).transform;\n scrollItem.sync(childNode, profile, { width: own.width, height: own.height });\n view.addScrollItem(scrollItem);\n } else if (node.type === \"page-group\" && childNode !== undefined && view instanceof PageGroupNodeView) {\n // Unlike a scroll-view item, a page fills the group's own resolved rect completely\n // (`childSize`, computed above): a page is a full sub-screen, not content sized to itself.\n const pageItem = new PageItemContainer(childView);\n pageItem.sync(childNode, profile, childSize);\n view.addPageItem(pageItem);\n } else {\n view.addChild(childView);\n }\n if (node.type === \"grid-layout\") {\n const settings = node.layoutGroup.overrides?.[profile] === undefined ? node.layoutGroup.base : { ...node.layoutGroup.base, ...node.layoutGroup.overrides[profile] };\n if (settings.constraint !== \"flexible\" && settings.constraintCount !== undefined && (childIndex + 1) % settings.constraintCount === 0 && childIndex + 1 < node.children.length) {\n const lineBreak = createGridLineBreak(node, profile);\n if (lineBreak !== undefined && view instanceof LayoutGroupNodeView) view.addLayoutChild(lineBreak);\n }\n }\n }\n\n return view;\n };\n\n const ownerRoot = new Container();\n for (const rootNodeId of owner.rootNodeIds) {\n ownerRoot.addChild(buildNode(rootNodeId, rootSize));\n }\n\n return ownerRoot;\n };\n\n const canvasRoot = buildOwner(canvasSize);\n canvasRoot.scale.set(canvasScale);\n const hostRoot = new SceneViewport(canvasRoot, screenSize, options.clipToViewport ?? interaction === \"runtime\");\n particleEmitterRegistry.set(hostRoot, particleEmitters);\n // Контроллер применяет переводы сразу к уже созданным views, поэтому keyed Text показывает\n // базовую локаль без единого дополнительного вызова со стороны хоста.\n const localization = new SceneLocalization(document, scene, nodeViews, options.localization);\n wireCheckboxGroups(owner.nodes, nodeViews);\n wireSpineConnectors(owner.nodes, nodeViews);\n wireNodeReferences(owner.nodes, nodeViews, interaction);\n return { root: hostRoot, nodeViews, localization };\n}\n\nfunction wireSpineConnectors(nodes: readonly UINode[], nodeViews: ReadonlyMap<string, Container>): void {\n for (const node of nodes) {\n if (node.type !== \"spine\") continue;\n const view = nodeViews.get(node.id);\n if (!(view instanceof SpineNodeView)) continue;\n view.setConnectorBones((node.connectors ?? []).flatMap((connector) => {\n const target = nodeViews.get(connector.targetNodeId);\n return target === undefined ? [] : [{ ...connector, target }];\n }));\n }\n}\n\n/**\n * Разрешает все ссылки «нода → нода» в живые views: элементы item table и кнопки-стрелки пагинатора.\n * Та же форма, что у `wireSpineConnectors`: документ хранит id, а во что он превратился, знает только\n * собранная сцена, поэтому сами виды никогда не резолвят id. Один проход на все виды ссылок, чтобы\n * следующая не завела собственный обход с чуть другой областью видимости.\n *\n * Стрелки подключаются только в runtime-сцене: на authoring-канвасе контрол инертен, как и клик по\n * самой точке пагинатора. Вместимость таблицы, наоборот, видна и в редакторе — это не интерактивность.\n */\nfunction wireNodeReferences(nodes: readonly UINode[], nodeViews: ReadonlyMap<string, Container>, interaction: SceneInteractionMode): void {\n const arrowView = (nodeId: string | undefined): PaginationArrow | undefined => {\n const view = nodeId === undefined ? undefined : nodeViews.get(nodeId);\n return view instanceof ButtonNodeView || view instanceof StagedButtonNodeView ? view : undefined;\n };\n for (const node of nodes) {\n const view = nodeViews.get(node.id);\n if (node.type === \"item-table\" && view instanceof ItemTableNodeView) {\n view.setItems((node.items ?? []).map((itemId) => nodeViews.get(itemId)));\n } else if (node.type === \"pagination\" && view instanceof PaginationNodeView && interaction === \"runtime\") {\n view.setArrows({ previous: arrowView(node.prevButtonNodeId), next: arrowView(node.nextButtonNodeId) });\n }\n }\n}\n\n/**\n * Authored `group` gives sibling checkboxes radio-button behavior: checking one force-unchecks its\n * live group-mates (same `parentId`, same `group`), without touching the document. Runs once per\n * scene build; `CheckboxNodeView.forceCheck` never re-emits `onCheck`, so this can't recurse.\n */\nfunction wireCheckboxGroups(nodes: readonly UINode[], nodeViews: ReadonlyMap<string, Container>): void {\n const byGroup = new Map<string, CheckboxNodeView[]>();\n for (const node of nodes) {\n if (node.type !== \"checkbox\" || node.group === undefined) continue;\n const view = nodeViews.get(node.id);\n if (!(view instanceof CheckboxNodeView)) continue;\n const key = `${node.parentId ?? \"\"}::${node.group}`;\n const group = byGroup.get(key) ?? [];\n group.push(view);\n byGroup.set(key, group);\n }\n for (const group of byGroup.values()) {\n if (group.length < 2) continue;\n for (const view of group) {\n view.onCheck.connect((checked) => {\n if (!checked) return;\n for (const other of group) if (other !== view) other.forceCheck(false);\n });\n }\n }\n}\n\n/**\n * Applies a node's resolved transform, visibility, and content to an existing display object,\n * so editors can update views in place without rebuilding the scene tree.\n */\nexport function updateNodeView(view: Container, node: UINode, profile: LayoutProfileId, parentSize?: LayoutSize, parentNode?: UINode, effect?: EffectDefinition, spineReferenceFrame?: SpineReferenceFrame): void {\n if (isLayoutGroup(node)) applyLayoutGroup(view, node, profile, parentSize);\n if (!(view instanceof NodeView)) return;\n if (view instanceof SpineNodeView) view.setReferenceFrame(spineReferenceFrame);\n if (node.type === \"particle-emitter\" && effect !== undefined && isParticleEffect(effect) && \"syncEffect\" in view && typeof (view as { syncEffect?: unknown }).syncEffect === \"function\") (view as { syncEffect(effect: import(\"@pixi-ui-editor/schema\").ParticleEffectDefinition): void }).syncEffect(effect);\n if (parentNode !== undefined && isLayoutGroup(parentNode) && view.parent instanceof LayoutItemContainer) {\n applyLayoutItem(view.parent, node, parentNode, profile);\n } else if (parentNode !== undefined && parentNode.type === \"scroll-view\" && view.parent instanceof ScrollItemContainer) {\n const own = resolveProfileTransform(node, profile).transform;\n view.parent.sync(node, profile, { width: own.width, height: own.height });\n } else if (parentNode !== undefined && parentNode.type === \"page-group\" && view.parent instanceof PageItemContainer && parentSize !== undefined) {\n // A page is position-managed exactly like a layout/scroll item: it fills the group's own rectangle\n // (`parentSize`, the same value `buildSceneView` passes as `childSize`). Without this branch an\n // in-place update fell through to `view.update` and handed the page back its authored x/y and\n // anchors, so editing anything inside a page group knocked its pages out of place.\n view.parent.sync(node, profile, parentSize);\n } else {\n view.update(node, profile, parentSize);\n }\n}\n\n/** Previews a resolved editor rectangle without consulting content bounds or rebuilding the view. */\nexport function previewNodeView(view: Container, node: UINode, profile: LayoutProfileId, transform: UINode[\"transform\"]): void {\n if (isLayoutGroup(node)) applyLayoutGroup(view, node, profile, undefined, { width: transform.width, height: transform.height });\n if (view instanceof NodeView) view.preview(node, transform, resolveProfileTransform(node, profile).visible, profile);\n}\n\n/** Hosts call this from their own Application ticker; runtime never subscribes to Ticker.shared. */\nexport function updateParticleEmitters(root: Container, deltaSeconds: number): void {\n const registered = particleEmitterRegistry.get(root);\n if (registered !== undefined) {\n for (const emitter of registered) emitter.updateParticles(deltaSeconds);\n return;\n }\n // Backward-compatible fallback for hosts that assemble a display tree manually instead of using\n // buildSceneView. Built scenes always take the O(emitter count) registry path above.\n const visit = (view: Container): void => {\n if (view instanceof ParticleEmitterNodeView) view.updateParticles(deltaSeconds);\n for (const child of view.children) visit(child);\n };\n visit(root);\n}\n\n/** Lists the nodes a scene renders, including nodes of prefab definitions its prefab instances expand to. */\nexport function collectRenderedNodes(document: ProjectDocument, scene: Scene): UINode[] {\n return resolveOwnerNodeGraph(document, scene).nodes;\n}\n\nexport type PrefabViewConfiguration = Pick<Extract<UINode, { type: \"prefab-instance\" }>, \"propertyOverrides\" | \"locallyAddedNodes\"> & { instanceId?: string };\n\nfunction prefabScene(document: ProjectDocument, prefabId: string, configuration: PrefabViewConfiguration = {}): { document: ProjectDocument; sceneId: string; instanceId: string } {\n const prefab = document.prefabs.find((candidate) => candidate.id === prefabId);\n if (prefab === undefined) throw new Error(`Prefab '${prefabId}' does not exist in the project document.`);\n const width = Math.max(1, ...prefab.nodes.map((node) => Math.abs(node.transform.x) + Math.max(0, node.transform.width)));\n const height = Math.max(1, ...prefab.nodes.map((node) => Math.abs(node.transform.y) + Math.max(0, node.transform.height)));\n const instanceId = configuration.instanceId ?? createStableId();\n const instance: Extract<UINode, { type: \"prefab-instance\" }> = {\n id: instanceId, name: prefab.name, type: \"prefab-instance\", prefabId, parentId: null, children: [],\n visible: true, transform: { x: 0, y: 0, width, height, scaleX: 1, scaleY: 1, rotation: 0, anchorMinX: 0, anchorMaxX: 0, anchorMinY: 0, anchorMaxY: 0, pivotX: 0, pivotY: 0 },\n ...(configuration.propertyOverrides === undefined ? {} : { propertyOverrides: structuredClone(configuration.propertyOverrides) }),\n ...(configuration.locallyAddedNodes === undefined ? {} : { locallyAddedNodes: structuredClone(configuration.locallyAddedNodes) }),\n };\n const sceneId = createStableId();\n const viewport = { width, height };\n const scene: Scene = { id: sceneId, name: prefab.name, rootNodeIds: [instance.id], nodes: [instance], layout: { referenceViewports: { desktop: viewport, mobile: viewport }, preferredViewports: { desktop: viewport, mobile: viewport } } };\n return { document: { ...document, scenes: [...document.scenes, scene] }, sceneId, instanceId };\n}\n\n/** Builds a fresh runtime prefab instance without requiring it to already exist in a scene. */\nexport function buildPrefabView(document: ProjectDocument, prefabId: string, profile: LayoutProfileId, options: BuildSceneViewOptions, configuration: PrefabViewConfiguration = {}): SceneViewResult & { instanceId: string } {\n const synthetic = prefabScene(document, prefabId, configuration);\n return { ...buildSceneView(synthetic.document, synthetic.sceneId, profile, { ...options, clipToViewport: false }), instanceId: synthetic.instanceId };\n}\n\n/** Loads a prefab's assets and returns a fresh display tree suitable for dynamic game-code spawning. */\nexport async function loadPrefabView(document: ProjectDocument, prefabId: string, profile: LayoutProfileId, resolveFileUrl: FileUrlResolver, options: { interaction: SceneInteractionMode; ticker?: Ticker; localization?: SceneLocalizationOptions; assetCache?: SceneAssetCache }, configuration: PrefabViewConfiguration = {}): Promise<SceneViewResult & { instanceId: string }> {\n const synthetic = prefabScene(document, prefabId, configuration);\n return { ...await loadSceneView(synthetic.document, synthetic.sceneId, profile, resolveFileUrl, { ...options, clipToViewport: false }), instanceId: synthetic.instanceId };\n}\n\n/** Loads a scene's textures and Spine data, then builds its display tree in one call. */\nexport async function loadSceneView(\n document: ProjectDocument,\n sceneId: string,\n profile: LayoutProfileId,\n resolveFileUrl: FileUrlResolver,\n options: { interaction: SceneInteractionMode; ticker?: Ticker; localization?: SceneLocalizationOptions; clipToViewport?: boolean; assetCache?: SceneAssetCache },\n): Promise<SceneViewResult> {\n // Без assetCache каждый вызов начинает с пустых кэшей: для одиночной загрузки сцены это нормально, а вот\n // игровой код, который поднимает пресеты по одному, обязан передать собственный кэш — иначе один и тот же\n // скелет, атлас и текстура парсятся заново на каждую вьюху и дублируются в видеопамяти.\n const cache = options.assetCache;\n const [textures, spines, fonts, bitmapFonts] = await Promise.all([\n loadSceneTextures(document, sceneId, (asset) => (asset.type === \"image\" ? resolveFileUrl(asset.source.uri) : undefined), resolveFileUrl, cache?.textures, cache?.spritesheets, cache?.bitmapFonts),\n loadSceneSpines(document, sceneId, resolveFileUrl, cache?.spines),\n loadSceneFonts(document, sceneId, resolveFileUrl, cache?.fonts),\n loadSceneBitmapFonts(document, sceneId, resolveFileUrl, cache?.bitmapFonts),\n ]);\n return buildSceneView(document, sceneId, profile, { interaction: options.interaction, textures, spines, fonts, bitmapFonts, ticker: options.ticker, localization: options.localization, clipToViewport: options.clipToViewport });\n}\n"]}
1
+ {"version":3,"file":"scene.js","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"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","sourcesContent":["import { type SkeletonData } from \"@esotericsoftware/spine-pixi-v8\";\nimport { createStableId, isLayoutGroup, isParticleEffect, resolveLayoutGroupSettings, resolveOwnerNodeGraph, type EffectDefinition, type GridLayoutSettings, type LayoutProfileId, type ProjectDocument, type Scene, type SpineReferenceFrame, type UINode } from \"@pixi-ui-editor/schema\";\nimport { Container, Texture, type Ticker } from \"pixi.js\";\nimport { loadSceneSpines } from \"./assets/spine.js\";\nimport { loadSceneTextures, type FileUrlResolver } from \"./assets/textures.js\";\nimport { loadSceneFonts } from \"./assets/fonts.js\";\nimport { loadSceneBitmapFonts } from \"./assets/bitmapFonts.js\";\nimport type { SceneAssetCache } from \"./assets/cache.js\";\nimport { getCanvasLogicalSize, getCanvasScale, resolveAnchoredTransform, resolveProfileTransform, type LayoutSize } from \"./layout.js\";\nimport { NodeView, type SceneInteractionMode } from \"./views/NodeView.js\";\nimport { CheckboxNodeView } from \"./views/CheckboxNodeView.js\";\nimport { createNodeView } from \"./views/createNodeView.js\";\nimport { applyLayoutGroup, applyLayoutItem, createGridLineBreak, initializePixiLayout, LayoutItemContainer } from \"./layoutGroups.js\";\nimport { LayoutGroupNodeView } from \"./views/basic.js\";\nimport { PageItemContainer } from \"./pageGroup.js\";\nimport { PageGroupNodeView } from \"./views/PageGroupNodeView.js\";\nimport { PaginationNodeView, type PaginationArrow } from \"./views/PaginationNodeView.js\";\nimport { ItemTableNodeView } from \"./views/ItemTableNodeView.js\";\nimport { ButtonNodeView } from \"./views/ButtonNodeView.js\";\nimport { StagedButtonNodeView } from \"./views/StagedButtonNodeView.js\";\nimport { ScrollItemContainer } from \"./scrollView.js\";\nimport { ScrollViewNodeView } from \"./views/ScrollViewNodeView.js\";\nimport { SpineNodeView } from \"./views/SpineNodeView.js\";\nimport { ParticleEmitterNodeView } from \"./views/ParticleEmitterNodeView.js\";\nimport { SceneLocalization, type SceneLocalizationOptions } from \"./localization.js\";\nimport { SceneViewport } from \"./SceneViewport.js\";\nimport type { Sound } from \"@pixi/sound\";\n\nexport type BuildSceneViewOptions = {\n /** Explicit: an editor canvas must pass \"authoring\", Preview and the consuming app \"runtime\". */\n interaction: SceneInteractionMode;\n textures?: ReadonlyMap<string, Texture>;\n spines?: ReadonlyMap<string, SkeletonData>;\n fonts?: ReadonlyMap<string, string>;\n bitmapFonts?: ReadonlyMap<string, string>;\n sounds?: ReadonlyMap<string, Sound>;\n /**\n * The host's own Application ticker, driving self-updating content such as Spine skeletons.\n * Without it they fall back to `Ticker.shared`, which runs a second rAF loop independent of the\n * renderer that draws them — see the same rule as `updateParticleEmitters`.\n */\n ticker?: Ticker;\n /** Called after Yoga changes a managed rectangle; authoring hosts use it to refresh overlays. */\n onLayout?: () => void;\n /**\n * Начальное состояние локализации. Опция необязательна: при наличии `Text.textKey` base locale\n * каталога применяется и без неё, а документ без ключей выглядит ровно как раньше.\n */\n localization?: SceneLocalizationOptions;\n /** Internal host boundary override: prefab views are spawnable content, not screen viewports. */\n clipToViewport?: boolean;\n};\n\nexport type SceneViewResult = { root: SceneViewport; nodeViews: Map<string, Container>; localization: SceneLocalization };\nconst particleEmitterRegistry = new WeakMap<Container, readonly ParticleEmitterNodeView[]>();\n\nfunction spineReferenceFrameFor(document: ProjectDocument, node: UINode): SpineReferenceFrame | undefined {\n if (node.type !== \"spine\") return undefined;\n const asset = document.assets.find((candidate) => candidate.id === node.assetId);\n return asset?.type === \"spine\" ? asset.referenceFrame : undefined;\n}\n\n/** Builds a PixiJS display tree for a scene without depending on DOM or editor state. */\nexport function buildSceneView(\n document: ProjectDocument,\n sceneId: string,\n profile: LayoutProfileId,\n options: BuildSceneViewOptions,\n): SceneViewResult {\n initializePixiLayout();\n const { interaction, textures, spines, fonts, bitmapFonts, sounds, ticker, onLayout } = options;\n const scene = document.scenes.find((candidate) => candidate.id === sceneId);\n\n if (scene === undefined) {\n throw new Error(`Scene '${sceneId}' does not exist in the project document.`);\n }\n\n const nodeViews = new Map<string, Container>();\n const particleEmitters: ParticleEmitterNodeView[] = [];\n\n // Materialized prefab children use instance-scoped IDs, so authoring and runtime can address\n // multiple instances independently without changing canonical definition IDs.\n const screenSize = scene.layout.referenceViewports[profile];\n const referenceResolution = scene.layout.preferredViewports[profile];\n const canvasScale = getCanvasScale(screenSize, referenceResolution);\n const canvasSize = getCanvasLogicalSize(screenSize, referenceResolution);\n\n // Единый резолвер иерархии: тот же граф, что видит редактор, включая вложенные пресеты.\n const owner = resolveOwnerNodeGraph(document, scene);\n const prefabIds = new Set(document.prefabs.map((prefab) => prefab.id));\n\n const buildOwner = (rootSize: LayoutSize): Container => {\n const nodesById = new Map(owner.nodes.map((node) => [node.id, node]));\n\n const buildNode = (nodeId: string, parentSize: LayoutSize): NodeView => {\n const node = nodesById.get(nodeId);\n\n if (node === undefined) {\n throw new Error(`Scene '${sceneId}' references missing node '${nodeId}'.`);\n }\n\n const resolved = resolveProfileTransform(node, profile);\n const transform = resolveAnchoredTransform(resolved.transform, parentSize);\n const view = createNodeView(node, interaction, textures, spines, (prefabId) => prefabIds.has(prefabId), fonts, sounds, node.type === \"particle-emitter\" ? document.effects.find((effect) => effect.id === node.effectId && isParticleEffect(effect)) : undefined, spineReferenceFrameFor(document, node), ticker, bitmapFonts);\n if (isLayoutGroup(node)) applyLayoutGroup(view, node, profile, parentSize);\n // Yoga owns only the group's inner layoutContent; the outer NodeView keeps authored transform.\n view.update(node, profile, parentSize);\n nodeViews.set(node.id, view);\n if (view instanceof ParticleEmitterNodeView) particleEmitters.push(view);\n\n // Прямые дети корня сцены разрешают якоря относительно логического Canvas, а не размера корня.\n // Прямой ребёнок grid-layout (сам `node` здесь) не владеет своим отрисованным размером: Unity-подобная\n // фиксированная ячейка полностью переопределяет authored transform (см. applyLayoutItem). Его\n // собственным потомкам нужен именно cellWidth/cellHeight, а не anchor-resolved authored-размер —\n // иначе они не отслеживают изменение Cell width/height и якорятся относительно устаревшего размера.\n const gridParent = node.parentId === null ? undefined : nodesById.get(node.parentId);\n const gridCell = gridParent?.type === \"grid-layout\" ? resolveLayoutGroupSettings<GridLayoutSettings>(gridParent, profile) : undefined;\n // Та же логика для прямого ребёнка page-group (страницы): `PageItemContainer`/`updateManaged`\n // растягивают её на весь resolved rectangle группы независимо от собственных anchors ноды\n // (см. NodeView.applyResolvedTransform, managedByLayout). Здесь `node` — сама страница, поэтому\n // это переопределённый размер, который она фактически получит, — `parentSize`, уже разрешённый\n // как rectangle page-group. Без этой ветки дети страницы якорились бы относительно её\n // anchor-resolved authored-размера, который может расходиться с фактическим rectangle группы,\n // особенно в другом layout-профиле.\n const childSize = node.parentId === null\n ? rootSize\n : gridCell !== undefined\n ? { width: gridCell.cellWidth, height: gridCell.cellHeight }\n : gridParent?.type === \"page-group\"\n ? parentSize\n : { width: transform.width, height: transform.height };\n for (const [childIndex, childId] of node.children.entries()) {\n const childNode = nodesById.get(childId);\n const childView = buildNode(childId, childSize);\n if (isLayoutGroup(node) && childNode !== undefined && view instanceof LayoutGroupNodeView) {\n const layoutItem = new LayoutItemContainer(childView, onLayout);\n applyLayoutItem(layoutItem, childNode, node, profile);\n view.addLayoutChild(layoutItem);\n } else if (node.type === \"scroll-view\" && childNode !== undefined && view instanceof ScrollViewNodeView) {\n const scrollItem = new ScrollItemContainer(childView, onLayout);\n // Как и у layout-item: собственный (не растянутый якорями) размер ребёнка — List не\n // предоставляет per-item override размера, в отличие от Yoga flexGrow/cellSize.\n const own = resolveProfileTransform(childNode, profile).transform;\n scrollItem.sync(childNode, profile, { width: own.width, height: own.height });\n view.addScrollItem(scrollItem);\n } else if (node.type === \"page-group\" && childNode !== undefined && view instanceof PageGroupNodeView) {\n // Unlike a scroll-view item, a page fills the group's own resolved rect completely\n // (`childSize`, computed above): a page is a full sub-screen, not content sized to itself.\n const pageItem = new PageItemContainer(childView);\n pageItem.sync(childNode, profile, childSize);\n view.addPageItem(pageItem);\n } else {\n view.addChild(childView);\n }\n if (node.type === \"grid-layout\") {\n const settings = node.layoutGroup.overrides?.[profile] === undefined ? node.layoutGroup.base : { ...node.layoutGroup.base, ...node.layoutGroup.overrides[profile] };\n if (settings.constraint !== \"flexible\" && settings.constraintCount !== undefined && (childIndex + 1) % settings.constraintCount === 0 && childIndex + 1 < node.children.length) {\n const lineBreak = createGridLineBreak(node, profile);\n if (lineBreak !== undefined && view instanceof LayoutGroupNodeView) view.addLayoutChild(lineBreak);\n }\n }\n }\n\n return view;\n };\n\n const ownerRoot = new Container();\n for (const rootNodeId of owner.rootNodeIds) {\n ownerRoot.addChild(buildNode(rootNodeId, rootSize));\n }\n\n return ownerRoot;\n };\n\n const canvasRoot = buildOwner(canvasSize);\n canvasRoot.scale.set(canvasScale);\n const hostRoot = new SceneViewport(canvasRoot, screenSize, options.clipToViewport ?? interaction === \"runtime\");\n particleEmitterRegistry.set(hostRoot, particleEmitters);\n // Контроллер применяет переводы сразу к уже созданным views, поэтому keyed Text показывает\n // базовую локаль без единого дополнительного вызова со стороны хоста.\n const localization = new SceneLocalization(document, scene, nodeViews, options.localization);\n wireCheckboxGroups(owner.nodes, nodeViews);\n wireSpineConnectors(owner.nodes, nodeViews);\n wireNodeReferences(owner.nodes, nodeViews, interaction);\n return { root: hostRoot, nodeViews, localization };\n}\n\nfunction wireSpineConnectors(nodes: readonly UINode[], nodeViews: ReadonlyMap<string, Container>): void {\n for (const node of nodes) {\n if (node.type !== \"spine\") continue;\n const view = nodeViews.get(node.id);\n if (!(view instanceof SpineNodeView)) continue;\n view.setConnectorBones((node.connectors ?? []).flatMap((connector) => {\n const target = nodeViews.get(connector.targetNodeId);\n return target === undefined ? [] : [{ ...connector, target }];\n }));\n }\n}\n\n/**\n * Разрешает все ссылки «нода → нода» в живые views: элементы item table и кнопки-стрелки пагинатора.\n * Та же форма, что у `wireSpineConnectors`: документ хранит id, а во что он превратился, знает только\n * собранная сцена, поэтому сами виды никогда не резолвят id. Один проход на все виды ссылок, чтобы\n * следующая не завела собственный обход с чуть другой областью видимости.\n *\n * Стрелки подключаются только в runtime-сцене: на authoring-канвасе контрол инертен, как и клик по\n * самой точке пагинатора. Вместимость таблицы, наоборот, видна и в редакторе — это не интерактивность.\n */\nfunction wireNodeReferences(nodes: readonly UINode[], nodeViews: ReadonlyMap<string, Container>, interaction: SceneInteractionMode): void {\n const arrowView = (nodeId: string | undefined): PaginationArrow | undefined => {\n const view = nodeId === undefined ? undefined : nodeViews.get(nodeId);\n return view instanceof ButtonNodeView || view instanceof StagedButtonNodeView ? view : undefined;\n };\n for (const node of nodes) {\n const view = nodeViews.get(node.id);\n if (node.type === \"item-table\" && view instanceof ItemTableNodeView) {\n view.setItems((node.items ?? []).map((itemId) => nodeViews.get(itemId)));\n } else if (node.type === \"pagination\" && view instanceof PaginationNodeView && interaction === \"runtime\") {\n view.setArrows({ previous: arrowView(node.prevButtonNodeId), next: arrowView(node.nextButtonNodeId) });\n } else if (node.type === \"page-group\" && view instanceof PageGroupNodeView && interaction === \"runtime\") {\n view.setArrows({ up: arrowView(node.pageUpButtonNodeId), down: arrowView(node.pageDownButtonNodeId) });\n }\n }\n}\n\n/**\n * Authored `group` gives sibling checkboxes radio-button behavior: checking one force-unchecks its\n * live group-mates (same `parentId`, same `group`), without touching the document. Runs once per\n * scene build; `CheckboxNodeView.forceCheck` never re-emits `onCheck`, so this can't recurse.\n */\nfunction wireCheckboxGroups(nodes: readonly UINode[], nodeViews: ReadonlyMap<string, Container>): void {\n const byGroup = new Map<string, CheckboxNodeView[]>();\n for (const node of nodes) {\n if (node.type !== \"checkbox\" || node.group === undefined) continue;\n const view = nodeViews.get(node.id);\n if (!(view instanceof CheckboxNodeView)) continue;\n const key = `${node.parentId ?? \"\"}::${node.group}`;\n const group = byGroup.get(key) ?? [];\n group.push(view);\n byGroup.set(key, group);\n }\n for (const group of byGroup.values()) {\n if (group.length < 2) continue;\n for (const view of group) {\n view.onCheck.connect((checked) => {\n if (!checked) return;\n for (const other of group) if (other !== view) other.forceCheck(false);\n });\n }\n }\n}\n\n/**\n * Applies a node's resolved transform, visibility, and content to an existing display object,\n * so editors can update views in place without rebuilding the scene tree.\n */\nexport function updateNodeView(view: Container, node: UINode, profile: LayoutProfileId, parentSize?: LayoutSize, parentNode?: UINode, effect?: EffectDefinition, spineReferenceFrame?: SpineReferenceFrame): void {\n if (isLayoutGroup(node)) applyLayoutGroup(view, node, profile, parentSize);\n if (!(view instanceof NodeView)) return;\n if (view instanceof SpineNodeView) view.setReferenceFrame(spineReferenceFrame);\n if (node.type === \"particle-emitter\" && effect !== undefined && isParticleEffect(effect) && \"syncEffect\" in view && typeof (view as { syncEffect?: unknown }).syncEffect === \"function\") (view as { syncEffect(effect: import(\"@pixi-ui-editor/schema\").ParticleEffectDefinition): void }).syncEffect(effect);\n if (parentNode !== undefined && isLayoutGroup(parentNode) && view.parent instanceof LayoutItemContainer) {\n applyLayoutItem(view.parent, node, parentNode, profile);\n } else if (parentNode !== undefined && parentNode.type === \"scroll-view\" && view.parent instanceof ScrollItemContainer) {\n const own = resolveProfileTransform(node, profile).transform;\n view.parent.sync(node, profile, { width: own.width, height: own.height });\n } else if (parentNode !== undefined && parentNode.type === \"page-group\" && view.parent instanceof PageItemContainer && parentSize !== undefined) {\n // A page is position-managed exactly like a layout/scroll item: it fills the group's own rectangle\n // (`parentSize`, the same value `buildSceneView` passes as `childSize`). Without this branch an\n // in-place update fell through to `view.update` and handed the page back its authored x/y and\n // anchors, so editing anything inside a page group knocked its pages out of place.\n view.parent.sync(node, profile, parentSize);\n } else {\n view.update(node, profile, parentSize);\n }\n}\n\n/** Previews a resolved editor rectangle without consulting content bounds or rebuilding the view. */\nexport function previewNodeView(view: Container, node: UINode, profile: LayoutProfileId, transform: UINode[\"transform\"]): void {\n if (isLayoutGroup(node)) applyLayoutGroup(view, node, profile, undefined, { width: transform.width, height: transform.height });\n if (view instanceof NodeView) view.preview(node, transform, resolveProfileTransform(node, profile).visible, profile);\n}\n\n/** Hosts call this from their own Application ticker; runtime never subscribes to Ticker.shared. */\nexport function updateParticleEmitters(root: Container, deltaSeconds: number): void {\n const registered = particleEmitterRegistry.get(root);\n if (registered !== undefined) {\n for (const emitter of registered) emitter.updateParticles(deltaSeconds);\n return;\n }\n // Backward-compatible fallback for hosts that assemble a display tree manually instead of using\n // buildSceneView. Built scenes always take the O(emitter count) registry path above.\n const visit = (view: Container): void => {\n if (view instanceof ParticleEmitterNodeView) view.updateParticles(deltaSeconds);\n for (const child of view.children) visit(child);\n };\n visit(root);\n}\n\n/** Lists the nodes a scene renders, including nodes of prefab definitions its prefab instances expand to. */\nexport function collectRenderedNodes(document: ProjectDocument, scene: Scene): UINode[] {\n return resolveOwnerNodeGraph(document, scene).nodes;\n}\n\nexport type PrefabViewConfiguration = Pick<Extract<UINode, { type: \"prefab-instance\" }>, \"propertyOverrides\" | \"locallyAddedNodes\"> & { instanceId?: string };\n\nfunction prefabScene(document: ProjectDocument, prefabId: string, configuration: PrefabViewConfiguration = {}): { document: ProjectDocument; sceneId: string; instanceId: string } {\n const prefab = document.prefabs.find((candidate) => candidate.id === prefabId);\n if (prefab === undefined) throw new Error(`Prefab '${prefabId}' does not exist in the project document.`);\n const width = Math.max(1, ...prefab.nodes.map((node) => Math.abs(node.transform.x) + Math.max(0, node.transform.width)));\n const height = Math.max(1, ...prefab.nodes.map((node) => Math.abs(node.transform.y) + Math.max(0, node.transform.height)));\n const instanceId = configuration.instanceId ?? createStableId();\n const instance: Extract<UINode, { type: \"prefab-instance\" }> = {\n id: instanceId, name: prefab.name, type: \"prefab-instance\", prefabId, parentId: null, children: [],\n visible: true, transform: { x: 0, y: 0, width, height, scaleX: 1, scaleY: 1, rotation: 0, anchorMinX: 0, anchorMaxX: 0, anchorMinY: 0, anchorMaxY: 0, pivotX: 0, pivotY: 0 },\n ...(configuration.propertyOverrides === undefined ? {} : { propertyOverrides: structuredClone(configuration.propertyOverrides) }),\n ...(configuration.locallyAddedNodes === undefined ? {} : { locallyAddedNodes: structuredClone(configuration.locallyAddedNodes) }),\n };\n const sceneId = createStableId();\n const viewport = { width, height };\n const scene: Scene = { id: sceneId, name: prefab.name, rootNodeIds: [instance.id], nodes: [instance], layout: { referenceViewports: { desktop: viewport, mobile: viewport }, preferredViewports: { desktop: viewport, mobile: viewport } } };\n return { document: { ...document, scenes: [...document.scenes, scene] }, sceneId, instanceId };\n}\n\n/** Builds a fresh runtime prefab instance without requiring it to already exist in a scene. */\nexport function buildPrefabView(document: ProjectDocument, prefabId: string, profile: LayoutProfileId, options: BuildSceneViewOptions, configuration: PrefabViewConfiguration = {}): SceneViewResult & { instanceId: string } {\n const synthetic = prefabScene(document, prefabId, configuration);\n return { ...buildSceneView(synthetic.document, synthetic.sceneId, profile, { ...options, clipToViewport: false }), instanceId: synthetic.instanceId };\n}\n\n/** Loads a prefab's assets and returns a fresh display tree suitable for dynamic game-code spawning. */\nexport async function loadPrefabView(document: ProjectDocument, prefabId: string, profile: LayoutProfileId, resolveFileUrl: FileUrlResolver, options: { interaction: SceneInteractionMode; ticker?: Ticker; localization?: SceneLocalizationOptions; assetCache?: SceneAssetCache }, configuration: PrefabViewConfiguration = {}): Promise<SceneViewResult & { instanceId: string }> {\n const synthetic = prefabScene(document, prefabId, configuration);\n return { ...await loadSceneView(synthetic.document, synthetic.sceneId, profile, resolveFileUrl, { ...options, clipToViewport: false }), instanceId: synthetic.instanceId };\n}\n\n/** Loads a scene's textures and Spine data, then builds its display tree in one call. */\nexport async function loadSceneView(\n document: ProjectDocument,\n sceneId: string,\n profile: LayoutProfileId,\n resolveFileUrl: FileUrlResolver,\n options: { interaction: SceneInteractionMode; ticker?: Ticker; localization?: SceneLocalizationOptions; clipToViewport?: boolean; assetCache?: SceneAssetCache },\n): Promise<SceneViewResult> {\n // Без assetCache каждый вызов начинает с пустых кэшей: для одиночной загрузки сцены это нормально, а вот\n // игровой код, который поднимает пресеты по одному, обязан передать собственный кэш — иначе один и тот же\n // скелет, атлас и текстура парсятся заново на каждую вьюху и дублируются в видеопамяти.\n const cache = options.assetCache;\n const [textures, spines, fonts, bitmapFonts] = await Promise.all([\n loadSceneTextures(document, sceneId, (asset) => (asset.type === \"image\" ? resolveFileUrl(asset.source.uri) : undefined), resolveFileUrl, cache?.textures, cache?.spritesheets, cache?.bitmapFonts),\n loadSceneSpines(document, sceneId, resolveFileUrl, cache?.spines),\n loadSceneFonts(document, sceneId, resolveFileUrl, cache?.fonts),\n loadSceneBitmapFonts(document, sceneId, resolveFileUrl, cache?.bitmapFonts),\n ]);\n return buildSceneView(document, sceneId, profile, { interaction: options.interaction, textures, spines, fonts, bitmapFonts, ticker: options.ticker, localization: options.localization, clipToViewport: options.clipToViewport });\n}\n"]}
@@ -2,6 +2,7 @@ import { type PageGroupNode } from "@pixi-ui-editor/schema";
2
2
  import { Container, Texture } from "pixi.js";
3
3
  import { PageItemContainer } from "../pageGroup.js";
4
4
  import { NodeView } from "./NodeView.js";
5
+ import type { PaginationArrow } from "./PaginationNodeView.js";
5
6
  export type { PageGroupNode };
6
7
  /**
7
8
  * Shows exactly one direct child ("page") at a time and hides the rest; each page fills the group's
@@ -38,5 +39,18 @@ export declare class PageGroupNodeView extends NodeView {
38
39
  get page(): number;
39
40
  /** External sync from game code (or the pagination widget's `onPageChange`): switches the visible page. */
40
41
  set page(value: number);
42
+ /**
43
+ * Подключает опциональные авторские кнопки-стрелки `pageUpButtonNodeId`/`pageDownButtonNodeId` —
44
+ * тот же приём, что `PaginationNodeView.setArrows` даёт пагинатору (ADR 0043): кнопки остаются
45
+ * обычными нодами сцены, виджет только подписывается на `onPress`. В отличие от пагинатора, здесь
46
+ * нет края диапазона, который гасил бы стрелку: это карусель — "up" с последней страницы
47
+ * возвращается на первую, "down" с первой уходит на последнюю, поэтому обе стрелки всегда активны.
48
+ */
49
+ setArrows(arrows: {
50
+ up?: PaginationArrow;
51
+ down?: PaginationArrow;
52
+ }): void;
53
+ /** Moves by `delta` pages, wrapping around both ends of the range — a carousel, not a clamp. */
54
+ private step;
41
55
  }
42
56
  //# sourceMappingURL=PageGroupNodeView.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PageGroupNodeView.d.ts","sourceRoot":"","sources":["../../src/views/PageGroupNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAe,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B;;;;;;;;;;;;;;GAcG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,WAAW,CAAS;IAE5B,YAAY,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAGlF;IAED,mHAAmH;IACnH,WAAW,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAKzC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAU/B;IAED,SAAS,CAAC,WAAW,IAAI,IAAI,CAE5B;IAED,OAAO,CAAC,eAAe;IAIvB,IAAI,SAAS,IAAI,MAAM,CAA8B;IAErD,IAAI,IAAI,IAAI,MAAM,CAA6B;IAE/C,2GAA2G;IAC3G,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAMrB;CACF"}
1
+ {"version":3,"file":"PageGroupNodeView.d.ts","sourceRoot":"","sources":["../../src/views/PageGroupNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAe,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B;;;;;;;;;;;;;;GAcG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,WAAW,CAAS;IAE5B,YAAY,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAGlF;IAED,mHAAmH;IACnH,WAAW,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAKzC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAU/B;IAED,SAAS,CAAC,WAAW,IAAI,IAAI,CAE5B;IAED,OAAO,CAAC,eAAe;IAIvB,IAAI,SAAS,IAAI,MAAM,CAA8B;IAErD,IAAI,IAAI,IAAI,MAAM,CAA6B;IAE/C,2GAA2G;IAC3G,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAMrB;IAED;;;;;;OAMG;IACH,SAAS,CAAC,MAAM,EAAE;QAAE,EAAE,CAAC,EAAE,eAAe,CAAC;QAAC,IAAI,CAAC,EAAE,eAAe,CAAA;KAAE,GAAG,IAAI,CAGxE;IAED,gGAAgG;IAChG,OAAO,CAAC,IAAI;CAKb"}
@@ -68,5 +68,23 @@ export class PageGroupNodeView extends NodeView {
68
68
  this.currentPage = next;
69
69
  this.applyVisibility();
70
70
  }
71
+ /**
72
+ * Подключает опциональные авторские кнопки-стрелки `pageUpButtonNodeId`/`pageDownButtonNodeId` —
73
+ * тот же приём, что `PaginationNodeView.setArrows` даёт пагинатору (ADR 0043): кнопки остаются
74
+ * обычными нодами сцены, виджет только подписывается на `onPress`. В отличие от пагинатора, здесь
75
+ * нет края диапазона, который гасил бы стрелку: это карусель — "up" с последней страницы
76
+ * возвращается на первую, "down" с первой уходит на последнюю, поэтому обе стрелки всегда активны.
77
+ */
78
+ setArrows(arrows) {
79
+ arrows.up?.onPress.connect(() => this.step(1));
80
+ arrows.down?.onPress.connect(() => this.step(-1));
81
+ }
82
+ /** Moves by `delta` pages, wrapping around both ends of the range — a carousel, not a clamp. */
83
+ step(delta) {
84
+ if (this.items.length === 0)
85
+ return;
86
+ const count = this.items.length;
87
+ this.page = (this.currentPage + delta + count) % count;
88
+ }
71
89
  }
72
90
  //# sourceMappingURL=PageGroupNodeView.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PageGroupNodeView.js","sourceRoot":"","sources":["../../src/views/PageGroupNodeView.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIzC;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,iBAAkB,SAAQ,QAAQ;IAC5B,KAAK,GAAgB,EAAE,CAAC;IACjC,WAAW,CAAS;IAE5B,YAAY,IAAmB,EAAE,QAAkD;QACjF,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,mHAAmH;IACnH,WAAW,CAAC,IAAuB;QACjC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAChC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC;IAC5C,CAAC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,IAAe;QACrB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC;QAC/C,MAAM,SAAS,GAAG,IAA8E,CAAC;QACjG,IAAI,OAAO,SAAS,CAAC,MAAM,KAAK,UAAU;YAAE,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;aAC3E,CAAC;YAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAAC,CAAC;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAChC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC;QAC1C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACpB,OAAO,KAAK,CAAC;IACf,CAAC;IAES,WAAW;QACnB,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,GAAG,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IACtF,CAAC;IAED,IAAI,SAAS,KAAa,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAErD,IAAI,IAAI,KAAa,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAE/C,2GAA2G;IAC3G,IAAI,IAAI,CAAC,KAAa;QACpB,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7E,IAAI,IAAI,KAAK,IAAI,CAAC,WAAW;YAAE,OAAO;QACtC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;CACF","sourcesContent":["import { type PageGroupNode, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { Container, Texture } from \"pixi.js\";\r\nimport { PageItemContainer } from \"../pageGroup.js\";\r\nimport { NodeView } from \"./NodeView.js\";\r\n\r\nexport type { PageGroupNode };\r\n\r\n/**\r\n * Shows exactly one direct child (\"page\") at a time and hides the rest; each page fills the group's\r\n * full resolved rectangle (`PageItemContainer`/`scene.ts`, the same \"children don't own their own\r\n * position\" contract a layout group or scroll-view has). Page order is simply hierarchy child order,\r\n * followed by any pages appended at runtime through `addPage`.\r\n *\r\n * This view never decides on its own when to switch pages — it is driven one-way by `setPageGroupPage`\r\n * from game code, or from the standalone `pagination` widget's `onPageChange` — the same relationship\r\n * `PaginationNodeView` has with the value it displays. No built-in swipe gesture or transition.\r\n *\r\n * Pages are ordinarily authored (one per document child), but the count is not required to be known at\r\n * authoring time: a growing dataset (e.g. a spin history list appended to during play) can start with\r\n * zero or a few authored pages and grow through `addPage` — the same \"the document is a starting point,\r\n * not a ceiling\" contract `ScrollViewNodeView.addScrollItem` already gives scroll-view content.\r\n */\r\nexport class PageGroupNodeView extends NodeView {\r\n private readonly items: Container[] = [];\r\n private currentPage: number;\r\n\r\n constructor(node: PageGroupNode, textures: ReadonlyMap<string, Texture> | undefined) {\r\n super(textures);\r\n this.currentPage = Math.max(0, Math.round(node.defaultPage));\r\n }\r\n\r\n /** Registers a direct child's wrapper in hierarchy order — called once per child while the scene tree is built. */\r\n addPageItem(item: PageItemContainer): void {\r\n this.addChild(item);\r\n const index = this.items.length;\r\n this.items.push(item);\r\n item.visible = index === this.currentPage;\r\n }\r\n\r\n /**\r\n * Appends a page built at runtime (e.g. via `buildPrefabView`/`loadPrefabView`, or any hand-built\r\n * `Container`) after the last one and fits it to the group's current resolved rectangle — a\r\n * `SceneViewport` root is resized through its own `resize(...)` (the same fit contract Preview and\r\n * export already rely on); anything else falls back to `Container.width`/`height`. Hidden until\r\n * switched to via `page`/`setPageGroupViewPage`. Returns the new page's index.\r\n */\r\n addPage(view: Container): number {\r\n const { width, height } = this.layoutRectangle;\r\n const resizable = view as Partial<{ resize: (size: { width: number; height: number }) => void }>;\r\n if (typeof resizable.resize === \"function\") resizable.resize({ width, height });\r\n else { view.width = width; view.height = height; }\r\n const index = this.items.length;\r\n this.items.push(view);\r\n view.visible = index === this.currentPage;\r\n this.addChild(view);\r\n return index;\r\n }\r\n\r\n protected syncContent(): void {\r\n this.applyVisibility();\r\n }\r\n\r\n private applyVisibility(): void {\r\n this.items.forEach((item, index) => { item.visible = index === this.currentPage; });\r\n }\r\n\r\n get pageCount(): number { return this.items.length; }\r\n\r\n get page(): number { return this.currentPage; }\r\n\r\n /** External sync from game code (or the pagination widget's `onPageChange`): switches the visible page. */\r\n set page(value: number) {\r\n if (this.items.length === 0) return;\r\n const next = Math.min(Math.max(0, Math.round(value)), this.items.length - 1);\r\n if (next === this.currentPage) return;\r\n this.currentPage = next;\r\n this.applyVisibility();\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"PageGroupNodeView.js","sourceRoot":"","sources":["../../src/views/PageGroupNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { type PageGroupNode, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { Container, Texture } from \"pixi.js\";\r\nimport { PageItemContainer } from \"../pageGroup.js\";\r\nimport { NodeView } from \"./NodeView.js\";\r\nimport type { PaginationArrow } from \"./PaginationNodeView.js\";\r\n\r\nexport type { PageGroupNode };\r\n\r\n/**\r\n * Shows exactly one direct child (\"page\") at a time and hides the rest; each page fills the group's\r\n * full resolved rectangle (`PageItemContainer`/`scene.ts`, the same \"children don't own their own\r\n * position\" contract a layout group or scroll-view has). Page order is simply hierarchy child order,\r\n * followed by any pages appended at runtime through `addPage`.\r\n *\r\n * This view never decides on its own when to switch pages — it is driven one-way by `setPageGroupPage`\r\n * from game code, or from the standalone `pagination` widget's `onPageChange` — the same relationship\r\n * `PaginationNodeView` has with the value it displays. No built-in swipe gesture or transition.\r\n *\r\n * Pages are ordinarily authored (one per document child), but the count is not required to be known at\r\n * authoring time: a growing dataset (e.g. a spin history list appended to during play) can start with\r\n * zero or a few authored pages and grow through `addPage` — the same \"the document is a starting point,\r\n * not a ceiling\" contract `ScrollViewNodeView.addScrollItem` already gives scroll-view content.\r\n */\r\nexport class PageGroupNodeView extends NodeView {\r\n private readonly items: Container[] = [];\r\n private currentPage: number;\r\n\r\n constructor(node: PageGroupNode, textures: ReadonlyMap<string, Texture> | undefined) {\r\n super(textures);\r\n this.currentPage = Math.max(0, Math.round(node.defaultPage));\r\n }\r\n\r\n /** Registers a direct child's wrapper in hierarchy order — called once per child while the scene tree is built. */\r\n addPageItem(item: PageItemContainer): void {\r\n this.addChild(item);\r\n const index = this.items.length;\r\n this.items.push(item);\r\n item.visible = index === this.currentPage;\r\n }\r\n\r\n /**\r\n * Appends a page built at runtime (e.g. via `buildPrefabView`/`loadPrefabView`, or any hand-built\r\n * `Container`) after the last one and fits it to the group's current resolved rectangle — a\r\n * `SceneViewport` root is resized through its own `resize(...)` (the same fit contract Preview and\r\n * export already rely on); anything else falls back to `Container.width`/`height`. Hidden until\r\n * switched to via `page`/`setPageGroupViewPage`. Returns the new page's index.\r\n */\r\n addPage(view: Container): number {\r\n const { width, height } = this.layoutRectangle;\r\n const resizable = view as Partial<{ resize: (size: { width: number; height: number }) => void }>;\r\n if (typeof resizable.resize === \"function\") resizable.resize({ width, height });\r\n else { view.width = width; view.height = height; }\r\n const index = this.items.length;\r\n this.items.push(view);\r\n view.visible = index === this.currentPage;\r\n this.addChild(view);\r\n return index;\r\n }\r\n\r\n protected syncContent(): void {\r\n this.applyVisibility();\r\n }\r\n\r\n private applyVisibility(): void {\r\n this.items.forEach((item, index) => { item.visible = index === this.currentPage; });\r\n }\r\n\r\n get pageCount(): number { return this.items.length; }\r\n\r\n get page(): number { return this.currentPage; }\r\n\r\n /** External sync from game code (or the pagination widget's `onPageChange`): switches the visible page. */\r\n set page(value: number) {\r\n if (this.items.length === 0) return;\r\n const next = Math.min(Math.max(0, Math.round(value)), this.items.length - 1);\r\n if (next === this.currentPage) return;\r\n this.currentPage = next;\r\n this.applyVisibility();\r\n }\r\n\r\n /**\r\n * Подключает опциональные авторские кнопки-стрелки `pageUpButtonNodeId`/`pageDownButtonNodeId` —\r\n * тот же приём, что `PaginationNodeView.setArrows` даёт пагинатору (ADR 0043): кнопки остаются\r\n * обычными нодами сцены, виджет только подписывается на `onPress`. В отличие от пагинатора, здесь\r\n * нет края диапазона, который гасил бы стрелку: это карусель — \"up\" с последней страницы\r\n * возвращается на первую, \"down\" с первой уходит на последнюю, поэтому обе стрелки всегда активны.\r\n */\r\n setArrows(arrows: { up?: PaginationArrow; down?: PaginationArrow }): void {\r\n arrows.up?.onPress.connect(() => this.step(1));\r\n arrows.down?.onPress.connect(() => this.step(-1));\r\n }\r\n\r\n /** Moves by `delta` pages, wrapping around both ends of the range — a carousel, not a clamp. */\r\n private step(delta: number): void {\r\n if (this.items.length === 0) return;\r\n const count = this.items.length;\r\n this.page = (this.currentPage + delta + count) % count;\r\n }\r\n}\r\n"]}
@@ -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,EAsBlO;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,CA2BlG;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,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,CAgClG;CACF"}
@@ -32,14 +32,20 @@ export class SpineNodeView extends NodeView {
32
32
  //
33
33
  // An authoring view starts at the node's own autoplay setting, so a scene full of paused
34
34
  // skeletons subscribes to no ticker at all — the editor toggles `autoUpdate` from there.
35
- // A runtime view always keeps it on: it carries no track until game code starts an animation,
36
- // and that animation must then advance without the game touching `autoUpdate` itself.
35
+ // A runtime view always keeps it on: an animation game code starts later must advance without
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
- // Runtime leaves a disabled animation without a track, ready for game code to start on an event.
40
- // Authoring still creates the track so its frame scrubber can inspect either initial state.
41
- if ((autoplay || initializeForAuthoring) && animation !== undefined && skeletonData.findAnimation(animation) !== null)
42
- spine.state.setAnimation(0, animation, loop).timeScale = animationSpeed;
39
+ // A configured animation always gets a track, posed to its own first frame a skeleton left
40
+ // without one instead renders Spine's setup/bind pose, which is almost never the intended "static"
41
+ // look and was reported as a visibly broken/twitching pose (still-running physics/IK constraints
42
+ // have nothing to settle against without a driving animation). When not autoplaying, `timeScale`
43
+ // is frozen at 0 so the track holds frame 0 forever without playing; game code starting a real
44
+ // animation later just calls `state.setAnimation(...)` itself, same as before.
45
+ if (animation !== undefined && skeletonData.findAnimation(animation) !== null) {
46
+ const playing = autoplay || initializeForAuthoring;
47
+ spine.state.setAnimation(0, animation, loop).timeScale = playing ? animationSpeed : 0;
48
+ }
43
49
  this.setContent(spine);
44
50
  }
45
51
  /** Runtime switch used by game code; authored connector definitions are inactive by default. */
@@ -187,15 +193,20 @@ export class SpineNodeView extends NodeView {
187
193
  const track = this.content.state.tracks[0];
188
194
  const animationChanged = track?.animation?.name !== settings.animation;
189
195
  const loopChanged = track !== null && track !== undefined && track.loop !== settings.loop;
190
- if (settings.animation === undefined || (!settings.autoplay && !this.initializeForAuthoring)) {
196
+ // Same "always a track, frozen at frame 0 unless actually playing" contract as the constructor:
197
+ // a static (non-autoplay) skeleton stays posed to its configured animation's first frame,
198
+ // never Spine's setup/bind pose.
199
+ const playing = settings.autoplay || this.initializeForAuthoring;
200
+ const desiredTimeScale = playing ? settings.animationSpeed : 0;
201
+ if (settings.animation === undefined) {
191
202
  if (track !== null && track !== undefined)
192
203
  this.content.state.clearTrack(0);
193
204
  }
194
205
  else if ((animationChanged || loopChanged) && this.content.skeleton.data.findAnimation(settings.animation) !== null) {
195
- this.content.state.setAnimation(0, settings.animation, settings.loop).timeScale = settings.animationSpeed;
206
+ this.content.state.setAnimation(0, settings.animation, settings.loop).timeScale = desiredTimeScale;
196
207
  }
197
208
  else if (track !== null && track !== undefined) {
198
- track.timeScale = settings.animationSpeed;
209
+ track.timeScale = desiredTimeScale;
199
210
  }
200
211
  }
201
212
  const fit = fitSpineToTransform(this.content.skeleton.data, transform, this.referenceFrame);
@@ -1 +1 @@
1
- {"version":3,"file":"SpineNodeView.js","sourceRoot":"","sources":["../../src/views/SpineNodeView.ts"],"names":[],"mappings":"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","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 };\n\nfunction resolveConnectorPart(binding: RuntimeConnectorBinding): Pick<SpineConnector, \"partType\" | \"partName\"> | undefined {\n if ((binding.partType === \"bone\" || binding.partType === \"slot\") && typeof binding.partName === \"string\" && binding.partName.length > 0) {\n return { partType: binding.partType, partName: binding.partName };\n }\n const boneName = \"boneName\" in binding ? binding.boneName : undefined;\n return typeof boneName === \"string\" && boneName.length > 0 ? { partType: \"bone\", partName: boneName } : undefined;\n}\n\nexport class SpineNodeView extends NodeView {\n private referenceFrame: SpineReferenceFrame | undefined;\n private readonly initializeForAuthoring: boolean;\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\";\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();\n this.referenceFrame = referenceFrame;\n this.initializeForAuthoring = initializeForAuthoring;\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: it carries no track until game code starts an animation,\r\n // and that animation must then advance without the game touching `autoUpdate` itself.\r\n const spine = new Spine({ skeletonData, autoUpdate: initializeForAuthoring ? autoplay : true, ...(ticker === undefined ? {} : { ticker }) });\n spine.afterUpdateWorldTransforms = () => this.refreshConnectorBones();\n // Runtime leaves a disabled animation without a track, ready for game code to start on an event.\r\n // Authoring still creates the track so its frame scrubber can inspect either initial state.\r\n if ((autoplay || initializeForAuthoring) && animation !== undefined && skeletonData.findAnimation(animation) !== null) spine.state.setAnimation(0, animation, loop).timeScale = animationSpeed;\r\n this.setContent(spine);\n }\n\n /** Runtime switch used by game code; authored connector definitions are inactive by default. */\n get activeConnectorBones(): boolean {\n return this.connectorBonesActive;\n }\n\n set activeConnectorBones(active: boolean) {\n this.setConnectorBonesActive(active);\n }\n\n /** Replaces the scene-resolved connector targets, preserving the current active state. */\n setConnectorBones(bindings: readonly RuntimeConnectorBinding[]): void {\n const wasActive = this.connectorBonesActive;\n if (wasActive) this.setConnectorBonesActive(false);\n this.connectorBindings = [...bindings];\n if (wasActive) this.setConnectorBonesActive(true);\n }\n\n setConnectorBonesActive(active: boolean): void {\n if (active === this.connectorBonesActive) return;\n this.connectorBonesActive = active;\n if (!active) {\n this.restoreConnectorTargets();\n return;\n }\n\n const spine = this.getSpine();\n if (spine === undefined) return;\n for (const binding of this.connectorBindings) {\n const part = resolveConnectorPart(binding);\n if (part === undefined) continue;\n if (part.partType === \"bone\" ? spine.skeleton.findBone(part.partName) === null : spine.skeleton.findSlot(part.partName) === null) continue;\n const parent = binding.target.parent;\n if (parent === null || parent.destroyed) continue;\n const host = new Container();\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 };\n // The host genuinely belongs to the Spine view, so the authored skeleton offset inherits the\n // visual Spine fit. refreshConnectorBones compensates the host's linear transform only, so the\n // target keeps its original UI size/orientation.\n spine.addChild(host);\n host.addChild(binding.target);\n this.activeConnectors.push(snapshot);\n }\n this.refreshConnectorBones();\n }\n\n /** Reapplies bone matrices and the target's required zero local transform. */\n refreshConnectorBones(): void {\n const spine = this.getSpine();\n if (spine === undefined) return;\n for (const connector of this.activeConnectors) {\n const slot = connector.partType === \"slot\" ? spine.skeleton.findSlot(connector.partName) : null;\n const bone = connector.partType === \"bone\" ? spine.skeleton.findBone(connector.partName) : slot?.bone;\n if (bone === null || bone === undefined || connector.parent.destroyed) continue;\n // A slot itself has no transform beyond its bone, but a region attachment does: Spine stores\n // its authored Point offset in attachment.x/y. Project that attachment origin, otherwise\n // changing Point from e.g. -650 to -850 moves the visual attachment but not the UI connector.\n const attachment = slot?.attachment;\n let spineX = bone.worldX;\n let spineY = bone.worldY;\n if (attachment instanceof PointAttachment) {\n const point = attachment.computeWorldPosition(bone, new Vector2());\n spineX = point.x;\n spineY = point.y;\n } else if (attachment instanceof RegionAttachment) {\n spineX += attachment.x * bone.a + attachment.y * bone.b;\n spineY += attachment.x * bone.c + attachment.y * bone.d;\n }\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 ));\n connector.host.visible = slot === null\n || (spine.skeleton.drawOrder.includes(slot) && slot.attachment !== null && spine.alpha > 0 && spine.skeleton.color.a * slot.color.a > 0);\n connector.target.position.set(0, 0);\n }\n }\n\n private restoreConnectorTargets(): void {\n for (const connector of this.activeConnectors) {\n const { target, parent } = connector;\n if (!target.destroyed && !parent.destroyed) {\n const index = Math.min(connector.index, parent.children.length);\n parent.addChildAt(target, index);\n target.position.set(connector.position.x, connector.position.y);\n target.scale.set(connector.scale.x, connector.scale.y);\n target.skew.set(connector.skew.x, connector.skew.y);\n target.pivot.set(connector.pivot.x, connector.pivot.y);\n target.rotation = connector.rotation;\n }\n connector.host.destroy({ children: false });\n }\n this.activeConnectors = [];\n }\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 (this.content instanceof Spine) {\n if (node.type === \"spine\") {\n const settings = resolveSpineSettings(node, profile);\n const track = this.content.state.tracks[0];\n const animationChanged = track?.animation?.name !== settings.animation;\n const loopChanged = track !== null && track !== undefined && track.loop !== settings.loop;\n if (settings.animation === undefined || (!settings.autoplay && !this.initializeForAuthoring)) {\n if (track !== null && track !== undefined) this.content.state.clearTrack(0);\n } else if ((animationChanged || loopChanged) && this.content.skeleton.data.findAnimation(settings.animation) !== null) {\n this.content.state.setAnimation(0, settings.animation, settings.loop).timeScale = settings.animationSpeed;\n } else if (track !== null && track !== undefined) {\n track.timeScale = settings.animationSpeed;\n }\n }\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":"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","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 (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"]}
@@ -74,6 +74,8 @@ export declare class TextNodeView extends NodeView {
74
74
  /** Последний применённый прямоугольник и стиль — их же переиспользует инкрементальный `setText`. */
75
75
  private lastTransform?;
76
76
  private lastStyle?;
77
+ /** `Text.textCase` from the last synced node — `setText`'s incremental path re-applies it without waiting for a full `syncContent`. */
78
+ private textCase?;
77
79
  constructor(text: string, fonts?: ReadonlyMap<string, string> | undefined);
78
80
  protected syncContent(node: UINode, transform: UINode["transform"], profile: LayoutProfileId): void;
79
81
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"basic.d.ts","sourceRoot":"","sources":["../../src/views/basic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,aAAa,EAAE,KAAK,eAAe,EAA2C,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC7J,OAAO,EAAc,SAAS,EAA2C,OAAO,EAAE,MAAM,SAAS,CAAC;AAClG,OAAO,EAAE,QAAQ,EAAE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAGpE,qBAAa,iBAAkB,SAAQ,QAAQ;IAC7C,SAAS,CAAC,WAAW,IAAI,IAAI,CAAG;CACjC;AAED,iFAAiF;AACjF,qBAAa,YAAa,SAAQ,QAAQ;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;IAE5C,cAMC;IAED,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAGxE;CACF;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,oBAAqB,SAAQ,QAAQ;IAChD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;IACnD,8FAA8F;IAC9F,OAAO,CAAC,cAAc,CAAC,CAAS;IAChC,OAAO,CAAC,eAAe,CAAK;IAE5B,YAAY,WAAW,EAAE,oBAAoB,EAG5C;IAED,2GAA2G;IAC3G,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAG5C;IAED,OAAO,CAAC,YAAY;IAQpB,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIxC;CACF;AAED,yHAAyH;AACzH,qBAAa,mBAAoB,SAAQ,QAAQ;IAC/C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmB;IACjD,OAAO,CAAC,UAAU,CAAC,CAAS;IAE5B,YAAY,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAK7D;IAED,IAAI,YAAY,IAAI,SAAS,CAA+B;IAE5D,cAAc,CAAC,CAAC,SAAS,SAAS,EAAE,EAAE,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAE1D;IAED,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAUxE;CACF;AAED;;;;;;;GAOG;AACH,qBAAa,aAAc,SAAQ,QAAQ;IACzC,YAAY,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,SAAS,CAAC,EAAE,aAAa,EAIrH;IAED,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAOlC,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CA+BxE;IAED;;;;OAIG;IACH,gBAAgB,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAM/C;CAEF;AAED,qBAAa,YAAa,SAAQ,QAAQ;IAUd,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IATjD;;;OAGG;IACH,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,oGAAoG;IACpG,OAAO,CAAC,aAAa,CAAC,CAAsB;IAC5C,OAAO,CAAC,SAAS,CAAC,CAAsB;IAExC,YAAY,IAAI,EAAE,MAAM,EAAmB,KAAK,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,YAAA,EAG7E;IAED,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CAUlG;IAED;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IA8BxB;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAI1B;IAED,4FAA4F;IAC5F,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAG/C;IAED;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAG7C;IAED;;;;;;;OAOG;IACH,eAAe,IAAI,OAAO,CAQzB;IAED,OAAO,CAAC,KAAK;CAUd;AAED;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,QAAQ;IAKlC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IAJnC,OAAO,CAAC,aAAa,CAAC,CAAsB;IAC5C,OAAO,CAAC,SAAS,CAAuC;IACxD,OAAO,CAAC,iBAAiB,CAAsC;IAE/D,YAA6B,KAAK,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,YAAA,EAG/D;IAED,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAgBxE;IAED;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAI1B;IAED;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IA6BxB;;;;;;;;OAQG;IACH,OAAO,CAAC,KAAK;CASd;AAED;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,QAAQ;IAClD,YAAY,QAAQ,EAAE,OAAO,EAG5B;IAED,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAEzE;CACF"}
1
+ {"version":3,"file":"basic.d.ts","sourceRoot":"","sources":["../../src/views/basic.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { applyTextCase } from "@pixi-ui-editor/schema";
1
2
  import { BitmapText, Container, Graphics, NineSliceSprite, Sprite, Text } from "pixi.js";
2
3
  import { NodeView } from "./NodeView.js";
3
4
  import { resolveTextStyle } from "../layout.js";
@@ -187,6 +188,8 @@ export class TextNodeView extends NodeView {
187
188
  /** Последний применённый прямоугольник и стиль — их же переиспользует инкрементальный `setText`. */
188
189
  lastTransform;
189
190
  lastStyle;
191
+ /** `Text.textCase` from the last synced node — `setText`'s incremental path re-applies it without waiting for a full `syncContent`. */
192
+ textCase;
190
193
  constructor(text, fonts) {
191
194
  super();
192
195
  this.fonts = fonts;
@@ -195,7 +198,8 @@ export class TextNodeView extends NodeView {
195
198
  syncContent(node, transform, profile) {
196
199
  if (node.type !== "text" || !(this.content instanceof Text))
197
200
  return;
198
- const text = this.localizedText ?? node.text;
201
+ this.textCase = node.textCase;
202
+ const text = applyTextCase(this.localizedText ?? node.text, this.textCase);
199
203
  if (this.content.text !== text)
200
204
  this.content.text = text;
201
205
  const style = resolveTextStyle(node, profile);
@@ -255,9 +259,12 @@ export class TextNodeView extends NodeView {
255
259
  * сохраняет identity, поэтому смена локали не трогает ни сцену, ни GPU-ресурсы стиля.
256
260
  */
257
261
  setText(text) {
258
- if (!(this.content instanceof Text) || this.content.text === text)
262
+ if (!(this.content instanceof Text))
259
263
  return;
260
- this.content.text = text;
264
+ const cased = applyTextCase(text, this.textCase);
265
+ if (this.content.text === cased)
266
+ return;
267
+ this.content.text = cased;
261
268
  this.align();
262
269
  }
263
270
  /** `undefined` возвращает ноду к авторской строке при следующей синхронизации документа. */
@@ -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, type SceneInteractionMode } 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/**\r\n * Multiplies one opacity into its whole child subtree, the same contract as Unity's `CanvasGroup.alpha`:\r\n * PixiJS already folds a container's `alpha` into every descendant's `worldAlpha`, so this costs one\r\n * multiply per object in a traversal that happens anyway — no offscreen render pass, and a fade over an\r\n * arbitrarily large subtree stays a single number written once per frame. Overlapping children therefore\r\n * show through each other at intermediate values, exactly as they do under a Unity `CanvasGroup`; true\r\n * flattened group opacity would need an `AlphaFilter` and its per-frame render texture, which is\r\n * deliberately not what this node is for.\r\n *\r\n * At zero opacity a runtime scene also stops rendering and hit-testing the subtree outright — the\r\n * `blocksRaycasts` half of `CanvasGroup`, without which a fully faded-out screen keeps eating the\r\n * pointer input of the one faded in over it. Both are skipped while authoring: `eventMode = \"none\"` on\r\n * the view itself would drop the node and its children out of editor selection, and hit testing stays\r\n * `NodeView`'s responsibility.\r\n */\r\nexport class OpacityGroupNodeView extends NodeView {\r\n private readonly interaction: SceneInteractionMode;\r\n /** Transient runtime override; `undefined` keeps the authored `opacity` from the document. */\r\n private runtimeOpacity?: number;\r\n private authoredOpacity = 1;\r\n\r\n constructor(interaction: SceneInteractionMode) {\r\n super();\r\n this.interaction = interaction;\r\n }\r\n\r\n /** Drives a fade from game code without touching the document; `undefined` restores the authored value. */\r\n setOpacity(opacity: number | undefined): void {\r\n this.runtimeOpacity = opacity === undefined ? undefined : Math.min(1, Math.max(0, opacity));\r\n this.applyOpacity(this.runtimeOpacity ?? this.authoredOpacity);\r\n }\r\n\r\n private applyOpacity(opacity: number): void {\r\n this.alpha = opacity;\r\n if (this.interaction === \"authoring\") return;\r\n const hidden = opacity <= 0;\r\n this.renderable = !hidden;\r\n this.eventMode = hidden ? \"none\" : \"passive\";\r\n }\r\n\r\n protected syncContent(node: UINode): void {\r\n if (node.type !== \"opacity-group\") return;\r\n this.authoredOpacity = node.opacity;\r\n this.applyOpacity(this.runtimeOpacity ?? this.authoredOpacity);\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);\r\n else graphics.fill(0x4a5568).stroke({ width: 1, color: 0x94a3b8 });\r\n }\r\n this.content!.alpha = node.opacity ?? 1;\r\n if (this.content instanceof Sprite || this.content instanceof NineSliceSprite) this.content.tint = node.tint ?? 0xffffff;\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\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 * Updates the rendered bitmap text without reapplying the node transform. This lets game code\r\n * refresh counters that are temporarily attached to a Spine connector without dislodging them.\r\n */\r\n setText(text: string): void {\r\n if (!(this.content instanceof BitmapText) || this.content.text === text) return;\r\n this.content.text = text;\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 { applyTextCase, type BitmapTextNode, type LayoutPadding, type LayoutProfileId, type TextCase, 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, type SceneInteractionMode } 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/**\r\n * Multiplies one opacity into its whole child subtree, the same contract as Unity's `CanvasGroup.alpha`:\r\n * PixiJS already folds a container's `alpha` into every descendant's `worldAlpha`, so this costs one\r\n * multiply per object in a traversal that happens anyway — no offscreen render pass, and a fade over an\r\n * arbitrarily large subtree stays a single number written once per frame. Overlapping children therefore\r\n * show through each other at intermediate values, exactly as they do under a Unity `CanvasGroup`; true\r\n * flattened group opacity would need an `AlphaFilter` and its per-frame render texture, which is\r\n * deliberately not what this node is for.\r\n *\r\n * At zero opacity a runtime scene also stops rendering and hit-testing the subtree outright — the\r\n * `blocksRaycasts` half of `CanvasGroup`, without which a fully faded-out screen keeps eating the\r\n * pointer input of the one faded in over it. Both are skipped while authoring: `eventMode = \"none\"` on\r\n * the view itself would drop the node and its children out of editor selection, and hit testing stays\r\n * `NodeView`'s responsibility.\r\n */\r\nexport class OpacityGroupNodeView extends NodeView {\r\n private readonly interaction: SceneInteractionMode;\r\n /** Transient runtime override; `undefined` keeps the authored `opacity` from the document. */\r\n private runtimeOpacity?: number;\r\n private authoredOpacity = 1;\r\n\r\n constructor(interaction: SceneInteractionMode) {\r\n super();\r\n this.interaction = interaction;\r\n }\r\n\r\n /** Drives a fade from game code without touching the document; `undefined` restores the authored value. */\r\n setOpacity(opacity: number | undefined): void {\r\n this.runtimeOpacity = opacity === undefined ? undefined : Math.min(1, Math.max(0, opacity));\r\n this.applyOpacity(this.runtimeOpacity ?? this.authoredOpacity);\r\n }\r\n\r\n private applyOpacity(opacity: number): void {\r\n this.alpha = opacity;\r\n if (this.interaction === \"authoring\") return;\r\n const hidden = opacity <= 0;\r\n this.renderable = !hidden;\r\n this.eventMode = hidden ? \"none\" : \"passive\";\r\n }\r\n\r\n protected syncContent(node: UINode): void {\r\n if (node.type !== \"opacity-group\") return;\r\n this.authoredOpacity = node.opacity;\r\n this.applyOpacity(this.runtimeOpacity ?? this.authoredOpacity);\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);\r\n else graphics.fill(0x4a5568).stroke({ width: 1, color: 0x94a3b8 });\r\n }\r\n this.content!.alpha = node.opacity ?? 1;\r\n if (this.content instanceof Sprite || this.content instanceof NineSliceSprite) this.content.tint = node.tint ?? 0xffffff;\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\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 /** `Text.textCase` from the last synced node — `setText`'s incremental path re-applies it without waiting for a full `syncContent`. */\r\n private textCase?: TextCase;\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 this.textCase = node.textCase;\r\n const text = applyTextCase(this.localizedText ?? node.text, this.textCase);\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)) return;\r\n const cased = applyTextCase(text, this.textCase);\r\n if (this.content.text === cased) return;\r\n this.content.text = cased;\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 * Updates the rendered bitmap text without reapplying the node transform. This lets game code\r\n * refresh counters that are temporarily attached to a Spine connector without dislodging them.\r\n */\r\n setText(text: string): void {\r\n if (!(this.content instanceof BitmapText) || this.content.text === text) return;\r\n this.content.text = text;\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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixi-ui-editor/runtime-pixi",
3
- "version": "0.11.0",
3
+ "version": "0.12.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.11.0"
33
+ "@pixi-ui-editor/schema": "0.12.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^26.2.0"