@jamesyong42/infinite-canvas 1.2.0 → 1.3.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/README.md +65 -0
- package/dist/advanced.cjs +61 -24
- package/dist/advanced.cjs.map +1 -1
- package/dist/advanced.d.cts +180 -64
- package/dist/advanced.d.cts.map +1 -1
- package/dist/advanced.d.mts +180 -64
- package/dist/advanced.d.mts.map +1 -1
- package/dist/advanced.mjs +29 -12
- package/dist/advanced.mjs.map +1 -1
- package/dist/devtools.cjs +22 -22
- package/dist/devtools.cjs.map +1 -1
- package/dist/devtools.d.cts +2 -2
- package/dist/devtools.d.cts.map +1 -1
- package/dist/devtools.d.mts +2 -2
- package/dist/devtools.d.mts.map +1 -1
- package/dist/devtools.mjs +2 -2
- package/dist/devtools.mjs.map +1 -1
- package/dist/{hooks-BwY7rRHg.mjs → ecs-3kimUV5Z.mjs} +238 -74
- package/dist/ecs-3kimUV5Z.mjs.map +1 -0
- package/dist/{hooks-DHShH86C.cjs → ecs-B4QrqfvQ.cjs} +320 -108
- package/dist/ecs-B4QrqfvQ.cjs.map +1 -0
- package/dist/hooks-CtP02JNt.cjs +3762 -0
- package/dist/hooks-CtP02JNt.cjs.map +1 -0
- package/dist/hooks-gsQDDE56.mjs +3494 -0
- package/dist/hooks-gsQDDE56.mjs.map +1 -0
- package/dist/index-3GY7T8JM.d.mts +480 -0
- package/dist/index-3GY7T8JM.d.mts.map +1 -0
- package/dist/index-B7B1tRPl.d.cts +480 -0
- package/dist/index-B7B1tRPl.d.cts.map +1 -0
- package/dist/index-DSdbSQ_t.d.cts +1451 -0
- package/dist/index-DSdbSQ_t.d.cts.map +1 -0
- package/dist/index-Dj9odADH.d.mts +1451 -0
- package/dist/index-Dj9odADH.d.mts.map +1 -0
- package/dist/index.cjs +3865 -643
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +315 -138
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +315 -138
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3767 -571
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/SelectionRenderer-CR2PBQwx.d.cts +0 -105
- package/dist/SelectionRenderer-CR2PBQwx.d.cts.map +0 -1
- package/dist/SelectionRenderer-DlsBstAq.d.mts +0 -105
- package/dist/SelectionRenderer-DlsBstAq.d.mts.map +0 -1
- package/dist/WebGLWidgetLayer-BBMuwzHq.cjs +0 -3560
- package/dist/WebGLWidgetLayer-BBMuwzHq.cjs.map +0 -1
- package/dist/WebGLWidgetLayer-C3p1tnpm.mjs +0 -3375
- package/dist/WebGLWidgetLayer-C3p1tnpm.mjs.map +0 -1
- package/dist/engine-BfbvWXSk.d.mts +0 -982
- package/dist/engine-BfbvWXSk.d.mts.map +0 -1
- package/dist/engine-CCjuFMC-.d.cts +0 -982
- package/dist/engine-CCjuFMC-.d.cts.map +0 -1
- package/dist/hooks-BwY7rRHg.mjs.map +0 -1
- package/dist/hooks-DHShH86C.cjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
require("./
|
|
1
|
+
require("./hooks-CtP02JNt.cjs");
|
|
2
2
|
let _jamesyong42_reactive_ecs = require("@jamesyong42/reactive-ecs");
|
|
3
3
|
let react = require("react");
|
|
4
|
-
//#region src/components.ts
|
|
4
|
+
//#region src/ecs/components.ts
|
|
5
5
|
/** Position, size, and rotation of an entity in local coordinates (world units). */
|
|
6
6
|
const Transform2D = (0, _jamesyong42_reactive_ecs.defineComponent)("Transform2D", {
|
|
7
7
|
x: 0,
|
|
@@ -10,19 +10,57 @@ const Transform2D = (0, _jamesyong42_reactive_ecs.defineComponent)("Transform2D"
|
|
|
10
10
|
height: 100,
|
|
11
11
|
rotation: 0
|
|
12
12
|
});
|
|
13
|
-
/** Computed world-space bounding box. Read-only -- updated by the transform propagation system. */
|
|
14
|
-
const WorldBounds = (0, _jamesyong42_reactive_ecs.defineComponent)("WorldBounds", {
|
|
15
|
-
worldX: 0,
|
|
16
|
-
worldY: 0,
|
|
17
|
-
worldWidth: 0,
|
|
18
|
-
worldHeight: 0
|
|
19
|
-
});
|
|
20
13
|
/** Rendering and hit-test ordering. Higher values render on top. */
|
|
21
14
|
const ZIndex = (0, _jamesyong42_reactive_ecs.defineComponent)("ZIndex", { value: 0 });
|
|
22
|
-
/**
|
|
23
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Generic animated transition of `Transform2D.x` / `.y` over time.
|
|
17
|
+
* Runtime-only: the tween component is auto-removed on completion,
|
|
18
|
+
* and in-flight tweens are not serialized (the destination Transform2D
|
|
19
|
+
* is what survives a save/load).
|
|
20
|
+
*
|
|
21
|
+
* Introduced for RFC-004 Phase 4 fly-back but designed to be reusable
|
|
22
|
+
* for any future position-animation need (snap, drop-in, consume-pop).
|
|
23
|
+
* Starting a new tween on an entity that already has one overwrites.
|
|
24
|
+
*/
|
|
25
|
+
const TransformTween = (0, _jamesyong42_reactive_ecs.defineComponent)("TransformTween", {
|
|
26
|
+
fromX: 0,
|
|
27
|
+
fromY: 0,
|
|
28
|
+
toX: 0,
|
|
29
|
+
toY: 0,
|
|
30
|
+
/** `performance.now()`-ish timestamp captured at tween start. */
|
|
31
|
+
startMs: 0,
|
|
32
|
+
/** Total duration in ms. */
|
|
33
|
+
durationMs: 250,
|
|
34
|
+
easing: "ease-out",
|
|
35
|
+
/**
|
|
36
|
+
* Discriminator so downstream systems can react per kind
|
|
37
|
+
* (e.g. `'flyback'`, `'snap'`, `'spawn'`). The tween system
|
|
38
|
+
* itself is kind-agnostic.
|
|
39
|
+
*/
|
|
40
|
+
kind: "generic"
|
|
41
|
+
});
|
|
42
|
+
/**
|
|
43
|
+
* Container-hierarchy parenthood: the entity lives inside another
|
|
44
|
+
* entity's sub-canvas. Read by `navigationFilterSystem` to filter the
|
|
45
|
+
* active widget set by the current navigation frame.
|
|
46
|
+
*
|
|
47
|
+
* Container children have their own `Transform2D` in the container's
|
|
48
|
+
* local coord space — **no coord accumulation** through this reference.
|
|
49
|
+
* Replaces the old `Parent` component's container-hierarchy usage
|
|
50
|
+
* (RFC-005).
|
|
51
|
+
*/
|
|
52
|
+
const ParentFrame = (0, _jamesyong42_reactive_ecs.defineComponent)("ParentFrame", { id: 0 });
|
|
24
53
|
/** Child entity IDs. Used for nested containers and handle sync. */
|
|
25
54
|
const Children = (0, _jamesyong42_reactive_ecs.defineComponent)("Children", { ids: [] });
|
|
55
|
+
/**
|
|
56
|
+
* Ordered list of the entities a container owns (RFC-004 § Phase 5).
|
|
57
|
+
* Redundant with `ParentFrame` (the inverse relation) but materialised
|
|
58
|
+
* so UI / compositor paths can cheaply read "give me this container's
|
|
59
|
+
* children" without a reverse-index scan. `applyMutation` /
|
|
60
|
+
* `revertMutation` keep the two in sync. Serialized; IDs are remapped
|
|
61
|
+
* alongside `ParentFrame` on load.
|
|
62
|
+
*/
|
|
63
|
+
const ContainerChildren = (0, _jamesyong42_reactive_ecs.defineComponent)("ContainerChildren", { ids: [] });
|
|
26
64
|
/** Marks an entity as a renderable widget with a type identifier and rendering surface. */
|
|
27
65
|
const Widget = (0, _jamesyong42_reactive_ecs.defineComponent)("Widget", {
|
|
28
66
|
surface: "dom",
|
|
@@ -37,38 +75,100 @@ const WidgetBreakpoint = (0, _jamesyong42_reactive_ecs.defineComponent)("WidgetB
|
|
|
37
75
|
screenHeight: 0
|
|
38
76
|
});
|
|
39
77
|
/**
|
|
40
|
-
* Marks an entity as an iOS-style card with a fixed preset size
|
|
41
|
-
*
|
|
42
|
-
*
|
|
78
|
+
* Marks an entity as an iOS-style card with a fixed preset size, AND
|
|
79
|
+
* opts the entity into the full card-shaped behavior bundle:
|
|
80
|
+
*
|
|
81
|
+
* - DOM `<CardChrome>` slot (rounded body, hairline ring, shadow,
|
|
82
|
+
* CSS lift transition on Dragging)
|
|
83
|
+
* - drag-promote to the 'overlay' layer for DOM cards (so dragged
|
|
84
|
+
* DOM cards visually pop above the R3F canvas)
|
|
85
|
+
* - composition discard rect for R3F cards (so other R3F widgets
|
|
86
|
+
* are clipped out of the dragged card's screen rect — defends
|
|
87
|
+
* the chrome from being painted over)
|
|
88
|
+
* - drop-to-consume contracts (`accepts` / `provides`) — RFC-004.
|
|
89
|
+
*
|
|
90
|
+
* Widgets *without* `Card` get none of this — they render bare (no
|
|
91
|
+
* chrome, no lift transition), and on drag they only get the
|
|
92
|
+
* compositor's renderOrder bump if they're R3F (so they stack on
|
|
93
|
+
* top of other R3F widgets they overlap).
|
|
94
|
+
*
|
|
95
|
+
* The `cardSystem` reconciles `Transform2D.width/height` from the
|
|
96
|
+
* preset each tick, so cards cannot be resized freely — change
|
|
97
|
+
* `preset` instead.
|
|
98
|
+
*/
|
|
99
|
+
const Card = (0, _jamesyong42_reactive_ecs.defineComponent)("Card", {
|
|
100
|
+
preset: "small",
|
|
101
|
+
/**
|
|
102
|
+
* CSS background for the chrome's surface (any valid background value;
|
|
103
|
+
* defaults to the dark iOS card colour). Picked up by the
|
|
104
|
+
* `<CardChrome>` component rendered for this entity.
|
|
105
|
+
*/
|
|
106
|
+
background: "#1C1C1E",
|
|
107
|
+
/**
|
|
108
|
+
* Drop-to-consume contract — what this card accepts as a *parent*.
|
|
109
|
+
* An incoming dragged card's `provides` must intersect this list
|
|
110
|
+
* for the consume mechanic to fire (RFC-004 § Phase 3). Empty
|
|
111
|
+
* array = card never consumes anything.
|
|
112
|
+
*/
|
|
113
|
+
accepts: [],
|
|
114
|
+
/**
|
|
115
|
+
* Drop-to-consume contract — what this card offers when dropped
|
|
116
|
+
* as a *child*. Empty array = card is never consumed by anything.
|
|
117
|
+
*/
|
|
118
|
+
provides: []
|
|
119
|
+
});
|
|
120
|
+
/**
|
|
121
|
+
* Transient — set by the card-overlap pass on every card whose AABB
|
|
122
|
+
* intersects the dragged card's AABB during drag. Layer 1 of the
|
|
123
|
+
* two-layer overlap visual state (RFC-004 § Phase 3). Cleared on drag
|
|
124
|
+
* end. Runtime-only — not serialized.
|
|
43
125
|
*/
|
|
44
|
-
const
|
|
126
|
+
const OverlapCandidate = (0, _jamesyong42_reactive_ecs.defineTag)("OverlapCandidate");
|
|
127
|
+
/**
|
|
128
|
+
* Transient — set on the single primary candidate (closest centre
|
|
129
|
+
* distance) iff its `accepts` contract intersects the dragged card's
|
|
130
|
+
* `provides` contract AND the optional `canAccept` gate passes.
|
|
131
|
+
* Layer 2 of the two-layer overlap visual state. Cleared on drag end
|
|
132
|
+
* or when match becomes false. Runtime-only — not serialized.
|
|
133
|
+
*/
|
|
134
|
+
const OverlapTarget = (0, _jamesyong42_reactive_ecs.defineTag)("OverlapTarget");
|
|
135
|
+
/**
|
|
136
|
+
* Per-candidate "hot point" for the position-dependent radial glow
|
|
137
|
+
* (RFC-004 § Phase 3). `x` and `y` are normalized [0..1] local coords
|
|
138
|
+
* within the overlapped card, pointing at the intersection centroid.
|
|
139
|
+
* `strength` ramps between 0 and 1 for the fade-in / fade-out.
|
|
140
|
+
* Runtime-only — not serialized.
|
|
141
|
+
*/
|
|
142
|
+
const CardOverlapHotPoint = (0, _jamesyong42_reactive_ecs.defineComponent)("CardOverlapHotPoint", {
|
|
143
|
+
x: .5,
|
|
144
|
+
y: .5,
|
|
145
|
+
strength: 0
|
|
146
|
+
});
|
|
45
147
|
/** Marks an entity as an enterable container (double-click/double-tap to enter). */
|
|
46
148
|
const Container = (0, _jamesyong42_reactive_ecs.defineComponent)("Container", { enterable: true });
|
|
47
149
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
150
|
+
* Per-container persistent camera state. When the user navigates out of
|
|
151
|
+
* a container, their current pan/zoom is snapshotted here; when they
|
|
152
|
+
* navigate back in, it's restored. Serialized — containers remember
|
|
153
|
+
* their view across save/load (RFC-004 § Phase 0c).
|
|
52
154
|
*/
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
height: 0
|
|
155
|
+
const ContainerCamera = (0, _jamesyong42_reactive_ecs.defineComponent)("ContainerCamera", {
|
|
156
|
+
x: 0,
|
|
157
|
+
y: 0,
|
|
158
|
+
zoom: 1
|
|
58
159
|
});
|
|
59
160
|
/**
|
|
60
161
|
* Declares what happens when this entity is hit, plus its hit-test priority.
|
|
61
|
-
* Canonical layers: 0=canvas, 5=widget body,
|
|
162
|
+
* Canonical layers: 0=canvas, 5=widget body, 20=reserved.
|
|
163
|
+
*
|
|
164
|
+
* Resize corner/edge roles are emitted inline by `interaction.ts` from the
|
|
165
|
+
* selected `Resizable` widget's Transform2D; they are NOT stored as
|
|
166
|
+
* per-handle entities (RFC-005).
|
|
62
167
|
*/
|
|
63
168
|
const InteractionRole = (0, _jamesyong42_reactive_ecs.defineComponent)("InteractionRole", {
|
|
64
169
|
layer: 0,
|
|
65
170
|
role: { type: "canvas" }
|
|
66
171
|
});
|
|
67
|
-
/**
|
|
68
|
-
* Component on the parent entity listing the EntityIds of its spawned handle children.
|
|
69
|
-
* Enables O(1) cascade destroy without a reverse-index scan of Parent components.
|
|
70
|
-
*/
|
|
71
|
-
const HandleSet = (0, _jamesyong42_reactive_ecs.defineComponent)("HandleSet", { ids: [] });
|
|
72
172
|
/** Declares the cursor this entity requests when hovered and when active. */
|
|
73
173
|
const CursorHint = (0, _jamesyong42_reactive_ecs.defineComponent)("CursorHint", {
|
|
74
174
|
hover: "default",
|
|
@@ -80,6 +180,32 @@ const Selectable = (0, _jamesyong42_reactive_ecs.defineTag)("Selectable");
|
|
|
80
180
|
const Draggable = (0, _jamesyong42_reactive_ecs.defineTag)("Draggable");
|
|
81
181
|
/** Marks an entity as resizable via edge/corner handles. */
|
|
82
182
|
const Resizable = (0, _jamesyong42_reactive_ecs.defineTag)("Resizable");
|
|
183
|
+
/**
|
|
184
|
+
* Marks an entity that, when dragged, runs alignment-snap math against
|
|
185
|
+
* the set of `SnapTarget` entities. Without this tag, dragging proceeds
|
|
186
|
+
* with raw pointer deltas (no snapping). Independent of `SnapTarget`:
|
|
187
|
+
* an entity can be a source without being a target (rare) or a target
|
|
188
|
+
* without being a source (e.g. cards — they participate as references
|
|
189
|
+
* for other widgets but never snap themselves).
|
|
190
|
+
*
|
|
191
|
+
* Multi-select drag: only the first selected entity's bounds drive the
|
|
192
|
+
* snap calculation; followers receive the same correction delta. Tag a
|
|
193
|
+
* follower-only entity with `SnapSource` if you also want it to lead a
|
|
194
|
+
* single-entity drag, but be aware its geometry is ignored when it is
|
|
195
|
+
* being dragged as part of a multi-select group.
|
|
196
|
+
*/
|
|
197
|
+
const SnapSource = (0, _jamesyong42_reactive_ecs.defineTag)("SnapSource");
|
|
198
|
+
/**
|
|
199
|
+
* Marks an entity whose bounds are usable as a snap reference when
|
|
200
|
+
* another `SnapSource` entity is being dragged. References are further
|
|
201
|
+
* filtered by `Active`, so only entities in the current navigation
|
|
202
|
+
* frame can pull a drag — a `SnapTarget` inside a closed container
|
|
203
|
+
* does not leak into a root-level drag. Visibility of the resulting
|
|
204
|
+
* guide lines is controlled separately by the engine's
|
|
205
|
+
* `snap.guidesVisible` config — this tag only governs participation
|
|
206
|
+
* in the math.
|
|
207
|
+
*/
|
|
208
|
+
const SnapTarget = (0, _jamesyong42_reactive_ecs.defineTag)("SnapTarget");
|
|
83
209
|
/** Prevents an entity from being moved or resized. */
|
|
84
210
|
const Locked = (0, _jamesyong42_reactive_ecs.defineTag)("Locked");
|
|
85
211
|
/** Indicates the entity is currently selected. */
|
|
@@ -101,18 +227,41 @@ const SelectionFrame = (0, _jamesyong42_reactive_ecs.defineTag)("SelectionFrame"
|
|
|
101
227
|
const Active = (0, _jamesyong42_reactive_ecs.defineTag)("Active");
|
|
102
228
|
/** Indicates the entity is within the visible viewport. Set by the cull system. */
|
|
103
229
|
const Visible = (0, _jamesyong42_reactive_ecs.defineTag)("Visible");
|
|
230
|
+
/**
|
|
231
|
+
* Indicates the entity is `Active` but **outside** the visible viewport
|
|
232
|
+
* (+overscan). The complement of `Visible` for Active entities — the cull
|
|
233
|
+
* system maintains the invariant that every Active entity carries exactly
|
|
234
|
+
* one of `Visible` or `Culled`.
|
|
235
|
+
*
|
|
236
|
+
* Render layers consume this to keep state cached without rendering: DOM
|
|
237
|
+
* widgets may stay mounted-but-hidden for fast re-reveal, and the R3F
|
|
238
|
+
* compositor (RFC-002) holds widget render targets in its Cold pool.
|
|
239
|
+
*/
|
|
240
|
+
const Culled = (0, _jamesyong42_reactive_ecs.defineTag)("Culled");
|
|
241
|
+
const Layer = (0, _jamesyong42_reactive_ecs.defineComponent)("Layer", { name: "base" });
|
|
242
|
+
const PreDragLayer = (0, _jamesyong42_reactive_ecs.defineComponent)("PreDragLayer", { name: "base" });
|
|
104
243
|
//#endregion
|
|
105
|
-
//#region src/resources.ts
|
|
244
|
+
//#region src/ecs/resources.ts
|
|
106
245
|
/**
|
|
107
246
|
* Output sink for the cursor system. Written by cursorSystem each tick;
|
|
108
247
|
* read by the RAF loop to apply style.cursor on the root container div.
|
|
109
248
|
*/
|
|
110
249
|
const CursorResource = (0, _jamesyong42_reactive_ecs.defineResource)("Cursor", { cursor: "default" });
|
|
111
|
-
/**
|
|
250
|
+
/**
|
|
251
|
+
* Camera state: world-space position (x, y) and zoom level.
|
|
252
|
+
*
|
|
253
|
+
* `gesturing` is true while the user is actively manipulating the camera
|
|
254
|
+
* (continuous wheel zoom, pinch, two-finger pan). Set/cleared by gesture
|
|
255
|
+
* handlers via {@link LayoutEngine.setGesturing}; render layers can use it
|
|
256
|
+
* to defer expensive work (e.g. the R3F compositor skips zoom-band
|
|
257
|
+
* repaints while gesturing so a continuous pinch doesn't trigger a
|
|
258
|
+
* repaint storm across every visible widget).
|
|
259
|
+
*/
|
|
112
260
|
const CameraResource = (0, _jamesyong42_reactive_ecs.defineResource)("Camera", {
|
|
113
261
|
x: 0,
|
|
114
262
|
y: 0,
|
|
115
|
-
zoom: 1
|
|
263
|
+
zoom: 1,
|
|
264
|
+
gesturing: false
|
|
116
265
|
});
|
|
117
266
|
/** Viewport dimensions in CSS pixels and device pixel ratio. Updated on resize. */
|
|
118
267
|
const ViewportResource = (0, _jamesyong42_reactive_ecs.defineResource)("Viewport", {
|
|
@@ -132,57 +281,77 @@ const BreakpointConfigResource = (0, _jamesyong42_reactive_ecs.defineResource)("
|
|
|
132
281
|
normal: 500,
|
|
133
282
|
expanded: 1200
|
|
134
283
|
});
|
|
135
|
-
/**
|
|
284
|
+
/**
|
|
285
|
+
* Navigation stack for hierarchical container traversal. Always has at
|
|
286
|
+
* least one frame (the root). The last element is the current frame;
|
|
287
|
+
* `containerId === null` means the user is at the root canvas.
|
|
288
|
+
*
|
|
289
|
+
* Runtime-only view state — deliberately not serialized, so reloading a
|
|
290
|
+
* saved canvas always drops the user at the root frame (RFC-004 § Phase 0c).
|
|
291
|
+
*/
|
|
136
292
|
const NavigationStackResource = (0, _jamesyong42_reactive_ecs.defineResource)("NavigationStack", {
|
|
137
|
-
frames: [{
|
|
138
|
-
containerId: null,
|
|
139
|
-
camera: {
|
|
140
|
-
x: 0,
|
|
141
|
-
y: 0,
|
|
142
|
-
zoom: 1
|
|
143
|
-
}
|
|
144
|
-
}],
|
|
293
|
+
frames: [{ containerId: null }],
|
|
145
294
|
changed: false
|
|
146
295
|
});
|
|
147
296
|
/**
|
|
297
|
+
* Camera state for the root canvas. Persisted (serialized) so the root
|
|
298
|
+
* view returns to its previous pan/zoom across navigation push/pop and
|
|
299
|
+
* across save/load. Container frames use the `ContainerCamera` component
|
|
300
|
+
* on the container entity instead (RFC-004 § Phase 0c).
|
|
301
|
+
*/
|
|
302
|
+
const RootCameraResource = (0, _jamesyong42_reactive_ecs.defineResource)("RootCamera", {
|
|
303
|
+
x: 0,
|
|
304
|
+
y: 0,
|
|
305
|
+
zoom: 1
|
|
306
|
+
});
|
|
307
|
+
/**
|
|
308
|
+
* Built-in card preset sizes (iOS widget conventions — 155×155 tile).
|
|
309
|
+
* Single source of truth consumed by:
|
|
310
|
+
* - {@link CardPresetsResource} — runtime lookup by the cardSystem.
|
|
311
|
+
* - `createCardWidget` / `createGeometryCardWidget` — widget-registration-
|
|
312
|
+
* time `defaultSize`, which must be known before the engine is built.
|
|
313
|
+
*/
|
|
314
|
+
const DEFAULT_CARD_PRESET_SIZES = {
|
|
315
|
+
small: {
|
|
316
|
+
width: 155,
|
|
317
|
+
height: 155
|
|
318
|
+
},
|
|
319
|
+
medium: {
|
|
320
|
+
width: 329,
|
|
321
|
+
height: 155
|
|
322
|
+
},
|
|
323
|
+
large: {
|
|
324
|
+
width: 329,
|
|
325
|
+
height: 345
|
|
326
|
+
},
|
|
327
|
+
xl: {
|
|
328
|
+
width: 329,
|
|
329
|
+
height: 535
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
/**
|
|
148
333
|
* iOS-style card preset size map. Lookup happens by `Card.preset`; the
|
|
149
334
|
* `cardSystem` stamps `Transform2D.width/height` from the resolved size.
|
|
150
335
|
*
|
|
151
|
-
* Defaults mirror iOS widget conventions — 155×155 tile + 19px gap.
|
|
152
336
|
* Override at `createLayoutEngine({ cardPresets })` for tablet-scale or
|
|
153
337
|
* custom design systems.
|
|
154
338
|
*/
|
|
155
339
|
const CardPresetsResource = (0, _jamesyong42_reactive_ecs.defineResource)("CardPresets", {
|
|
156
|
-
presets: {
|
|
157
|
-
small: {
|
|
158
|
-
width: 155,
|
|
159
|
-
height: 155
|
|
160
|
-
},
|
|
161
|
-
medium: {
|
|
162
|
-
width: 329,
|
|
163
|
-
height: 155
|
|
164
|
-
},
|
|
165
|
-
large: {
|
|
166
|
-
width: 329,
|
|
167
|
-
height: 345
|
|
168
|
-
},
|
|
169
|
-
xl: {
|
|
170
|
-
width: 329,
|
|
171
|
-
height: 535
|
|
172
|
-
}
|
|
173
|
-
},
|
|
340
|
+
presets: { ...DEFAULT_CARD_PRESET_SIZES },
|
|
174
341
|
/** Gap between adjacent tiles (future tile-snap system reads this). */
|
|
175
342
|
gap: 19
|
|
176
343
|
});
|
|
344
|
+
/** ECS resource holding the SpatialIndex instance for viewport culling and hit testing. */
|
|
345
|
+
const SpatialIndexResource = (0, _jamesyong42_reactive_ecs.defineResource)("SpatialIndex", { instance: null });
|
|
346
|
+
const LayerOrderResource = (0, _jamesyong42_reactive_ecs.defineResource)("LayerOrder", { layers: [
|
|
347
|
+
"background",
|
|
348
|
+
"base",
|
|
349
|
+
"overlay"
|
|
350
|
+
] });
|
|
177
351
|
//#endregion
|
|
178
|
-
//#region src/react/context.ts
|
|
352
|
+
//#region src/react/context/engine-context.ts
|
|
179
353
|
const EngineContext = (0, react.createContext)(null);
|
|
180
354
|
const EngineProvider = EngineContext.Provider;
|
|
181
|
-
const ContainerRefContext = (0, react.createContext)(null);
|
|
182
|
-
const ContainerRefProvider = ContainerRefContext.Provider;
|
|
183
|
-
function useContainerRef() {
|
|
184
|
-
return (0, react.useContext)(ContainerRefContext);
|
|
185
|
-
}
|
|
186
355
|
/**
|
|
187
356
|
* Returns the LayoutEngine instance from the nearest InfiniteCanvas context.
|
|
188
357
|
* Throws if used outside an InfiniteCanvas provider.
|
|
@@ -192,13 +361,8 @@ function useLayoutEngine() {
|
|
|
192
361
|
if (!engine) throw new Error("useLayoutEngine must be used within an <InfiniteCanvas>");
|
|
193
362
|
return engine;
|
|
194
363
|
}
|
|
195
|
-
const WidgetResolverContext = (0, react.createContext)(null);
|
|
196
|
-
const WidgetResolverProvider = WidgetResolverContext.Provider;
|
|
197
|
-
function useWidgetResolver() {
|
|
198
|
-
return (0, react.useContext)(WidgetResolverContext);
|
|
199
|
-
}
|
|
200
364
|
//#endregion
|
|
201
|
-
//#region src/react/hooks.ts
|
|
365
|
+
//#region src/react/hooks/ecs.ts
|
|
202
366
|
function shallowEqual(a, b) {
|
|
203
367
|
const keysA = Object.keys(a);
|
|
204
368
|
const keysB = Object.keys(b);
|
|
@@ -445,6 +609,12 @@ Object.defineProperty(exports, "Card", {
|
|
|
445
609
|
return Card;
|
|
446
610
|
}
|
|
447
611
|
});
|
|
612
|
+
Object.defineProperty(exports, "CardOverlapHotPoint", {
|
|
613
|
+
enumerable: true,
|
|
614
|
+
get: function() {
|
|
615
|
+
return CardOverlapHotPoint;
|
|
616
|
+
}
|
|
617
|
+
});
|
|
448
618
|
Object.defineProperty(exports, "CardPresetsResource", {
|
|
449
619
|
enumerable: true,
|
|
450
620
|
get: function() {
|
|
@@ -463,10 +633,22 @@ Object.defineProperty(exports, "Container", {
|
|
|
463
633
|
return Container;
|
|
464
634
|
}
|
|
465
635
|
});
|
|
466
|
-
Object.defineProperty(exports, "
|
|
636
|
+
Object.defineProperty(exports, "ContainerCamera", {
|
|
467
637
|
enumerable: true,
|
|
468
638
|
get: function() {
|
|
469
|
-
return
|
|
639
|
+
return ContainerCamera;
|
|
640
|
+
}
|
|
641
|
+
});
|
|
642
|
+
Object.defineProperty(exports, "ContainerChildren", {
|
|
643
|
+
enumerable: true,
|
|
644
|
+
get: function() {
|
|
645
|
+
return ContainerChildren;
|
|
646
|
+
}
|
|
647
|
+
});
|
|
648
|
+
Object.defineProperty(exports, "Culled", {
|
|
649
|
+
enumerable: true,
|
|
650
|
+
get: function() {
|
|
651
|
+
return Culled;
|
|
470
652
|
}
|
|
471
653
|
});
|
|
472
654
|
Object.defineProperty(exports, "CursorHint", {
|
|
@@ -481,6 +663,12 @@ Object.defineProperty(exports, "CursorResource", {
|
|
|
481
663
|
return CursorResource;
|
|
482
664
|
}
|
|
483
665
|
});
|
|
666
|
+
Object.defineProperty(exports, "DEFAULT_CARD_PRESET_SIZES", {
|
|
667
|
+
enumerable: true,
|
|
668
|
+
get: function() {
|
|
669
|
+
return DEFAULT_CARD_PRESET_SIZES;
|
|
670
|
+
}
|
|
671
|
+
});
|
|
484
672
|
Object.defineProperty(exports, "Draggable", {
|
|
485
673
|
enumerable: true,
|
|
486
674
|
get: function() {
|
|
@@ -499,22 +687,22 @@ Object.defineProperty(exports, "EngineProvider", {
|
|
|
499
687
|
return EngineProvider;
|
|
500
688
|
}
|
|
501
689
|
});
|
|
502
|
-
Object.defineProperty(exports, "
|
|
690
|
+
Object.defineProperty(exports, "InteractionRole", {
|
|
503
691
|
enumerable: true,
|
|
504
692
|
get: function() {
|
|
505
|
-
return
|
|
693
|
+
return InteractionRole;
|
|
506
694
|
}
|
|
507
695
|
});
|
|
508
|
-
Object.defineProperty(exports, "
|
|
696
|
+
Object.defineProperty(exports, "Layer", {
|
|
509
697
|
enumerable: true,
|
|
510
698
|
get: function() {
|
|
511
|
-
return
|
|
699
|
+
return Layer;
|
|
512
700
|
}
|
|
513
701
|
});
|
|
514
|
-
Object.defineProperty(exports, "
|
|
702
|
+
Object.defineProperty(exports, "LayerOrderResource", {
|
|
515
703
|
enumerable: true,
|
|
516
704
|
get: function() {
|
|
517
|
-
return
|
|
705
|
+
return LayerOrderResource;
|
|
518
706
|
}
|
|
519
707
|
});
|
|
520
708
|
Object.defineProperty(exports, "Locked", {
|
|
@@ -529,10 +717,28 @@ Object.defineProperty(exports, "NavigationStackResource", {
|
|
|
529
717
|
return NavigationStackResource;
|
|
530
718
|
}
|
|
531
719
|
});
|
|
532
|
-
Object.defineProperty(exports, "
|
|
720
|
+
Object.defineProperty(exports, "OverlapCandidate", {
|
|
533
721
|
enumerable: true,
|
|
534
722
|
get: function() {
|
|
535
|
-
return
|
|
723
|
+
return OverlapCandidate;
|
|
724
|
+
}
|
|
725
|
+
});
|
|
726
|
+
Object.defineProperty(exports, "OverlapTarget", {
|
|
727
|
+
enumerable: true,
|
|
728
|
+
get: function() {
|
|
729
|
+
return OverlapTarget;
|
|
730
|
+
}
|
|
731
|
+
});
|
|
732
|
+
Object.defineProperty(exports, "ParentFrame", {
|
|
733
|
+
enumerable: true,
|
|
734
|
+
get: function() {
|
|
735
|
+
return ParentFrame;
|
|
736
|
+
}
|
|
737
|
+
});
|
|
738
|
+
Object.defineProperty(exports, "PreDragLayer", {
|
|
739
|
+
enumerable: true,
|
|
740
|
+
get: function() {
|
|
741
|
+
return PreDragLayer;
|
|
536
742
|
}
|
|
537
743
|
});
|
|
538
744
|
Object.defineProperty(exports, "Resizable", {
|
|
@@ -541,6 +747,12 @@ Object.defineProperty(exports, "Resizable", {
|
|
|
541
747
|
return Resizable;
|
|
542
748
|
}
|
|
543
749
|
});
|
|
750
|
+
Object.defineProperty(exports, "RootCameraResource", {
|
|
751
|
+
enumerable: true,
|
|
752
|
+
get: function() {
|
|
753
|
+
return RootCameraResource;
|
|
754
|
+
}
|
|
755
|
+
});
|
|
544
756
|
Object.defineProperty(exports, "Selectable", {
|
|
545
757
|
enumerable: true,
|
|
546
758
|
get: function() {
|
|
@@ -559,12 +771,36 @@ Object.defineProperty(exports, "SelectionFrame", {
|
|
|
559
771
|
return SelectionFrame;
|
|
560
772
|
}
|
|
561
773
|
});
|
|
774
|
+
Object.defineProperty(exports, "SnapSource", {
|
|
775
|
+
enumerable: true,
|
|
776
|
+
get: function() {
|
|
777
|
+
return SnapSource;
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
Object.defineProperty(exports, "SnapTarget", {
|
|
781
|
+
enumerable: true,
|
|
782
|
+
get: function() {
|
|
783
|
+
return SnapTarget;
|
|
784
|
+
}
|
|
785
|
+
});
|
|
786
|
+
Object.defineProperty(exports, "SpatialIndexResource", {
|
|
787
|
+
enumerable: true,
|
|
788
|
+
get: function() {
|
|
789
|
+
return SpatialIndexResource;
|
|
790
|
+
}
|
|
791
|
+
});
|
|
562
792
|
Object.defineProperty(exports, "Transform2D", {
|
|
563
793
|
enumerable: true,
|
|
564
794
|
get: function() {
|
|
565
795
|
return Transform2D;
|
|
566
796
|
}
|
|
567
797
|
});
|
|
798
|
+
Object.defineProperty(exports, "TransformTween", {
|
|
799
|
+
enumerable: true,
|
|
800
|
+
get: function() {
|
|
801
|
+
return TransformTween;
|
|
802
|
+
}
|
|
803
|
+
});
|
|
568
804
|
Object.defineProperty(exports, "ViewportResource", {
|
|
569
805
|
enumerable: true,
|
|
570
806
|
get: function() {
|
|
@@ -595,18 +831,6 @@ Object.defineProperty(exports, "WidgetData", {
|
|
|
595
831
|
return WidgetData;
|
|
596
832
|
}
|
|
597
833
|
});
|
|
598
|
-
Object.defineProperty(exports, "WidgetResolverProvider", {
|
|
599
|
-
enumerable: true,
|
|
600
|
-
get: function() {
|
|
601
|
-
return WidgetResolverProvider;
|
|
602
|
-
}
|
|
603
|
-
});
|
|
604
|
-
Object.defineProperty(exports, "WorldBounds", {
|
|
605
|
-
enumerable: true,
|
|
606
|
-
get: function() {
|
|
607
|
-
return WorldBounds;
|
|
608
|
-
}
|
|
609
|
-
});
|
|
610
834
|
Object.defineProperty(exports, "ZIndex", {
|
|
611
835
|
enumerable: true,
|
|
612
836
|
get: function() {
|
|
@@ -637,12 +861,6 @@ Object.defineProperty(exports, "useComponent", {
|
|
|
637
861
|
return useComponent;
|
|
638
862
|
}
|
|
639
863
|
});
|
|
640
|
-
Object.defineProperty(exports, "useContainerRef", {
|
|
641
|
-
enumerable: true,
|
|
642
|
-
get: function() {
|
|
643
|
-
return useContainerRef;
|
|
644
|
-
}
|
|
645
|
-
});
|
|
646
864
|
Object.defineProperty(exports, "useEntityComponents", {
|
|
647
865
|
enumerable: true,
|
|
648
866
|
get: function() {
|
|
@@ -697,11 +915,5 @@ Object.defineProperty(exports, "useTaggedEntities", {
|
|
|
697
915
|
return useTaggedEntities;
|
|
698
916
|
}
|
|
699
917
|
});
|
|
700
|
-
Object.defineProperty(exports, "useWidgetResolver", {
|
|
701
|
-
enumerable: true,
|
|
702
|
-
get: function() {
|
|
703
|
-
return useWidgetResolver;
|
|
704
|
-
}
|
|
705
|
-
});
|
|
706
918
|
|
|
707
|
-
//# sourceMappingURL=
|
|
919
|
+
//# sourceMappingURL=ecs-B4QrqfvQ.cjs.map
|