@sebastianwessel/isostate 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animation/animation-engine.d.ts +2 -0
- package/dist/animation/animation-engine.d.ts.map +1 -1
- package/dist/animation/controller.d.ts +9 -2
- package/dist/animation/controller.d.ts.map +1 -1
- package/dist/assets/software-architecture/IMAGEGEN-PROMPTS.md +66 -0
- package/dist/assets/software-architecture/LICENSE +21 -0
- package/dist/assets/software-architecture/NOTICE.md +17 -0
- package/dist/assets/software-architecture/README.md +105 -0
- package/dist/assets/software-architecture/agentic/AGENT-VISUAL-PROMPTS.md +42 -0
- package/dist/assets/software-architecture/agentic/HANDOFF-PROMPTS.md +19 -0
- package/dist/assets/software-architecture/agentic/PROCESS-VISUAL-PROMPTS.md +109 -0
- package/dist/assets/software-architecture/agentic/agents-sprites.png +0 -0
- package/dist/assets/software-architecture/agentic/ai-capabilities-sprites.png +0 -0
- package/dist/assets/software-architecture/agentic/ai-to-human-handoff.png +0 -0
- package/dist/assets/software-architecture/agentic/channels-sprites.png +0 -0
- package/dist/assets/software-architecture/agentic/human-to-ai-handoff.png +0 -0
- package/dist/assets/software-architecture/agentic/humans-sprites.png +0 -0
- package/dist/assets/software-architecture/agentic/infrastructure-sprites.png +0 -0
- package/dist/assets/software-architecture/agentic/lifecycle-sprites.png +0 -0
- package/dist/assets/software-architecture/agentic/orchestration-sprites.png +0 -0
- package/dist/assets/software-architecture/agentic/providers-sprites.png +0 -0
- package/dist/assets/software-architecture/agentic/servicenow-sprites.png +0 -0
- package/dist/assets/software-architecture/architecture/architecture-sprites.png +0 -0
- package/dist/assets/software-architecture/manifest.json +2095 -0
- package/dist/assets/software-architecture/workflow/workflow-process-sprites.png +0 -0
- package/dist/browser/isostate.runtime.js +4 -4
- package/dist/browser/isostate.runtime.js.map +9 -8
- package/dist/chunks/errors-2yA81Vfb.js +23 -0
- package/dist/chunks/{errors-DyqEkrm5.js.map → errors-2yA81Vfb.js.map} +1 -1
- package/dist/chunks/index-C_7KbR4v.js +1701 -0
- package/dist/chunks/index-C_7KbR4v.js.map +1 -0
- package/dist/chunks/rendering-engine-DLaM1XbU.js +1425 -0
- package/dist/chunks/rendering-engine-DLaM1XbU.js.map +1 -0
- package/dist/chunks/scene-parser-D_0OCHLL.js +3033 -0
- package/dist/chunks/scene-parser-D_0OCHLL.js.map +1 -0
- package/dist/chunks/sha256-BkgWUdh1.js +123 -0
- package/dist/chunks/sha256-BkgWUdh1.js.map +1 -0
- package/dist/dsl/browser.js +3 -3
- package/dist/dsl/index.js +3 -3
- package/dist/dsl/scene-parser.d.ts.map +1 -1
- package/dist/dsl/scene-validator.d.ts.map +1 -1
- package/dist/dsl/workflow-effects-validation.d.ts +8 -0
- package/dist/dsl/workflow-effects-validation.d.ts.map +1 -0
- package/dist/editor-support/adapter.d.ts.map +1 -1
- package/dist/editor-support/index.js +347 -394
- package/dist/editor-support/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +356 -424
- package/dist/index.js.map +1 -1
- package/dist/rendering/animation-css.d.ts.map +1 -1
- package/dist/rendering/rendering-engine.d.ts +2 -0
- package/dist/rendering/rendering-engine.d.ts.map +1 -1
- package/dist/rendering/scene-effects.d.ts +15 -0
- package/dist/rendering/scene-effects.d.ts.map +1 -0
- package/dist/runtime/index.js +4 -4
- package/dist/runtime/interactivity.d.ts.map +1 -1
- package/dist/types/asset-registry.d.ts.map +1 -1
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/node.d.ts +40 -1
- package/dist/types/node.d.ts.map +1 -1
- package/package.json +9 -8
- package/dist/chunks/errors-DyqEkrm5.js +0 -29
- package/dist/chunks/index-CB6XEsbY.js +0 -1756
- package/dist/chunks/index-CB6XEsbY.js.map +0 -1
- package/dist/chunks/rendering-engine-nkqYx0qc.js +0 -1303
- package/dist/chunks/rendering-engine-nkqYx0qc.js.map +0 -1
- package/dist/chunks/scene-parser-F69XGE0l.js +0 -2743
- package/dist/chunks/scene-parser-F69XGE0l.js.map +0 -1
- package/dist/chunks/sha256-4JuurR-b.js +0 -69
- package/dist/chunks/sha256-4JuurR-b.js.map +0 -1
|
@@ -1,428 +1,381 @@
|
|
|
1
|
-
import { g as getResolvedProjectionLayout, p as projectToRaw, a as getResolvedViewBox, b as
|
|
2
|
-
import { R as RenderError } from '../chunks/errors-
|
|
1
|
+
import { g as getResolvedProjectionLayout, p as projectToRaw, a as getResolvedViewBox, b as getElementState, c as getCurrentElementBounds, h as hideElementAfterExit, u as unhideElementOnReadd, d as getConnectorState, e as updateElementTransforms } from '../chunks/rendering-engine-DLaM1XbU.js';
|
|
2
|
+
import { R as RenderError } from '../chunks/errors-2yA81Vfb.js';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Project an isometric grid point into SVG screen coordinates.
|
|
6
|
-
* Uses the same projection, bounds, and padding as the renderer.
|
|
7
|
-
*/
|
|
8
4
|
function projectGridPoint(bundle, point) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
const layout = getResolvedProjectionLayout(bundle);
|
|
6
|
+
const rawX = layout.cellSize * (point[0] - point[1]) * 0.5;
|
|
7
|
+
const rawY = layout.cellSize * (point[0] + point[1]) * 0.25;
|
|
8
|
+
return {
|
|
9
|
+
x: rawX - layout.selectedBounds.minX + layout.padding.x,
|
|
10
|
+
y: rawY - layout.selectedBounds.minY + layout.padding.y
|
|
11
|
+
};
|
|
16
12
|
}
|
|
17
|
-
/**
|
|
18
|
-
* Unproject an SVG screen point back into fractional isometric grid coordinates.
|
|
19
|
-
* The editor owns snap-to-grid rounding.
|
|
20
|
-
*/
|
|
21
13
|
function unprojectScreenPoint(bundle, point) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
14
|
+
const layout = getResolvedProjectionLayout(bundle);
|
|
15
|
+
const rawX = point.x + layout.selectedBounds.minX - layout.padding.x;
|
|
16
|
+
const rawY = point.y + layout.selectedBounds.minY - layout.padding.y;
|
|
17
|
+
const cellSize = layout.cellSize;
|
|
18
|
+
const gridX = rawX / cellSize + 2 * rawY / cellSize;
|
|
19
|
+
const gridY = 2 * rawY / cellSize - rawX / cellSize;
|
|
20
|
+
return [gridX, gridY];
|
|
29
21
|
}
|
|
30
|
-
/**
|
|
31
|
-
* Convert browser pointer coordinates into SVG user units using the root SVG
|
|
32
|
-
* screen CTM inverse.
|
|
33
|
-
* @throws {RenderError} `EDITOR_GEOMETRY_UNAVAILABLE` when the CTM is missing or not invertible.
|
|
34
|
-
*/
|
|
35
22
|
function clientPointToSvgPoint(svg, point) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const result = svgPoint.matrixTransform(inverse);
|
|
54
|
-
return { x: result.x, y: result.y };
|
|
23
|
+
const ctm = svg.getScreenCTM();
|
|
24
|
+
if (!ctm) {
|
|
25
|
+
throw new RenderError("EDITOR_GEOMETRY_UNAVAILABLE", "SVG CTM is not available");
|
|
26
|
+
}
|
|
27
|
+
let inverse = null;
|
|
28
|
+
try {
|
|
29
|
+
inverse = ctm.inverse();
|
|
30
|
+
} catch {
|
|
31
|
+
}
|
|
32
|
+
if (!inverse) {
|
|
33
|
+
throw new RenderError("EDITOR_GEOMETRY_UNAVAILABLE", "SVG CTM is not invertible");
|
|
34
|
+
}
|
|
35
|
+
const svgPoint = svg.createSVGPoint();
|
|
36
|
+
svgPoint.x = point.clientX;
|
|
37
|
+
svgPoint.y = point.clientY;
|
|
38
|
+
const result = svgPoint.matrixTransform(inverse);
|
|
39
|
+
return { x: result.x, y: result.y };
|
|
55
40
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Return the four projected corners of a grid cell in clockwise order.
|
|
58
|
-
*/
|
|
59
41
|
function getGridCellPolygon(bundle, cell) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
42
|
+
const [x, y] = cell;
|
|
43
|
+
return [
|
|
44
|
+
projectGridPoint(bundle, [x, y]),
|
|
45
|
+
projectGridPoint(bundle, [x + 1, y]),
|
|
46
|
+
projectGridPoint(bundle, [x + 1, y + 1]),
|
|
47
|
+
projectGridPoint(bundle, [x, y + 1])
|
|
48
|
+
];
|
|
67
49
|
}
|
|
68
50
|
|
|
69
|
-
/**
|
|
70
|
-
* Find the topmost runtime object at a screen point.
|
|
71
|
-
* Hit testing follows the current rendered depth order so the visually
|
|
72
|
-
* topmost object wins.
|
|
73
|
-
*/
|
|
74
51
|
function getRuntimeObjectAtPoint(adapter, point, options = {}) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
id: obj.id,
|
|
96
|
-
kind: obj.kind,
|
|
97
|
-
layer: obj.layer,
|
|
98
|
-
bounds: obj.bounds,
|
|
99
|
-
};
|
|
100
|
-
}
|
|
52
|
+
const kinds = options.kinds ?? ["element", "connection"];
|
|
53
|
+
const currentScene = adapter.mounted.engine.getCurrentState();
|
|
54
|
+
if (!currentScene) return void 0;
|
|
55
|
+
const objects = adapter.getObjects(currentScene.id);
|
|
56
|
+
const layerOrder = adapter.getLayerOrder();
|
|
57
|
+
const layerRank = new Map(layerOrder.map((l, i) => [l.name, i]));
|
|
58
|
+
const candidates = objects.filter((obj) => kinds.includes(obj.kind)).filter((obj) => options.includeHidden || obj.present).sort((a, b) => {
|
|
59
|
+
const rankA = layerRank.get(a.layer) ?? -1;
|
|
60
|
+
const rankB = layerRank.get(b.layer) ?? -1;
|
|
61
|
+
return rankA - rankB;
|
|
62
|
+
});
|
|
63
|
+
for (let i = candidates.length - 1; i >= 0; i--) {
|
|
64
|
+
const obj = candidates[i];
|
|
65
|
+
if (pointInBounds(point, obj.bounds)) {
|
|
66
|
+
return {
|
|
67
|
+
id: obj.id,
|
|
68
|
+
kind: obj.kind,
|
|
69
|
+
layer: obj.layer,
|
|
70
|
+
bounds: obj.bounds
|
|
71
|
+
};
|
|
101
72
|
}
|
|
102
|
-
|
|
73
|
+
}
|
|
74
|
+
return void 0;
|
|
103
75
|
}
|
|
104
|
-
/**
|
|
105
|
-
* Compute the union bounds of a selection of runtime objects.
|
|
106
|
-
* Missing ids are ignored. Returns `undefined` if no ids resolve.
|
|
107
|
-
*/
|
|
108
76
|
function getRuntimeSelectionBounds(adapter, ids) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
height: maxY - minY,
|
|
130
|
-
};
|
|
77
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
78
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
79
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
80
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
81
|
+
for (const id of ids) {
|
|
82
|
+
const obj = adapter.getObject(id);
|
|
83
|
+
if (!obj?.present) continue;
|
|
84
|
+
const b = obj.bounds;
|
|
85
|
+
minX = Math.min(minX, b.minX);
|
|
86
|
+
minY = Math.min(minY, b.minY);
|
|
87
|
+
maxX = Math.max(maxX, b.minX + b.width);
|
|
88
|
+
maxY = Math.max(maxY, b.minY + b.height);
|
|
89
|
+
}
|
|
90
|
+
if (!Number.isFinite(minX)) return void 0;
|
|
91
|
+
return {
|
|
92
|
+
minX,
|
|
93
|
+
minY,
|
|
94
|
+
width: maxX - minX,
|
|
95
|
+
height: maxY - minY
|
|
96
|
+
};
|
|
131
97
|
}
|
|
132
98
|
function pointInBounds(point, bounds) {
|
|
133
|
-
|
|
134
|
-
point.x <= bounds.minX + bounds.width &&
|
|
135
|
-
point.y >= bounds.minY &&
|
|
136
|
-
point.y <= bounds.minY + bounds.height);
|
|
99
|
+
return point.x >= bounds.minX && point.x <= bounds.minX + bounds.width && point.y >= bounds.minY && point.y <= bounds.minY + bounds.height;
|
|
137
100
|
}
|
|
138
|
-
/** Compute screen-space bounds for a connector route. */
|
|
139
101
|
function getConnectionBounds(route, bundle) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
102
|
+
const layout = resolveLayoutForBounds(bundle);
|
|
103
|
+
let minRawX = Number.POSITIVE_INFINITY;
|
|
104
|
+
let minRawY = Number.POSITIVE_INFINITY;
|
|
105
|
+
let maxRawX = Number.NEGATIVE_INFINITY;
|
|
106
|
+
let maxRawY = Number.NEGATIVE_INFINITY;
|
|
107
|
+
for (const [x, y] of route) {
|
|
108
|
+
const { rawX, rawY } = projectToRaw(x, y, layout.cellSize);
|
|
109
|
+
minRawX = Math.min(minRawX, rawX);
|
|
110
|
+
minRawY = Math.min(minRawY, rawY);
|
|
111
|
+
maxRawX = Math.max(maxRawX, rawX);
|
|
112
|
+
maxRawY = Math.max(maxRawY, rawY);
|
|
113
|
+
}
|
|
114
|
+
const offsetX = -layout.selectedBounds.minX + layout.padding.x;
|
|
115
|
+
const offsetY = -layout.selectedBounds.minY + layout.padding.y;
|
|
116
|
+
return {
|
|
117
|
+
minX: minRawX + offsetX,
|
|
118
|
+
minY: minRawY + offsetY,
|
|
119
|
+
width: maxRawX - minRawX,
|
|
120
|
+
height: maxRawY - minRawY
|
|
121
|
+
};
|
|
160
122
|
}
|
|
161
|
-
// Lightweight re-computation of the layout values needed for bounds projection.
|
|
162
123
|
function resolveLayoutForBounds(bundle) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
for (const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
cMaxX = Math.max(cMaxX, rawX + visualSize * (1 - anchor[0]));
|
|
180
|
-
cMaxY = Math.max(cMaxY, rawY + visualSize * (1 - anchor[1]));
|
|
181
|
-
}
|
|
182
|
-
for (const conn of stop.connectors ?? []) {
|
|
183
|
-
if (conn.presence === "removed")
|
|
184
|
-
continue;
|
|
185
|
-
for (const [x, y] of conn.route) {
|
|
186
|
-
const { rawX, rawY } = projectToRaw(x, y, cellSize);
|
|
187
|
-
cMinX = Math.min(cMinX, rawX);
|
|
188
|
-
cMinY = Math.min(cMinY, rawY);
|
|
189
|
-
cMaxX = Math.max(cMaxX, rawX);
|
|
190
|
-
cMaxY = Math.max(cMaxY, rawY);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
124
|
+
const cellSize = bundle.grid.cellSize;
|
|
125
|
+
const padding = bundle.layout.padding;
|
|
126
|
+
let cMinX = Number.POSITIVE_INFINITY;
|
|
127
|
+
let cMinY = Number.POSITIVE_INFINITY;
|
|
128
|
+
let cMaxX = Number.NEGATIVE_INFINITY;
|
|
129
|
+
let cMaxY = Number.NEGATIVE_INFINITY;
|
|
130
|
+
for (const stop of bundle.scenes) {
|
|
131
|
+
for (const el of stop.elements ?? []) {
|
|
132
|
+
if (el.presence === "removed") continue;
|
|
133
|
+
const { rawX, rawY } = projectToRaw(el.pos[0] + el.size, el.pos[1] + el.size, cellSize);
|
|
134
|
+
const visualSize = cellSize * el.size;
|
|
135
|
+
const anchor = bundle.assets?.[el.asset]?.anchor ?? [0.5, 1];
|
|
136
|
+
cMinX = Math.min(cMinX, rawX - visualSize * anchor[0]);
|
|
137
|
+
cMinY = Math.min(cMinY, rawY - visualSize * anchor[1]);
|
|
138
|
+
cMaxX = Math.max(cMaxX, rawX + visualSize * (1 - anchor[0]));
|
|
139
|
+
cMaxY = Math.max(cMaxY, rawY + visualSize * (1 - anchor[1]));
|
|
193
140
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
cMaxX = cellSize;
|
|
198
|
-
cMaxY = cellSize;
|
|
199
|
-
}
|
|
200
|
-
// Floor bounds
|
|
201
|
-
const [ox, oy] = bundle.floor.origin;
|
|
202
|
-
const [fw, fh] = bundle.floor.size;
|
|
203
|
-
const floorPoints = [
|
|
204
|
-
[ox, oy],
|
|
205
|
-
[ox + fw, oy],
|
|
206
|
-
[ox, oy + fh],
|
|
207
|
-
[ox + fw, oy + fh],
|
|
208
|
-
];
|
|
209
|
-
let fMinX = Number.POSITIVE_INFINITY;
|
|
210
|
-
let fMinY = Number.POSITIVE_INFINITY;
|
|
211
|
-
let fMaxX = Number.NEGATIVE_INFINITY;
|
|
212
|
-
let fMaxY = Number.NEGATIVE_INFINITY;
|
|
213
|
-
for (const [x, y] of floorPoints) {
|
|
141
|
+
for (const conn of stop.connectors ?? []) {
|
|
142
|
+
if (conn.presence === "removed") continue;
|
|
143
|
+
for (const [x, y] of conn.route) {
|
|
214
144
|
const { rawX, rawY } = projectToRaw(x, y, cellSize);
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
// Select bounds
|
|
221
|
-
let sMinX;
|
|
222
|
-
let sMinY;
|
|
223
|
-
let sMaxX;
|
|
224
|
-
let sMaxY;
|
|
225
|
-
const mode = bundle.layout.bounds;
|
|
226
|
-
if (mode === "content") {
|
|
227
|
-
sMinX = cMinX;
|
|
228
|
-
sMinY = cMinY;
|
|
229
|
-
sMaxX = cMaxX;
|
|
230
|
-
sMaxY = cMaxY;
|
|
231
|
-
}
|
|
232
|
-
else if (mode === "floor") {
|
|
233
|
-
sMinX = fMinX;
|
|
234
|
-
sMinY = fMinY;
|
|
235
|
-
sMaxX = fMaxX;
|
|
236
|
-
sMaxY = fMaxY;
|
|
145
|
+
cMinX = Math.min(cMinX, rawX);
|
|
146
|
+
cMinY = Math.min(cMinY, rawY);
|
|
147
|
+
cMaxX = Math.max(cMaxX, rawX);
|
|
148
|
+
cMaxY = Math.max(cMaxY, rawY);
|
|
149
|
+
}
|
|
237
150
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
151
|
+
}
|
|
152
|
+
if (!Number.isFinite(cMinX)) {
|
|
153
|
+
cMinX = 0;
|
|
154
|
+
cMinY = 0;
|
|
155
|
+
cMaxX = cellSize;
|
|
156
|
+
cMaxY = cellSize;
|
|
157
|
+
}
|
|
158
|
+
const [ox, oy] = bundle.floor.origin;
|
|
159
|
+
const [fw, fh] = bundle.floor.size;
|
|
160
|
+
const floorPoints = [
|
|
161
|
+
[ox, oy],
|
|
162
|
+
[ox + fw, oy],
|
|
163
|
+
[ox, oy + fh],
|
|
164
|
+
[ox + fw, oy + fh]
|
|
165
|
+
];
|
|
166
|
+
let fMinX = Number.POSITIVE_INFINITY;
|
|
167
|
+
let fMinY = Number.POSITIVE_INFINITY;
|
|
168
|
+
let fMaxX = Number.NEGATIVE_INFINITY;
|
|
169
|
+
let fMaxY = Number.NEGATIVE_INFINITY;
|
|
170
|
+
for (const [x, y] of floorPoints) {
|
|
171
|
+
const { rawX, rawY } = projectToRaw(x, y, cellSize);
|
|
172
|
+
fMinX = Math.min(fMinX, rawX);
|
|
173
|
+
fMinY = Math.min(fMinY, rawY);
|
|
174
|
+
fMaxX = Math.max(fMaxX, rawX);
|
|
175
|
+
fMaxY = Math.max(fMaxY, rawY);
|
|
176
|
+
}
|
|
177
|
+
let sMinX;
|
|
178
|
+
let sMinY;
|
|
179
|
+
let sMaxX;
|
|
180
|
+
let sMaxY;
|
|
181
|
+
const mode = bundle.layout.bounds;
|
|
182
|
+
if (mode === "content") {
|
|
183
|
+
sMinX = cMinX;
|
|
184
|
+
sMinY = cMinY;
|
|
185
|
+
sMaxX = cMaxX;
|
|
186
|
+
sMaxY = cMaxY;
|
|
187
|
+
} else if (mode === "floor") {
|
|
188
|
+
sMinX = fMinX;
|
|
189
|
+
sMinY = fMinY;
|
|
190
|
+
sMaxX = fMaxX;
|
|
191
|
+
sMaxY = fMaxY;
|
|
192
|
+
} else {
|
|
193
|
+
sMinX = Math.min(cMinX, fMinX);
|
|
194
|
+
sMinY = Math.min(cMinY, fMinY);
|
|
195
|
+
sMaxX = Math.max(cMaxX, fMaxX);
|
|
196
|
+
sMaxY = Math.max(cMaxY, fMaxY);
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
cellSize,
|
|
200
|
+
padding,
|
|
201
|
+
selectedBounds: { minX: sMinX, minY: sMinY, maxX: sMaxX, maxY: sMaxY }
|
|
202
|
+
};
|
|
249
203
|
}
|
|
250
204
|
|
|
251
|
-
/**
|
|
252
|
-
* Create an editor runtime adapter around an already mounted scene.
|
|
253
|
-
* The adapter does not mutate the mounted scene or create editor UI.
|
|
254
|
-
*/
|
|
255
205
|
function createEditorRuntimeAdapter(mounted) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
206
|
+
const bundle = mounted.engine.bundle;
|
|
207
|
+
if (!bundle) {
|
|
208
|
+
throw new Error("EditorRuntimeAdapter requires an initialized mounted scene");
|
|
209
|
+
}
|
|
210
|
+
const layerOrder = bundle.layers.map((layer) => ({ name: layer.name, order: layer.order })).sort((a, b) => a.order - b.order || a.name.localeCompare(b.name));
|
|
211
|
+
return {
|
|
212
|
+
mounted,
|
|
213
|
+
setActiveScene(sceneId) {
|
|
214
|
+
const scene = bundle.scenes.find((candidate) => candidate.id === sceneId);
|
|
215
|
+
if (!scene) return false;
|
|
216
|
+
this.setProgress(scene.progress);
|
|
217
|
+
return true;
|
|
218
|
+
},
|
|
219
|
+
setProgress(progress) {
|
|
220
|
+
if (mounted.controller) {
|
|
221
|
+
mounted.controller.setProgress(progress);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
mounted.engine.setProgress(progress);
|
|
225
|
+
applyEditorFrame(mounted);
|
|
226
|
+
},
|
|
227
|
+
getObjects(sceneId) {
|
|
228
|
+
const currentState = mounted.engine.getCurrentState();
|
|
229
|
+
if (!currentState || currentState.id !== sceneId) return [];
|
|
230
|
+
const result = [];
|
|
231
|
+
for (const update of mounted.engine.getFrameUpdates()) {
|
|
232
|
+
const bounds = getEditorElementBounds(mounted, update.id, update.asset);
|
|
233
|
+
result.push({
|
|
234
|
+
id: update.id,
|
|
235
|
+
kind: "element",
|
|
236
|
+
sceneId: currentState.id,
|
|
237
|
+
layer: update.layer,
|
|
238
|
+
present: update.lifecycle !== "removed",
|
|
239
|
+
bounds: bounds ?? { minX: 0, minY: 0, width: 0, height: 0 },
|
|
240
|
+
grid: { kind: "element", at: update.pos, size: update.size }
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
for (const update of mounted.engine.getConnectorFrameUpdates()) {
|
|
244
|
+
const bounds = getConnectionBounds(update.route, bundle);
|
|
245
|
+
result.push({
|
|
246
|
+
id: update.id,
|
|
247
|
+
kind: "connection",
|
|
248
|
+
sceneId: currentState.id,
|
|
249
|
+
layer: update.layer,
|
|
250
|
+
present: update.lifecycle !== "removed",
|
|
251
|
+
bounds,
|
|
252
|
+
grid: { kind: "connection", route: update.route }
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
return result;
|
|
256
|
+
},
|
|
257
|
+
getObject(id) {
|
|
258
|
+
const currentState = mounted.engine.getCurrentState();
|
|
259
|
+
if (!currentState) return void 0;
|
|
260
|
+
const elementUpdate = mounted.engine.getElementUpdate(id);
|
|
261
|
+
if (elementUpdate && elementUpdate.asset !== "") {
|
|
262
|
+
const bounds = getEditorElementBounds(mounted, id, elementUpdate.asset);
|
|
263
|
+
return {
|
|
264
|
+
id: elementUpdate.id,
|
|
265
|
+
kind: "element",
|
|
266
|
+
sceneId: currentState.id,
|
|
267
|
+
layer: elementUpdate.layer,
|
|
268
|
+
present: elementUpdate.lifecycle !== "removed",
|
|
269
|
+
bounds: bounds ?? { minX: 0, minY: 0, width: 0, height: 0 },
|
|
270
|
+
grid: { kind: "element", at: elementUpdate.pos, size: elementUpdate.size }
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
const connectorUpdate = mounted.engine.getConnectorUpdate(id);
|
|
274
|
+
if (connectorUpdate && connectorUpdate.route.length > 0) {
|
|
275
|
+
const bounds = getConnectionBounds(connectorUpdate.route, bundle);
|
|
276
|
+
return {
|
|
277
|
+
id: connectorUpdate.id,
|
|
278
|
+
kind: "connection",
|
|
279
|
+
sceneId: currentState.id,
|
|
280
|
+
layer: connectorUpdate.layer,
|
|
281
|
+
present: connectorUpdate.lifecycle !== "removed",
|
|
282
|
+
bounds,
|
|
283
|
+
grid: { kind: "connection", route: connectorUpdate.route }
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
return void 0;
|
|
287
|
+
},
|
|
288
|
+
getLayerOrder() {
|
|
289
|
+
return layerOrder.slice();
|
|
290
|
+
},
|
|
291
|
+
getResolvedViewBox() {
|
|
292
|
+
return getResolvedViewBox(bundle);
|
|
293
|
+
},
|
|
294
|
+
projectGridPoint(point) {
|
|
295
|
+
return projectGridPoint(bundle, point);
|
|
296
|
+
},
|
|
297
|
+
unprojectScreenPoint(point) {
|
|
298
|
+
return unprojectScreenPoint(bundle, point);
|
|
299
|
+
},
|
|
300
|
+
clientPointToSvgPoint(point) {
|
|
301
|
+
return clientPointToSvgPoint(mounted.svg, point);
|
|
302
|
+
},
|
|
303
|
+
getGridCellPolygon(cell) {
|
|
304
|
+
return getGridCellPolygon(bundle, cell);
|
|
305
|
+
},
|
|
306
|
+
getObjectAtPoint(point, options) {
|
|
307
|
+
return getRuntimeObjectAtPoint(this, point, options);
|
|
308
|
+
},
|
|
309
|
+
getSelectionBounds(ids) {
|
|
310
|
+
return getRuntimeSelectionBounds(this, ids);
|
|
311
|
+
},
|
|
312
|
+
destroy() {
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
function getEditorElementBounds(mounted, id, asset) {
|
|
317
|
+
if (asset === "text") {
|
|
318
|
+
const rect = getElementState(mounted.svg, id)?.node.getBoundingClientRect();
|
|
319
|
+
if (rect && rect.width > 0 && rect.height > 0) {
|
|
320
|
+
const topLeft = clientPointToSvgPoint(mounted.svg, { clientX: rect.left, clientY: rect.top });
|
|
321
|
+
const bottomRight = clientPointToSvgPoint(mounted.svg, { clientX: rect.right, clientY: rect.bottom });
|
|
322
|
+
return { minX: topLeft.x, minY: topLeft.y, width: bottomRight.x - topLeft.x, height: bottomRight.y - topLeft.y };
|
|
259
323
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
.map((layer) => ({ name: layer.name, order: layer.order }))
|
|
263
|
-
.sort((a, b) => a.order - b.order || a.name.localeCompare(b.name));
|
|
264
|
-
return {
|
|
265
|
-
mounted,
|
|
266
|
-
setActiveScene(sceneId) {
|
|
267
|
-
const scene = bundle.scenes.find((candidate) => candidate.id === sceneId);
|
|
268
|
-
if (!scene)
|
|
269
|
-
return false;
|
|
270
|
-
this.setProgress(scene.progress);
|
|
271
|
-
return true;
|
|
272
|
-
},
|
|
273
|
-
setProgress(progress) {
|
|
274
|
-
mounted.engine.setProgress(progress);
|
|
275
|
-
applyEditorFrame(mounted);
|
|
276
|
-
},
|
|
277
|
-
getObjects(sceneId) {
|
|
278
|
-
const currentState = mounted.engine.getCurrentState();
|
|
279
|
-
if (!currentState || currentState.id !== sceneId)
|
|
280
|
-
return [];
|
|
281
|
-
const result = [];
|
|
282
|
-
// Elements from current engine frame
|
|
283
|
-
for (const update of mounted.engine.getFrameUpdates()) {
|
|
284
|
-
const bounds = getCurrentElementBounds(mounted.svg, update.id);
|
|
285
|
-
result.push({
|
|
286
|
-
id: update.id,
|
|
287
|
-
kind: "element",
|
|
288
|
-
sceneId: currentState.id,
|
|
289
|
-
layer: update.layer,
|
|
290
|
-
present: update.lifecycle !== "removed",
|
|
291
|
-
bounds: bounds ?? { minX: 0, minY: 0, width: 0, height: 0 },
|
|
292
|
-
grid: { kind: "element", at: update.pos, size: update.size },
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
// Connections from current engine frame
|
|
296
|
-
for (const update of mounted.engine.getConnectorFrameUpdates()) {
|
|
297
|
-
const bounds = getConnectionBounds(update.route, bundle);
|
|
298
|
-
result.push({
|
|
299
|
-
id: update.id,
|
|
300
|
-
kind: "connection",
|
|
301
|
-
sceneId: currentState.id,
|
|
302
|
-
layer: update.layer,
|
|
303
|
-
present: update.lifecycle !== "removed",
|
|
304
|
-
bounds,
|
|
305
|
-
grid: { kind: "connection", route: update.route },
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
return result;
|
|
309
|
-
},
|
|
310
|
-
getObject(id) {
|
|
311
|
-
const currentState = mounted.engine.getCurrentState();
|
|
312
|
-
if (!currentState)
|
|
313
|
-
return undefined;
|
|
314
|
-
const elementUpdate = mounted.engine.getElementUpdate(id);
|
|
315
|
-
if (elementUpdate && elementUpdate.asset !== "") {
|
|
316
|
-
const bounds = getCurrentElementBounds(mounted.svg, id);
|
|
317
|
-
return {
|
|
318
|
-
id: elementUpdate.id,
|
|
319
|
-
kind: "element",
|
|
320
|
-
sceneId: currentState.id,
|
|
321
|
-
layer: elementUpdate.layer,
|
|
322
|
-
present: elementUpdate.lifecycle !== "removed",
|
|
323
|
-
bounds: bounds ?? { minX: 0, minY: 0, width: 0, height: 0 },
|
|
324
|
-
grid: { kind: "element", at: elementUpdate.pos, size: elementUpdate.size },
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
const connectorUpdate = mounted.engine.getConnectorUpdate(id);
|
|
328
|
-
if (connectorUpdate && connectorUpdate.route.length > 0) {
|
|
329
|
-
const bounds = getConnectionBounds(connectorUpdate.route, bundle);
|
|
330
|
-
return {
|
|
331
|
-
id: connectorUpdate.id,
|
|
332
|
-
kind: "connection",
|
|
333
|
-
sceneId: currentState.id,
|
|
334
|
-
layer: connectorUpdate.layer,
|
|
335
|
-
present: connectorUpdate.lifecycle !== "removed",
|
|
336
|
-
bounds,
|
|
337
|
-
grid: { kind: "connection", route: connectorUpdate.route },
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
return undefined;
|
|
341
|
-
},
|
|
342
|
-
getLayerOrder() {
|
|
343
|
-
return layerOrder.slice();
|
|
344
|
-
},
|
|
345
|
-
getResolvedViewBox() {
|
|
346
|
-
return getResolvedViewBox(bundle);
|
|
347
|
-
},
|
|
348
|
-
projectGridPoint(point) {
|
|
349
|
-
return projectGridPoint(bundle, point);
|
|
350
|
-
},
|
|
351
|
-
unprojectScreenPoint(point) {
|
|
352
|
-
return unprojectScreenPoint(bundle, point);
|
|
353
|
-
},
|
|
354
|
-
clientPointToSvgPoint(point) {
|
|
355
|
-
return clientPointToSvgPoint(mounted.svg, point);
|
|
356
|
-
},
|
|
357
|
-
getGridCellPolygon(cell) {
|
|
358
|
-
return getGridCellPolygon(bundle, cell);
|
|
359
|
-
},
|
|
360
|
-
getObjectAtPoint(point, options) {
|
|
361
|
-
return getRuntimeObjectAtPoint(this, point, options);
|
|
362
|
-
},
|
|
363
|
-
getSelectionBounds(ids) {
|
|
364
|
-
return getRuntimeSelectionBounds(this, ids);
|
|
365
|
-
},
|
|
366
|
-
destroy() {
|
|
367
|
-
// Adapter owns no listeners or caches that outlive this call.
|
|
368
|
-
// The editor is responsible for mounted scene cleanup.
|
|
369
|
-
},
|
|
370
|
-
};
|
|
324
|
+
}
|
|
325
|
+
return getCurrentElementBounds(mounted.svg, id);
|
|
371
326
|
}
|
|
372
327
|
function applyEditorFrame(mounted) {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
}
|
|
328
|
+
const elements = mounted.engine.getFrameUpdates().map((update) => ({
|
|
329
|
+
id: update.id,
|
|
330
|
+
asset: update.asset,
|
|
331
|
+
pos: update.pos,
|
|
332
|
+
size: update.size,
|
|
333
|
+
layer: update.layer,
|
|
334
|
+
presence: update.lifecycle,
|
|
335
|
+
enter: update.entry,
|
|
336
|
+
exit: update.exit,
|
|
337
|
+
ambient: update.ambient,
|
|
338
|
+
text: update.text,
|
|
339
|
+
primitive: update.primitive,
|
|
340
|
+
activity: update.activity
|
|
341
|
+
}));
|
|
342
|
+
const connectors = mounted.engine.getConnectorFrameUpdates().map((update) => ({
|
|
343
|
+
id: update.id,
|
|
344
|
+
route: update.route,
|
|
345
|
+
layer: update.layer,
|
|
346
|
+
presence: update.lifecycle,
|
|
347
|
+
style: update.style,
|
|
348
|
+
start: update.start,
|
|
349
|
+
end: update.end,
|
|
350
|
+
direction: update.direction,
|
|
351
|
+
enter: update.entry,
|
|
352
|
+
exit: update.exit,
|
|
353
|
+
ambient: update.ambient,
|
|
354
|
+
message: update.message
|
|
355
|
+
}));
|
|
356
|
+
for (const element of elements) {
|
|
357
|
+
const state = getElementState(mounted.svg, element.id);
|
|
358
|
+
if (!state) continue;
|
|
359
|
+
if (element.presence === "removed") {
|
|
360
|
+
state.isHidden = true;
|
|
361
|
+
hideElementAfterExit(state.node);
|
|
362
|
+
} else {
|
|
363
|
+
state.isHidden = false;
|
|
364
|
+
unhideElementOnReadd(state.node);
|
|
411
365
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
unhideElementOnReadd(state.node);
|
|
423
|
-
}
|
|
366
|
+
}
|
|
367
|
+
for (const connector of connectors) {
|
|
368
|
+
const state = getConnectorState(mounted.svg, connector.id);
|
|
369
|
+
if (!state) continue;
|
|
370
|
+
if (connector.presence === "removed") {
|
|
371
|
+
state.isHidden = true;
|
|
372
|
+
hideElementAfterExit(state.node);
|
|
373
|
+
} else {
|
|
374
|
+
state.isHidden = false;
|
|
375
|
+
unhideElementOnReadd(state.node);
|
|
424
376
|
}
|
|
425
|
-
|
|
377
|
+
}
|
|
378
|
+
updateElementTransforms(mounted.svg, elements, connectors);
|
|
426
379
|
}
|
|
427
380
|
|
|
428
381
|
export { clientPointToSvgPoint, createEditorRuntimeAdapter, getGridCellPolygon, getRuntimeObjectAtPoint, getRuntimeSelectionBounds, projectGridPoint, unprojectScreenPoint };
|