@pixi-ui-editor/runtime-pixi 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/fonts.d.ts +5 -0
- package/dist/assets/fonts.d.ts.map +1 -0
- package/dist/assets/fonts.js +50 -0
- package/dist/assets/fonts.js.map +1 -0
- package/dist/assets/sounds.d.ts +14 -0
- package/dist/assets/sounds.d.ts.map +1 -0
- package/dist/assets/sounds.js +156 -0
- package/dist/assets/sounds.js.map +1 -0
- package/dist/assets/spine.d.ts +18 -0
- package/dist/assets/spine.d.ts.map +1 -0
- package/dist/assets/spine.js +82 -0
- package/dist/assets/spine.js.map +1 -0
- package/dist/assets/textures.d.ts +15 -0
- package/dist/assets/textures.d.ts.map +1 -0
- package/dist/assets/textures.js +86 -0
- package/dist/assets/textures.js.map +1 -0
- package/dist/controls.d.ts +19 -0
- package/dist/controls.d.ts.map +1 -0
- package/dist/controls.js +55 -0
- package/dist/controls.js.map +1 -0
- package/dist/document.d.ts +8 -0
- package/dist/document.d.ts.map +1 -0
- package/dist/document.js +22 -0
- package/dist/document.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +315 -0
- package/dist/index.test.js.map +1 -0
- package/dist/layout.d.ts +32 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +43 -0
- package/dist/layout.js.map +1 -0
- package/dist/layoutGroups.d.ts +31 -0
- package/dist/layoutGroups.d.ts.map +1 -0
- package/dist/layoutGroups.js +139 -0
- package/dist/layoutGroups.js.map +1 -0
- package/dist/particles.d.ts +139 -0
- package/dist/particles.d.ts.map +1 -0
- package/dist/particles.js +275 -0
- package/dist/particles.js.map +1 -0
- package/dist/particles.test.d.ts +2 -0
- package/dist/particles.test.d.ts.map +1 -0
- package/dist/particles.test.js +210 -0
- package/dist/particles.test.js.map +1 -0
- package/dist/scene.d.ts +41 -0
- package/dist/scene.d.ts.map +1 -0
- package/dist/scene.js +147 -0
- package/dist/scene.js.map +1 -0
- package/dist/scrollView.d.ts +28 -0
- package/dist/scrollView.d.ts.map +1 -0
- package/dist/scrollView.js +38 -0
- package/dist/scrollView.js.map +1 -0
- package/dist/test.setup.d.ts +2 -0
- package/dist/test.setup.d.ts.map +1 -0
- package/dist/test.setup.js +6 -0
- package/dist/test.setup.js.map +1 -0
- package/dist/views/ButtonNodeView.d.ts +36 -0
- package/dist/views/ButtonNodeView.d.ts.map +1 -0
- package/dist/views/ButtonNodeView.js +104 -0
- package/dist/views/ButtonNodeView.js.map +1 -0
- package/dist/views/InputNodeView.d.ts +36 -0
- package/dist/views/InputNodeView.d.ts.map +1 -0
- package/dist/views/InputNodeView.js +170 -0
- package/dist/views/InputNodeView.js.map +1 -0
- package/dist/views/NodeView.d.ts +53 -0
- package/dist/views/NodeView.d.ts.map +1 -0
- package/dist/views/NodeView.js +86 -0
- package/dist/views/NodeView.js.map +1 -0
- package/dist/views/ParticleEmitterNodeView.d.ts +26 -0
- package/dist/views/ParticleEmitterNodeView.d.ts.map +1 -0
- package/dist/views/ParticleEmitterNodeView.js +101 -0
- package/dist/views/ParticleEmitterNodeView.js.map +1 -0
- package/dist/views/ParticleEmitterNodeView.test.d.ts +2 -0
- package/dist/views/ParticleEmitterNodeView.test.d.ts.map +1 -0
- package/dist/views/ParticleEmitterNodeView.test.js +148 -0
- package/dist/views/ParticleEmitterNodeView.test.js.map +1 -0
- package/dist/views/ScrollViewNodeView.d.ts +29 -0
- package/dist/views/ScrollViewNodeView.d.ts.map +1 -0
- package/dist/views/ScrollViewNodeView.js +67 -0
- package/dist/views/ScrollViewNodeView.js.map +1 -0
- package/dist/views/SpineNodeView.d.ts +8 -0
- package/dist/views/SpineNodeView.d.ts.map +1 -0
- package/dist/views/SpineNodeView.js +30 -0
- package/dist/views/SpineNodeView.js.map +1 -0
- package/dist/views/ValueControlNodeViews.d.ts +37 -0
- package/dist/views/ValueControlNodeViews.d.ts.map +1 -0
- package/dist/views/ValueControlNodeViews.js +179 -0
- package/dist/views/ValueControlNodeViews.js.map +1 -0
- package/dist/views/basic.d.ts +29 -0
- package/dist/views/basic.d.ts.map +1 -0
- package/dist/views/basic.js +92 -0
- package/dist/views/basic.js.map +1 -0
- package/dist/views/createNodeView.d.ts +13 -0
- package/dist/views/createNodeView.d.ts.map +1 -0
- package/dist/views/createNodeView.js +89 -0
- package/dist/views/createNodeView.js.map +1 -0
- package/package.json +36 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type { SkeletonData } from "@esotericsoftware/spine-pixi-v8";
|
|
2
|
+
export type { Sound } from "@pixi/sound";
|
|
3
|
+
export * from "./document.js";
|
|
4
|
+
export * from "./layout.js";
|
|
5
|
+
export * from "./layoutGroups.js";
|
|
6
|
+
export * from "./scrollView.js";
|
|
7
|
+
export * from "./views/NodeView.js";
|
|
8
|
+
export { ButtonNodeView } from "./views/ButtonNodeView.js";
|
|
9
|
+
export { InputNodeView } from "./views/InputNodeView.js";
|
|
10
|
+
export { ScrollViewNodeView } from "./views/ScrollViewNodeView.js";
|
|
11
|
+
export { ProgressBarNodeView, SliderNodeView } from "./views/ValueControlNodeViews.js";
|
|
12
|
+
export { ParticleEmitterNodeView } from "./views/ParticleEmitterNodeView.js";
|
|
13
|
+
export * from "./particles.js";
|
|
14
|
+
export { collectNodeAssetIds } from "./views/createNodeView.js";
|
|
15
|
+
export type { BuildSceneViewOptions } from "./scene.js";
|
|
16
|
+
export { buildSceneView, collectRenderedNodes, previewNodeView, updateNodeView, updateParticleEmitters, loadSceneView } from "./scene.js";
|
|
17
|
+
export * from "./controls.js";
|
|
18
|
+
export * from "./assets/textures.js";
|
|
19
|
+
export * from "./assets/spine.js";
|
|
20
|
+
export * from "./assets/fonts.js";
|
|
21
|
+
export * from "./assets/sounds.js";
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpE,YAAY,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,YAAY,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,eAAe,EAAE,cAAc,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC1I,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export * from "./document.js";
|
|
2
|
+
export * from "./layout.js";
|
|
3
|
+
export * from "./layoutGroups.js";
|
|
4
|
+
export * from "./scrollView.js";
|
|
5
|
+
export * from "./views/NodeView.js";
|
|
6
|
+
export { ButtonNodeView } from "./views/ButtonNodeView.js";
|
|
7
|
+
export { InputNodeView } from "./views/InputNodeView.js";
|
|
8
|
+
export { ScrollViewNodeView } from "./views/ScrollViewNodeView.js";
|
|
9
|
+
export { ProgressBarNodeView, SliderNodeView } from "./views/ValueControlNodeViews.js";
|
|
10
|
+
export { ParticleEmitterNodeView } from "./views/ParticleEmitterNodeView.js";
|
|
11
|
+
export * from "./particles.js";
|
|
12
|
+
export { collectNodeAssetIds } from "./views/createNodeView.js";
|
|
13
|
+
export { buildSceneView, collectRenderedNodes, previewNodeView, updateNodeView, updateParticleEmitters, loadSceneView } from "./scene.js";
|
|
14
|
+
export * from "./controls.js";
|
|
15
|
+
export * from "./assets/textures.js";
|
|
16
|
+
export * from "./assets/spine.js";
|
|
17
|
+
export * from "./assets/fonts.js";
|
|
18
|
+
export * from "./assets/sounds.js";
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,eAAe,EAAE,cAAc,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC1I,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { serializeProjectDocument } from "@pixi-ui-editor/schema";
|
|
4
|
+
import { Sprite, Texture } from "pixi.js";
|
|
5
|
+
import { TextureAtlas } from "@esotericsoftware/spine-pixi-v8";
|
|
6
|
+
import { assignAtlasPageTextures, buildSceneView, fitSpineToTransform, parseProjectDocumentJson, ProjectDocumentJsonParseError, resolveAnchoredTransform, resolveProfileForViewport, resolveProfileTransform } from "./index.js";
|
|
7
|
+
import { createNodeView } from "./views/createNodeView.js";
|
|
8
|
+
import { ContainerNodeView } from "./views/basic.js";
|
|
9
|
+
const sampleUrl = new URL("../../../examples/sample-project/project.json", import.meta.url);
|
|
10
|
+
const sampleJson = readFileSync(sampleUrl, "utf8");
|
|
11
|
+
const ids = {
|
|
12
|
+
scene: "10000000-0000-4000-8000-000000000002",
|
|
13
|
+
root: "10000000-0000-4000-8000-000000000003",
|
|
14
|
+
image: "10000000-0000-4000-8000-000000000051",
|
|
15
|
+
asset: "10000000-0000-4000-8000-000000000010",
|
|
16
|
+
text: "10000000-0000-4000-8000-000000000006",
|
|
17
|
+
};
|
|
18
|
+
const clone = (value) => structuredClone(value);
|
|
19
|
+
const buttonIds = { node: "10000000-0000-4000-8000-000000000008", pressedAsset: "10000000-0000-4000-8000-000000000009" };
|
|
20
|
+
/** Rendering contracts use a DOM-free mini scene; the repository sample itself also exercises Yoga groups. */
|
|
21
|
+
function renderDocument() {
|
|
22
|
+
const document = parseProjectDocumentJson(sampleJson);
|
|
23
|
+
const scene = document.scenes[0];
|
|
24
|
+
const root = scene.nodes.find((node) => node.id === ids.root);
|
|
25
|
+
const image = scene.nodes.find((node) => node.id === ids.image);
|
|
26
|
+
const text = scene.nodes.find((node) => node.id === ids.text);
|
|
27
|
+
image.parentId = root.id;
|
|
28
|
+
text.parentId = root.id;
|
|
29
|
+
root.children = [image.id, text.id];
|
|
30
|
+
scene.nodes = [root, image, text];
|
|
31
|
+
return document;
|
|
32
|
+
}
|
|
33
|
+
/** Sample scene plus a button whose pressed state has its own image and whose hover/disabled states have none. */
|
|
34
|
+
function documentWithButton() {
|
|
35
|
+
const document = renderDocument();
|
|
36
|
+
const scene = document.scenes[0];
|
|
37
|
+
const root = scene.nodes.find((node) => node.id === ids.root);
|
|
38
|
+
document.assets.push({ id: buttonIds.pressedAsset, name: "Pressed", type: "image", source: { uri: "assets/pressed.png", mediaType: "image/png" } });
|
|
39
|
+
scene.nodes.push({
|
|
40
|
+
id: buttonIds.node,
|
|
41
|
+
name: "Play",
|
|
42
|
+
type: "button",
|
|
43
|
+
parentId: ids.root,
|
|
44
|
+
children: [],
|
|
45
|
+
visible: true,
|
|
46
|
+
enabled: true,
|
|
47
|
+
states: { normalAssetId: ids.asset, pressedAssetId: buttonIds.pressedAsset },
|
|
48
|
+
transform: { x: 0, y: 0, width: 120, height: 40, scaleX: 1, scaleY: 1, rotation: 0 },
|
|
49
|
+
});
|
|
50
|
+
root.children.push(buttonIds.node);
|
|
51
|
+
return document;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* По одному узлу каждого типа, который можно вытащить на сцену.
|
|
55
|
+
* `Record<UINode["type"], ...>` — намеренно: компилятор не даст добавить новый тип ноды,
|
|
56
|
+
* не дописав его сюда, а значит новый тип не сможет молча потерять selection и drag.
|
|
57
|
+
*/
|
|
58
|
+
const NODE_TYPE_FIXTURES = {
|
|
59
|
+
container: (base) => ({ ...base, type: "container" }),
|
|
60
|
+
"horizontal-layout": (base) => ({ ...base, type: "horizontal-layout", layoutGroup: { base: { padding: { left: 0, right: 0, top: 0, bottom: 0 }, spacing: 0, childAlignment: "upper-left", reverseOrder: false, controlChildWidth: true, controlChildHeight: true, forceExpandWidth: false, forceExpandHeight: false } } }),
|
|
61
|
+
"vertical-layout": (base) => ({ ...base, type: "vertical-layout", layoutGroup: { base: { padding: { left: 0, right: 0, top: 0, bottom: 0 }, spacing: 0, childAlignment: "upper-left", reverseOrder: false, controlChildWidth: true, controlChildHeight: true, forceExpandWidth: false, forceExpandHeight: false } } }),
|
|
62
|
+
"grid-layout": (base) => ({ ...base, type: "grid-layout", layoutGroup: { base: { padding: { left: 0, right: 0, top: 0, bottom: 0 }, spacingX: 0, spacingY: 0, cellWidth: 20, cellHeight: 20, startCorner: "upper-left", startAxis: "horizontal", childAlignment: "upper-left", constraint: "flexible" } } }),
|
|
63
|
+
image: (base) => ({ ...base, type: "image", assetId: ids.asset }),
|
|
64
|
+
text: (base) => ({ ...base, type: "text", text: "Label" }),
|
|
65
|
+
spine: (base) => ({ ...base, type: "spine", assetId: ids.asset }),
|
|
66
|
+
button: (base) => ({ ...base, type: "button", enabled: true, states: { normalAssetId: ids.asset } }),
|
|
67
|
+
"prefab-instance": (base) => ({ ...base, type: "prefab-instance", prefabId: "40000000-0000-4000-8000-00000000000f" }),
|
|
68
|
+
"scroll-view": (base) => ({ ...base, type: "scroll-view", scrollView: { direction: "vertical", padding: { left: 0, right: 0, top: 0, bottom: 0 }, itemSpacing: 0, cornerRadius: 0, easingEnabled: true } }),
|
|
69
|
+
input: (base) => ({ ...base, type: "input", placeholder: "Enter text", defaultValue: "", secure: false, align: "left", padding: { left: 0, right: 0, top: 0, bottom: 0 }, cleanOnFocus: false, clipText: true, textStyle: { fontFamily: "Arial", fontSize: 24, fontWeight: "normal", fontStyle: "normal", fill: "#FFFFFF", align: "left", verticalAlign: "top", wordWrap: false, breakWords: false, letterSpacing: 0 } }),
|
|
70
|
+
slider: (base) => ({ ...base, type: "slider", backgroundAssetId: ids.asset, fillAssetId: ids.asset, handleAssetId: ids.asset, min: 0, max: 100, step: 1, defaultValue: 50, fillPadding: { left: 0, right: 0, top: 0, bottom: 0 } }),
|
|
71
|
+
"progress-bar": (base) => ({ ...base, type: "progress-bar", backgroundAssetId: ids.asset, fillAssetId: ids.asset, defaultProgress: 50, fillPadding: { left: 0, right: 0, top: 0, bottom: 0 } }),
|
|
72
|
+
"particle-emitter": (base) => ({ ...base, type: "particle-emitter", effectId: "40000000-0000-4000-8000-00000000000f", autoplay: true, simulationSpace: "local" }),
|
|
73
|
+
};
|
|
74
|
+
/** FancyButton keeps exactly one state view visible, so the shown texture identifies the active state. */
|
|
75
|
+
function shownStateTexture(view) {
|
|
76
|
+
const shown = [];
|
|
77
|
+
const walk = (container) => {
|
|
78
|
+
if (container instanceof Sprite && container.visible)
|
|
79
|
+
shown.push(container);
|
|
80
|
+
container.children.forEach(walk);
|
|
81
|
+
};
|
|
82
|
+
walk(view);
|
|
83
|
+
return shown.length === 1 ? shown[0].texture : undefined;
|
|
84
|
+
}
|
|
85
|
+
describe("sample project loader smoke test", () => {
|
|
86
|
+
it("matches atlas pages to texture files by name", () => {
|
|
87
|
+
const atlas = new TextureAtlas("second.png\nsize: 1,1\nformat: RGBA8888\nfilter: Linear,Linear\nrepeat: none\n\nfirst.png\nsize: 1,1\nformat: RGBA8888\nfilter: Linear,Linear\nrepeat: none\n");
|
|
88
|
+
assignAtlasPageTextures(atlas, new Map([["first.png", Texture.WHITE], ["second.png", Texture.WHITE]]));
|
|
89
|
+
expect(atlas.pages.every((page) => page.texture !== null)).toBe(true);
|
|
90
|
+
});
|
|
91
|
+
it("resolves base transforms, partial desktop overrides, and profile visibility", () => {
|
|
92
|
+
const document = renderDocument();
|
|
93
|
+
const node = document.scenes[0].nodes[1];
|
|
94
|
+
expect(resolveProfileTransform(node, "desktop")).toEqual({ transform: node.transform, visible: true });
|
|
95
|
+
const withDesktopOverride = clone(node);
|
|
96
|
+
withDesktopOverride.layoutOverrides = { desktop: { transform: { x: 12, scaleY: 2 } } };
|
|
97
|
+
expect(resolveProfileTransform(withDesktopOverride, "desktop")).toEqual({
|
|
98
|
+
transform: { ...node.transform, x: 12, scaleY: 2 },
|
|
99
|
+
visible: true,
|
|
100
|
+
});
|
|
101
|
+
withDesktopOverride.layoutOverrides.desktop.visible = false;
|
|
102
|
+
expect(resolveProfileTransform(withDesktopOverride, "desktop").visible).toBe(false);
|
|
103
|
+
});
|
|
104
|
+
it("resolves normalized anchors against the parent rectangle", () => {
|
|
105
|
+
const transform = { x: -160, y: -50, width: 320, height: 100, scaleX: 1, scaleY: 1, rotation: 0, anchorMinX: 0.5, anchorMaxX: 0.5, anchorMinY: 1, anchorMaxY: 1 };
|
|
106
|
+
expect(resolveAnchoredTransform(transform, { width: 1920, height: 1080 })).toMatchObject({ x: 800, y: 1030, width: 320, height: 100 });
|
|
107
|
+
});
|
|
108
|
+
it("stretches a node between separated anchors following the parent size", () => {
|
|
109
|
+
const transform = { x: 10, y: 20, width: -30, height: 100, scaleX: 1, scaleY: 1, rotation: 0, anchorMinX: 0, anchorMaxX: 1, anchorMinY: 0.5, anchorMaxY: 0.5 };
|
|
110
|
+
expect(resolveAnchoredTransform(transform, { width: 1920, height: 1080 })).toMatchObject({ x: 10, y: 560, width: 1890, height: 100 });
|
|
111
|
+
expect(resolveAnchoredTransform(transform, { width: 800, height: 1080 })).toMatchObject({ x: 10, width: 770 });
|
|
112
|
+
});
|
|
113
|
+
it("resolves the viewport profile on both sides of the breakpoint and picks mobile exactly on it", () => {
|
|
114
|
+
const settings = { layoutProfileSelection: { mode: "aspect-ratio", mobileMaxAspectRatio: 1 } };
|
|
115
|
+
expect(resolveProfileForViewport(settings, 1920, 1080)).toBe("desktop");
|
|
116
|
+
expect(resolveProfileForViewport(settings, 390, 844)).toBe("mobile");
|
|
117
|
+
expect(resolveProfileForViewport(settings, 1000, 1000)).toBe("mobile");
|
|
118
|
+
});
|
|
119
|
+
it("fits Spine setup bounds to the node transform dimensions", () => {
|
|
120
|
+
const transform = { x: 0, y: 0, width: 200, height: 200, scaleX: 1, scaleY: 1, rotation: 0 };
|
|
121
|
+
expect(fitSpineToTransform({ x: -50, y: 20, width: 100, height: 400 }, transform)).toEqual({ scaleX: 2, scaleY: 0.5, x: 100, y: -10 });
|
|
122
|
+
expect(fitSpineToTransform({ x: 0, y: 0, width: 0, height: 400 }, transform)).toBeUndefined();
|
|
123
|
+
});
|
|
124
|
+
it("uses supplied textures for image nodes and otherwise preserves the placeholder", () => {
|
|
125
|
+
const document = renderDocument();
|
|
126
|
+
const textured = buildSceneView(document, ids.scene, "desktop", { interaction: "authoring", textures: new Map([[ids.asset, Texture.WHITE]]) });
|
|
127
|
+
const imageView = textured.nodeViews.get(ids.image);
|
|
128
|
+
const sprite = imageView.children[0];
|
|
129
|
+
expect(imageView).not.toBeInstanceOf(Sprite);
|
|
130
|
+
expect(sprite).toBeInstanceOf(Sprite);
|
|
131
|
+
expect(sprite?.width).toBe(240);
|
|
132
|
+
const placeholder = buildSceneView(document, ids.scene, "desktop", { interaction: "authoring" }).nodeViews.get(ids.image)?.children[0];
|
|
133
|
+
expect(placeholder).not.toBeInstanceOf(Sprite);
|
|
134
|
+
const anchoredDocument = clone(document);
|
|
135
|
+
const anchoredNode = anchoredDocument.scenes[0].nodes.find((node) => node.id === ids.image);
|
|
136
|
+
anchoredNode.transform = { ...anchoredNode.transform, anchorMinX: 1, anchorMaxX: 1, pivotX: 1, x: 0 };
|
|
137
|
+
const anchoredView = buildSceneView(anchoredDocument, ids.scene, "desktop", { interaction: "authoring", textures: new Map([[ids.asset, Texture.WHITE]]) }).nodeViews.get(ids.image);
|
|
138
|
+
const anchoredSprite = anchoredView.children[0];
|
|
139
|
+
const renderedRight = anchoredView.position.x + (anchoredSprite.width - anchoredView.pivot.x) * anchoredView.scale.x;
|
|
140
|
+
expect(renderedRight).toBe(anchoredDocument.scenes[0].layout.referenceViewports.desktop.width);
|
|
141
|
+
const mobileNode = anchoredDocument.scenes[0].nodes.find((node) => node.id === ids.image);
|
|
142
|
+
mobileNode.layoutOverrides = { mobile: { transform: { anchorMinX: 1, anchorMaxX: 1, pivotX: 1, x: 0 } } };
|
|
143
|
+
const mobileView = buildSceneView(anchoredDocument, ids.scene, "mobile", { interaction: "authoring", textures: new Map([[ids.asset, Texture.WHITE]]) }).nodeViews.get(ids.image);
|
|
144
|
+
const mobileSprite = mobileView.children[0];
|
|
145
|
+
const mobileRight = mobileView.position.x + (mobileSprite.width - mobileView.pivot.x) * mobileView.scale.x;
|
|
146
|
+
expect(mobileRight).toBe(anchoredDocument.scenes[0].layout.referenceViewports.mobile.width);
|
|
147
|
+
});
|
|
148
|
+
it("places a zero-offset centred pivot at the centre of its parent", () => {
|
|
149
|
+
const document = renderDocument();
|
|
150
|
+
const imageNode = document.scenes[0].nodes.find((node) => node.id === ids.image);
|
|
151
|
+
imageNode.transform = {
|
|
152
|
+
...imageNode.transform,
|
|
153
|
+
x: 0,
|
|
154
|
+
y: 0,
|
|
155
|
+
anchorMinX: 0.5,
|
|
156
|
+
anchorMaxX: 0.5,
|
|
157
|
+
anchorMinY: 0.5,
|
|
158
|
+
anchorMaxY: 0.5,
|
|
159
|
+
pivotX: 0.5,
|
|
160
|
+
pivotY: 0.5,
|
|
161
|
+
};
|
|
162
|
+
const imageView = buildSceneView(document, ids.scene, "desktop", { interaction: "authoring" }).nodeViews.get(ids.image);
|
|
163
|
+
const viewport = document.scenes[0].layout.referenceViewports.desktop;
|
|
164
|
+
expect(imageView.position).toMatchObject({ x: viewport.width / 2, y: viewport.height / 2 });
|
|
165
|
+
});
|
|
166
|
+
it("gives every node type the same grab rectangle, whatever it renders", () => {
|
|
167
|
+
const types = Object.keys(NODE_TYPE_FIXTURES);
|
|
168
|
+
const nodeId = (index) => `40000000-0000-4000-8000-00000000000${index}`;
|
|
169
|
+
const views = types.map((type, index) => {
|
|
170
|
+
const node = NODE_TYPE_FIXTURES[type]({
|
|
171
|
+
id: nodeId(index),
|
|
172
|
+
name: type,
|
|
173
|
+
parentId: ids.root,
|
|
174
|
+
children: [],
|
|
175
|
+
visible: true,
|
|
176
|
+
transform: { x: 10, y: 20, width: 120, height: 40, scaleX: 1, scaleY: 1, rotation: 0 },
|
|
177
|
+
});
|
|
178
|
+
// Input and ScrollBox create DOM controls; their NodeView-level grab contract is the same.
|
|
179
|
+
const view = node.type === "scroll-view" || node.type === "input" ? new ContainerNodeView() : createNodeView(node, "authoring");
|
|
180
|
+
view.update(node, "desktop", { width: 1920, height: 1080 });
|
|
181
|
+
return view;
|
|
182
|
+
});
|
|
183
|
+
// Ни текстур, ни Spine-данных: grab-зона не должна зависеть ни от контента ноды, ни от загруженных ассетов.
|
|
184
|
+
const grab = (index, x, y) => views[index]?.containsPoint({ x, y });
|
|
185
|
+
const grabbedInsideRect = types.map((type, index) => [type, grab(index, 60, 20) ?? false]);
|
|
186
|
+
const missedOutsideRect = types.map((type, index) => [type, grab(index, 200, 20) ?? true]);
|
|
187
|
+
expect(grabbedInsideRect).toEqual(types.map((type) => [type, true]));
|
|
188
|
+
expect(missedOutsideRect).toEqual(types.map((type) => [type, false]));
|
|
189
|
+
});
|
|
190
|
+
it("keeps a child grabbable where it reaches past its parent's rectangle", () => {
|
|
191
|
+
const document = renderDocument();
|
|
192
|
+
const scene = document.scenes[0];
|
|
193
|
+
const root = scene.nodes.find((node) => node.id === ids.root);
|
|
194
|
+
const parentId = "50000000-0000-4000-8000-000000000001";
|
|
195
|
+
const childId = "50000000-0000-4000-8000-000000000002";
|
|
196
|
+
const transform = { scaleX: 1, scaleY: 1, rotation: 0 };
|
|
197
|
+
// Ребёнок по умолчанию смещён на 50/50 внутри родителя 100x100, поэтому наполовину торчит наружу.
|
|
198
|
+
scene.nodes.push({ id: parentId, name: "Parent", type: "container", parentId: ids.root, children: [childId], visible: true, transform: { ...transform, x: 0, y: 0, width: 100, height: 100 } });
|
|
199
|
+
scene.nodes.push({ id: childId, name: "Child", type: "container", parentId, children: [], visible: true, transform: { ...transform, x: 50, y: 50, width: 100, height: 100 } });
|
|
200
|
+
root.children.push(parentId);
|
|
201
|
+
const { nodeViews } = buildSceneView(document, ids.scene, "desktop", { interaction: "authoring" });
|
|
202
|
+
const child = nodeViews.get(childId);
|
|
203
|
+
// Точка (90, 90) в локальных координатах ребёнка лежит за границей родителя.
|
|
204
|
+
expect(child.containsPoint({ x: 90, y: 90 })).toBe(true);
|
|
205
|
+
// hitArea родителя обрезала бы здесь всё поддерево, поэтому её быть не должно.
|
|
206
|
+
expect(nodeViews.get(parentId).hitArea).toBeUndefined();
|
|
207
|
+
});
|
|
208
|
+
it("falls back to the normal image for states without an asset and switches the shown view on every state", () => {
|
|
209
|
+
const document = documentWithButton();
|
|
210
|
+
const textures = new Map([[ids.asset, Texture.WHITE], [buttonIds.pressedAsset, Texture.EMPTY]]);
|
|
211
|
+
const view = buildSceneView(document, ids.scene, "desktop", { interaction: "runtime", textures }).nodeViews.get(buttonIds.node);
|
|
212
|
+
expect(view.state).toBe("normal");
|
|
213
|
+
expect(shownStateTexture(view)).toBe(Texture.WHITE);
|
|
214
|
+
// hover и disabled не имеют своего asset и обязаны показывать normal; pressed — собственный.
|
|
215
|
+
const shown = ["hover", "pressed", "normal", "disabled"].map((state) => {
|
|
216
|
+
view.setState(state);
|
|
217
|
+
return [view.state, shownStateTexture(view)];
|
|
218
|
+
});
|
|
219
|
+
expect(shown).toEqual([
|
|
220
|
+
["hover", Texture.WHITE],
|
|
221
|
+
["pressed", Texture.EMPTY],
|
|
222
|
+
["normal", Texture.WHITE],
|
|
223
|
+
["disabled", Texture.WHITE],
|
|
224
|
+
]);
|
|
225
|
+
});
|
|
226
|
+
it("stops dispatching pointer events to a disabled button without writing runtime state back to the document", () => {
|
|
227
|
+
const document = documentWithButton();
|
|
228
|
+
const view = buildSceneView(document, ids.scene, "desktop", { interaction: "runtime", textures: new Map([[ids.asset, Texture.WHITE]]) }).nodeViews.get(buttonIds.node);
|
|
229
|
+
const node = document.scenes[0].nodes.find((candidate) => candidate.id === buttonIds.node);
|
|
230
|
+
const button = view.children[0];
|
|
231
|
+
expect(view.enabled).toBe(true);
|
|
232
|
+
expect(button.eventMode).toBe("static");
|
|
233
|
+
view.enabled = false;
|
|
234
|
+
expect(view.enabled).toBe(false);
|
|
235
|
+
expect(view.state).toBe("disabled");
|
|
236
|
+
// Именно так @pixi/ui глушит press: EventSystem не доставляет события неинтерактивному view.
|
|
237
|
+
expect(button.eventMode).not.toBe("static");
|
|
238
|
+
// Enabled — только начальное presentation-состояние: runtime setter документ не трогает.
|
|
239
|
+
expect(node).toMatchObject({ type: "button", enabled: true });
|
|
240
|
+
});
|
|
241
|
+
it("builds an inert button on an authoring canvas while keeping the node itself grabbable", () => {
|
|
242
|
+
const document = documentWithButton();
|
|
243
|
+
const view = buildSceneView(document, ids.scene, "desktop", { interaction: "authoring", textures: new Map([[ids.asset, Texture.WHITE]]) }).nodeViews.get(buttonIds.node);
|
|
244
|
+
// FancyButton не реагирует на pointer во время authoring...
|
|
245
|
+
expect(view.children[0].eventMode).toBe("none");
|
|
246
|
+
// ...но выделение и drag идут через grab-прямоугольник самого NodeView и обязаны продолжать работать.
|
|
247
|
+
expect(view.containsPoint({ x: 60, y: 20 })).toBe(true);
|
|
248
|
+
});
|
|
249
|
+
it("applies identical layout coordinates to image, text, and Spine node containers", () => {
|
|
250
|
+
const document = renderDocument();
|
|
251
|
+
const scene = document.scenes[0];
|
|
252
|
+
const root = scene.nodes.find((node) => node.id === ids.root);
|
|
253
|
+
const image = scene.nodes.find((node) => node.id === ids.image);
|
|
254
|
+
const text = scene.nodes.find((node) => node.id === ids.text);
|
|
255
|
+
const spineId = "10000000-0000-4000-8000-000000000007";
|
|
256
|
+
const transform = { x: -240, y: -90, width: 320, height: 180, scaleX: 1.25, scaleY: 0.75, rotation: 0.2, anchorMinX: 1, anchorMaxX: 1, anchorMinY: 0.5, anchorMaxY: 0.5, pivotX: 0.75, pivotY: 0.5 };
|
|
257
|
+
image.transform = { ...transform };
|
|
258
|
+
text.transform = { ...transform };
|
|
259
|
+
const spine = { id: spineId, name: "Spine", type: "spine", assetId: ids.asset, parentId: ids.root, children: [], visible: true, transform: { ...transform } };
|
|
260
|
+
scene.nodes.push(spine);
|
|
261
|
+
root.children.push(spineId);
|
|
262
|
+
const views = buildSceneView(document, ids.scene, "desktop", { interaction: "authoring", textures: new Map([[ids.asset, Texture.WHITE]]) }).nodeViews;
|
|
263
|
+
const snapshot = (nodeId) => {
|
|
264
|
+
const view = views.get(nodeId);
|
|
265
|
+
return { position: { x: view.position.x, y: view.position.y }, pivot: { x: view.pivot.x, y: view.pivot.y }, scale: { x: view.scale.x, y: view.scale.y }, rotation: view.rotation };
|
|
266
|
+
};
|
|
267
|
+
expect(snapshot(ids.text)).toEqual(snapshot(ids.image));
|
|
268
|
+
expect(snapshot(spineId)).toEqual(snapshot(ids.image));
|
|
269
|
+
});
|
|
270
|
+
it("loads the repository fixture through migration and validation", () => {
|
|
271
|
+
const document = parseProjectDocumentJson(sampleJson);
|
|
272
|
+
const scene = document.scenes[0];
|
|
273
|
+
expect(scene.id).toBe(ids.scene);
|
|
274
|
+
expect(scene.rootNodeIds).toEqual([ids.root]);
|
|
275
|
+
expect(scene.nodes.find((node) => node.id === ids.image && node.type === "image")).toMatchObject({ assetId: ids.asset });
|
|
276
|
+
expect(scene.nodes.find((node) => node.id === ids.text)).toMatchObject({ binding: "showcase.title" });
|
|
277
|
+
expect(scene.layout.referenceViewports).toHaveProperty("desktop");
|
|
278
|
+
expect(scene.layout.referenceViewports).toHaveProperty("mobile");
|
|
279
|
+
});
|
|
280
|
+
it("round-trips deterministically while retaining semantic child order", () => {
|
|
281
|
+
const document = parseProjectDocumentJson(sampleJson);
|
|
282
|
+
const serialized = serializeProjectDocument(document);
|
|
283
|
+
const roundTripped = parseProjectDocumentJson(serialized);
|
|
284
|
+
expect(roundTripped).toEqual(document);
|
|
285
|
+
expect(serializeProjectDocument(roundTripped)).toBe(serialized);
|
|
286
|
+
expect(roundTripped.scenes[0].nodes[0].children).toEqual([
|
|
287
|
+
ids.text,
|
|
288
|
+
"10000000-0000-4000-8000-000000000020",
|
|
289
|
+
"10000000-0000-4000-8000-000000000030",
|
|
290
|
+
"10000000-0000-4000-8000-000000000040",
|
|
291
|
+
"10000000-0000-4000-8000-000000000050",
|
|
292
|
+
"10000000-0000-4000-8000-000000000062",
|
|
293
|
+
"10000000-0000-4000-8000-000000000063",
|
|
294
|
+
]);
|
|
295
|
+
});
|
|
296
|
+
it("does not use display names as references", () => {
|
|
297
|
+
const document = parseProjectDocumentJson(sampleJson);
|
|
298
|
+
const renamed = clone(document);
|
|
299
|
+
const image = renamed.scenes[0].nodes.find((node) => node.id === ids.image);
|
|
300
|
+
image.name = "Renamed image";
|
|
301
|
+
expect(parseProjectDocumentJson(serializeProjectDocument(renamed)).scenes[0].nodes.find((node) => node.id === ids.image)).toMatchObject({ id: ids.image, assetId: ids.asset });
|
|
302
|
+
});
|
|
303
|
+
it("surfaces schema validation codes through the JSON loading boundary", () => {
|
|
304
|
+
const invalid = clone(parseProjectDocumentJson(sampleJson));
|
|
305
|
+
invalid.scenes[0].nodes.find((node) => node.id === ids.image).assetId = ids.text;
|
|
306
|
+
expect(() => parseProjectDocumentJson(JSON.stringify(invalid))).toThrow("MISSING_ASSET_REFERENCE");
|
|
307
|
+
});
|
|
308
|
+
it("distinguishes malformed JSON from schema errors", () => {
|
|
309
|
+
expect(() => parseProjectDocumentJson("{not json")).toThrow(ProjectDocumentJsonParseError);
|
|
310
|
+
const invalid = clone(parseProjectDocumentJson(sampleJson));
|
|
311
|
+
delete invalid.scenes[0].layout.referenceViewports.mobile;
|
|
312
|
+
expect(() => parseProjectDocumentJson(JSON.stringify(invalid))).toThrow(TypeError);
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}
|
package/dist/layout.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type LayoutProfileId, type ProjectDocument, type UINode } from "@pixi-ui-editor/schema";
|
|
2
|
+
export type ResolvedProfileTransform = {
|
|
3
|
+
transform: UINode["transform"];
|
|
4
|
+
visible: boolean;
|
|
5
|
+
};
|
|
6
|
+
export type LayoutSize = {
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
};
|
|
10
|
+
/** Resolves a node's base transform with a profile override applied field by field. */
|
|
11
|
+
export declare function resolveProfileTransform(node: UINode, profile: LayoutProfileId): ResolvedProfileTransform;
|
|
12
|
+
/**
|
|
13
|
+
* Resolves normalized Unity-style anchors against the node's parent rectangle.
|
|
14
|
+
* A point axis (anchorMin == anchorMax) offsets the stored x/y by the anchor point; missing anchors
|
|
15
|
+
* preserve legacy top-left positioning. A stretched axis (anchorMin < anchorMax) additionally treats
|
|
16
|
+
* the stored width/height as a delta to the anchor rectangle, so the node follows the parent's size.
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveAnchoredTransform(transform: UINode["transform"], parentSize?: LayoutSize): UINode["transform"];
|
|
19
|
+
/** Picks the layout profile for a viewport using the document's aspect-ratio rule; the breakpoint itself is mobile. */
|
|
20
|
+
export declare function resolveProfileForViewport(settings: ProjectDocument["settings"], width: number, height: number): LayoutProfileId;
|
|
21
|
+
export declare function fitSpineToTransform(bounds: {
|
|
22
|
+
x: number;
|
|
23
|
+
y: number;
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
}, transform: UINode["transform"]): {
|
|
27
|
+
scaleX: number;
|
|
28
|
+
scaleY: number;
|
|
29
|
+
x: number;
|
|
30
|
+
y: number;
|
|
31
|
+
} | undefined;
|
|
32
|
+
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEjG,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3D,uFAAuF;AACvF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,wBAAwB,CAOxG;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAarH;AAED,uHAAuH;AACvH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,CAE/H;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC/D,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,GAC7B;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAOtE"}
|
package/dist/layout.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** Resolves a node's base transform with a profile override applied field by field. */
|
|
2
|
+
export function resolveProfileTransform(node, profile) {
|
|
3
|
+
const override = node.layoutOverrides?.[profile];
|
|
4
|
+
return {
|
|
5
|
+
transform: { ...node.transform, ...override?.transform },
|
|
6
|
+
visible: override?.visible ?? node.visible,
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Resolves normalized Unity-style anchors against the node's parent rectangle.
|
|
11
|
+
* A point axis (anchorMin == anchorMax) offsets the stored x/y by the anchor point; missing anchors
|
|
12
|
+
* preserve legacy top-left positioning. A stretched axis (anchorMin < anchorMax) additionally treats
|
|
13
|
+
* the stored width/height as a delta to the anchor rectangle, so the node follows the parent's size.
|
|
14
|
+
*/
|
|
15
|
+
export function resolveAnchoredTransform(transform, parentSize) {
|
|
16
|
+
if (parentSize === undefined)
|
|
17
|
+
return transform;
|
|
18
|
+
const minX = transform.anchorMinX ?? 0;
|
|
19
|
+
const maxX = transform.anchorMaxX ?? minX;
|
|
20
|
+
const minY = transform.anchorMinY ?? 0;
|
|
21
|
+
const maxY = transform.anchorMaxY ?? minY;
|
|
22
|
+
return {
|
|
23
|
+
...transform,
|
|
24
|
+
x: transform.x + minX * parentSize.width,
|
|
25
|
+
y: transform.y + minY * parentSize.height,
|
|
26
|
+
width: Math.max(0, transform.width + (maxX - minX) * parentSize.width),
|
|
27
|
+
height: Math.max(0, transform.height + (maxY - minY) * parentSize.height),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Picks the layout profile for a viewport using the document's aspect-ratio rule; the breakpoint itself is mobile. */
|
|
31
|
+
export function resolveProfileForViewport(settings, width, height) {
|
|
32
|
+
return width / height <= settings.layoutProfileSelection.mobileMaxAspectRatio ? "mobile" : "desktop";
|
|
33
|
+
}
|
|
34
|
+
export function fitSpineToTransform(bounds, transform) {
|
|
35
|
+
if (!Number.isFinite(bounds.x) || !Number.isFinite(bounds.y) || !Number.isFinite(bounds.width) || !Number.isFinite(bounds.height) || bounds.width <= 0 || bounds.height <= 0)
|
|
36
|
+
return undefined;
|
|
37
|
+
const scaleX = transform.width / bounds.width;
|
|
38
|
+
const scaleY = transform.height / bounds.height;
|
|
39
|
+
return Number.isFinite(scaleX) && scaleX > 0 && Number.isFinite(scaleY) && scaleY > 0
|
|
40
|
+
? { scaleX, scaleY, x: -bounds.x * scaleX, y: -bounds.y * scaleY }
|
|
41
|
+
: undefined;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AASA,uFAAuF;AACvF,MAAM,UAAU,uBAAuB,CAAC,IAAY,EAAE,OAAwB;IAC5E,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,OAAO,CAAC,CAAC;IAEjD,OAAO;QACL,SAAS,EAAE,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,QAAQ,EAAE,SAAS,EAAE;QACxD,OAAO,EAAE,QAAQ,EAAE,OAAO,IAAI,IAAI,CAAC,OAAO;KAC3C,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,SAA8B,EAAE,UAAuB;IAC9F,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC/C,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,IAAI,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,IAAI,IAAI,CAAC;IAC1C,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,IAAI,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,IAAI,IAAI,CAAC;IAC1C,OAAO;QACL,GAAG,SAAS;QACZ,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,IAAI,GAAG,UAAU,CAAC,KAAK;QACxC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,IAAI,GAAG,UAAU,CAAC,MAAM;QACzC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC;QACtE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;KAC1E,CAAC;AACJ,CAAC;AAED,uHAAuH;AACvH,MAAM,UAAU,yBAAyB,CAAC,QAAqC,EAAE,KAAa,EAAE,MAAc;IAC5G,OAAO,KAAK,GAAG,MAAM,IAAI,QAAQ,CAAC,sBAAsB,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AACvG,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,MAA+D,EAC/D,SAA8B;IAE9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/L,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC9C,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAChD,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC;QACnF,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,EAAE;QAClE,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import "@pixi/layout";
|
|
2
|
+
import { type LayoutGroupNode, type LayoutProfileId, type UINode } from "@pixi-ui-editor/schema";
|
|
3
|
+
import { Container } from "pixi.js";
|
|
4
|
+
import { type LayoutSize } from "./layout.js";
|
|
5
|
+
import { NodeView } from "./views/NodeView.js";
|
|
6
|
+
/** Importing @pixi/layout installs its renderer extension. Kept as a shared explicit contract for every host. */
|
|
7
|
+
export declare function initializePixiLayout(): void;
|
|
8
|
+
/** Applies one declarative document group to Pixi Layout; no computed Yoga data crosses the document boundary. */
|
|
9
|
+
export declare function applyLayoutGroup(view: Container, node: LayoutGroupNode, profile: LayoutProfileId, parentSize?: LayoutSize, managedSize?: LayoutSize): void;
|
|
10
|
+
/**
|
|
11
|
+
* Runtime-only Yoga owner for one direct child. The wrapper receives Yoga coordinates while the
|
|
12
|
+
* serializable NodeView keeps the shared pivot/rotation/scale/content/hit-test contract.
|
|
13
|
+
*/
|
|
14
|
+
export declare class LayoutItemContainer extends Container {
|
|
15
|
+
readonly nodeView: NodeView;
|
|
16
|
+
private readonly onLayoutChanged?;
|
|
17
|
+
private node?;
|
|
18
|
+
private profile;
|
|
19
|
+
private fallbackSize;
|
|
20
|
+
constructor(nodeView: NodeView, onLayoutChanged?: (() => void) | undefined);
|
|
21
|
+
sync(node: UINode, profile: LayoutProfileId, fallbackSize: LayoutSize): void;
|
|
22
|
+
private applyComputedSize;
|
|
23
|
+
}
|
|
24
|
+
/** Marks a direct child's technical wrapper as layout-managed. */
|
|
25
|
+
export declare function applyLayoutItem(view: LayoutItemContainer, node: UINode, parent: LayoutGroupNode, profile: LayoutProfileId): void;
|
|
26
|
+
/** A zero-visual Yoga flex item. Fixed Unity grid constraints need explicit line breaks; this is still solved entirely by Yoga. */
|
|
27
|
+
export declare function createGridLineBreak(parent: Extract<LayoutGroupNode, {
|
|
28
|
+
type: "grid-layout";
|
|
29
|
+
}>, profile: LayoutProfileId): Container | undefined;
|
|
30
|
+
export declare function isLayoutManagedChild(node: UINode, nodes: readonly UINode[]): boolean;
|
|
31
|
+
//# sourceMappingURL=layoutGroups.d.ts.map
|
|
@@ -0,0 +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;gBAEtC,QAAQ,EAAE,QAAQ,EAAmB,eAAe,CAAC,GAAE,MAAM,IAAI,aAAA;IAMtF,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,UAAU,GAAG,IAAI;IAQ5E,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"}
|