@phaserjs/phaser-editor-layout 1.0.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 +304 -0
- package/dist/LayoutPlugin.d.ts +147 -0
- package/dist/LayoutPlugin.d.ts.map +1 -0
- package/dist/LayoutPlugin.js +354 -0
- package/dist/LayoutPlugin.js.map +1 -0
- package/dist/LayoutZone.d.ts +56 -0
- package/dist/LayoutZone.d.ts.map +1 -0
- package/dist/LayoutZone.js +54 -0
- package/dist/LayoutZone.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/phaser-editor-layout.js +424 -0
- package/dist/phaser-editor-layout.js.map +7 -0
- package/dist/phaser-editor-layout.min.js +1 -0
- package/dist/types.d.ts +79 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/global/phaser-editor-layout.global.d.ts +81 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# @phaserjs/phaser-editor-layout
|
|
2
|
+
|
|
3
|
+
A small **responsive layout runtime for Phaser 3**: anchor game objects to zones and
|
|
4
|
+
device safe areas, and have them re-flow automatically when the screen resizes or the
|
|
5
|
+
device orientation changes.
|
|
6
|
+
|
|
7
|
+
It is the runtime counterpart to Phaser Editor's responsive layout system — the same
|
|
8
|
+
resolver runs in the editor's live preview and in your game, so what you see in the
|
|
9
|
+
editor is what you get at run time. It also works perfectly well as a standalone library
|
|
10
|
+
without the editor.
|
|
11
|
+
|
|
12
|
+
> **Phaser version.** This targets **Phaser 3** (`^3.60.0`). A Phaser 4 build will
|
|
13
|
+
> follow; the API is intended to carry over unchanged.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @phaserjs/phaser-editor-layout
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`phaser` is a peer dependency — the library uses whatever Phaser 3 build your project
|
|
22
|
+
already has.
|
|
23
|
+
|
|
24
|
+
## Concepts
|
|
25
|
+
|
|
26
|
+
- **Scene plugin (`this.layout`).** The library is a Phaser *Scene Plugin*, reached as
|
|
27
|
+
`this.layout`, exactly like `this.physics`. It keeps the set of laid-out objects and
|
|
28
|
+
re-resolves them when the screen changes.
|
|
29
|
+
- **`obj.layoutData`.** Per-object layout state lives on the object as `obj.layoutData`
|
|
30
|
+
(cf. `obj.body` for physics). Its anchor properties are split into variants
|
|
31
|
+
(`base` / `portrait` / `landscape`); you configure layout by setting plain fields on
|
|
32
|
+
them.
|
|
33
|
+
- **Zones.** A zone is a screen-relative rectangle defined by margins from each screen
|
|
34
|
+
edge (also split into `base` / `portrait` / `landscape`). The built-ins are `screen`
|
|
35
|
+
(full bounds) and `safeArea` (insets supplied by the host). Make your own with
|
|
36
|
+
`createZone(...)`.
|
|
37
|
+
- **Anchors.** Per axis you pick an edge (`left`/`center`/`right`, `top`/`center`/
|
|
38
|
+
`bottom`, or `none`) plus a pixel offset. The object's matching edge/center is aligned
|
|
39
|
+
to the target's, then nudged by the offset.
|
|
40
|
+
- **Variants.** Both zones and layout data carry a `base` plus `portrait` / `landscape`
|
|
41
|
+
overrides. The active variant (see `this.layout.variant`) selects which overrides
|
|
42
|
+
apply on top of `base`, so one object can lay out differently per orientation.
|
|
43
|
+
|
|
44
|
+
## Quick start
|
|
45
|
+
|
|
46
|
+
### 1. Register the plugin
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import Phaser from "phaser";
|
|
50
|
+
import { LayoutPlugin } from "@phaserjs/phaser-editor-layout";
|
|
51
|
+
|
|
52
|
+
new Phaser.Game({
|
|
53
|
+
type: Phaser.AUTO,
|
|
54
|
+
scale: {
|
|
55
|
+
mode: Phaser.Scale.RESIZE, // so the layout follows the window/orientation
|
|
56
|
+
width: 1080,
|
|
57
|
+
height: 1920,
|
|
58
|
+
},
|
|
59
|
+
plugins: {
|
|
60
|
+
scene: [
|
|
61
|
+
{ key: "LayoutPlugin", plugin: LayoutPlugin, mapping: "layout" },
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
scene: [MainScene],
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The `mapping: "layout"` makes the plugin available as `this.layout` in every scene, and
|
|
69
|
+
the bundled TypeScript types make `this.layout` and `obj.layoutData` strongly typed.
|
|
70
|
+
|
|
71
|
+
### 2. Anchor objects in a scene
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
export class MainScene extends Phaser.Scene {
|
|
75
|
+
|
|
76
|
+
create() {
|
|
77
|
+
// Built-in zones are always available: this.layout.screen and this.layout.safeArea.
|
|
78
|
+
// Make a custom zone: createZone(top, right, bottom, left).
|
|
79
|
+
const reelsZone = this.layout.createZone(360, 90, 470, 90);
|
|
80
|
+
|
|
81
|
+
// Top-centered logo, anchored to the safe area. Configure the `base` variant.
|
|
82
|
+
const logo = this.add.image(0, 0, "logo");
|
|
83
|
+
const logoData = this.layout.add(logo);
|
|
84
|
+
logoData.base.targetType = "safeArea";
|
|
85
|
+
logoData.base.horizontalAnchor = "center";
|
|
86
|
+
logoData.base.verticalAnchor = "top";
|
|
87
|
+
logoData.base.verticalOffset = 24;
|
|
88
|
+
|
|
89
|
+
// Bottom-right button, 40px in from the safe-area corner.
|
|
90
|
+
const hud = this.add.image(0, 0, "hud");
|
|
91
|
+
const hudData = this.layout.add(hud);
|
|
92
|
+
hudData.base.targetType = "safeArea";
|
|
93
|
+
hudData.base.horizontalAnchor = "right";
|
|
94
|
+
hudData.base.horizontalOffset = -40;
|
|
95
|
+
hudData.base.verticalAnchor = "bottom";
|
|
96
|
+
hudData.base.verticalOffset = -40;
|
|
97
|
+
|
|
98
|
+
// Centered in a custom zone — "custom" is the one target that needs targetZone.
|
|
99
|
+
const reels = this.add.image(0, 0, "reels");
|
|
100
|
+
const reelsData = this.layout.add(reels);
|
|
101
|
+
reelsData.base.targetType = "custom";
|
|
102
|
+
reelsData.base.targetZone = reelsZone;
|
|
103
|
+
reelsData.base.horizontalAnchor = "center";
|
|
104
|
+
reelsData.base.verticalAnchor = "center";
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`add()` returns the object's `AnchorLayoutData`; you can also configure it via
|
|
110
|
+
`logo.layoutData!`. Setting only `base` (as above) means the object lays out the same in
|
|
111
|
+
every orientation — see [Variants & orientation](#variants--orientation) to vary it.
|
|
112
|
+
|
|
113
|
+
### 3. Feed the device safe area (optional)
|
|
114
|
+
|
|
115
|
+
The safe area is unknown at author time, so the host supplies it. On the web that's the
|
|
116
|
+
CSS `env(safe-area-inset-*)` values; in a native wrapper it's a device plugin. Set the
|
|
117
|
+
`safeArea` margins and re-resolve:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
this.layout.safeArea.base.marginTop = insets.top;
|
|
121
|
+
this.layout.safeArea.base.marginRight = insets.right;
|
|
122
|
+
this.layout.safeArea.base.marginBottom = insets.bottom;
|
|
123
|
+
this.layout.safeArea.base.marginLeft = insets.left;
|
|
124
|
+
this.layout.refresh();
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Anchoring inside a prefab (Parent Bounds)
|
|
128
|
+
|
|
129
|
+
A prefab is a `GameObject` (e.g. a `Container`), not a `Scene`, so it reaches the plugin
|
|
130
|
+
through `this.scene.layout`. Use `targetType: "parent"` to lay children out against the
|
|
131
|
+
prefab's own bounds:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
export class CollectorPrefab extends Phaser.GameObjects.Container {
|
|
135
|
+
|
|
136
|
+
constructor(scene: Phaser.Scene, x: number, y: number) {
|
|
137
|
+
super(scene, x, y);
|
|
138
|
+
this.setSize(300, 260); // containers have no intrinsic size
|
|
139
|
+
|
|
140
|
+
const coinIcon = scene.add.image(0, 0, "coin");
|
|
141
|
+
this.add(coinIcon);
|
|
142
|
+
|
|
143
|
+
const icon = scene.layout.add(coinIcon);
|
|
144
|
+
icon.base.targetType = "parent"; // resolves against this container's bounds
|
|
145
|
+
icon.base.horizontalAnchor = "left";
|
|
146
|
+
icon.base.horizontalOffset = 20;
|
|
147
|
+
icon.base.verticalAnchor = "center";
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Variants & orientation
|
|
153
|
+
|
|
154
|
+
Both `obj.layoutData` and every zone carry three variants — `base`, `portrait`,
|
|
155
|
+
`landscape`. `base` is the baseline; `portrait` / `landscape` hold only the fields that
|
|
156
|
+
differ. The resolver uses `active[prop] ?? base[prop]`, where the active variant is
|
|
157
|
+
`this.layout.variant`.
|
|
158
|
+
|
|
159
|
+
Pick the active variant in one of two ways (default is manual, `"base"`):
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
// Manual:
|
|
163
|
+
this.layout.setVariant("portrait");
|
|
164
|
+
|
|
165
|
+
// Or orientation-driven — follows the screen on every resize:
|
|
166
|
+
this.layout.autoVariant(true);
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Author once, and rotating re-flows automatically:
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
// Safe area: notch on top in portrait, on the left in landscape.
|
|
173
|
+
this.layout.safeArea.portrait.marginTop = 120;
|
|
174
|
+
this.layout.safeArea.landscape.marginLeft = 120;
|
|
175
|
+
|
|
176
|
+
// A button: bottom-center in portrait, right-center in landscape.
|
|
177
|
+
const data = this.layout.add(button);
|
|
178
|
+
data.base.targetType = "safeArea";
|
|
179
|
+
data.portrait.horizontalAnchor = "center";
|
|
180
|
+
data.portrait.verticalAnchor = "bottom";
|
|
181
|
+
data.portrait.verticalOffset = -40;
|
|
182
|
+
data.landscape.horizontalAnchor = "right";
|
|
183
|
+
data.landscape.horizontalOffset = -40;
|
|
184
|
+
data.landscape.verticalAnchor = "center";
|
|
185
|
+
|
|
186
|
+
this.layout.autoVariant(true);
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
See the `mobile-orientation` example for the full picture.
|
|
190
|
+
|
|
191
|
+
## When does layout resolve?
|
|
192
|
+
|
|
193
|
+
- **Automatically** once after the scene's `create`, and on every `scale` `resize`
|
|
194
|
+
(window resize, orientation change, etc.).
|
|
195
|
+
- **Manually** via `this.layout.refresh()` after you mutate `obj.layoutData` or the
|
|
196
|
+
`safeArea` margins at run time. There is no setter to hook — fields are set directly —
|
|
197
|
+
so an explicit `refresh()` is how changes take effect immediately.
|
|
198
|
+
|
|
199
|
+
`refresh()` always runs a full, ordered pass (parents before children), so a child
|
|
200
|
+
anchored to its parent always sees the parent's resolved position. The pass is just
|
|
201
|
+
arithmetic over the registered objects, so it is cheap.
|
|
202
|
+
|
|
203
|
+
## Reacting to layout
|
|
204
|
+
|
|
205
|
+
The plugin fires `layoutupdate` after each pass:
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
import { LAYOUT_UPDATE_EVENT } from "@phaserjs/phaser-editor-layout";
|
|
209
|
+
|
|
210
|
+
this.layout.on(LAYOUT_UPDATE_EVENT, () => {
|
|
211
|
+
// reposition non-layout decorations, redraw overlays, etc.
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
`this.layout.on/once/off` delegate to the plugin's `events` emitter
|
|
216
|
+
(`this.layout.events`).
|
|
217
|
+
|
|
218
|
+
## API
|
|
219
|
+
|
|
220
|
+
### `this.layout` (`LayoutPlugin`)
|
|
221
|
+
|
|
222
|
+
| Member | Description |
|
|
223
|
+
| --- | --- |
|
|
224
|
+
| `safeArea: LayoutZone` | Screen inset by the device safe-area insets. Set `safeArea.base.margin*` (or per-variant) from the host. |
|
|
225
|
+
| `screen: LayoutZone` | The full screen bounds. |
|
|
226
|
+
| `variant: VariantName` | The active variant (`"base" \| "portrait" \| "landscape"`). Defaults to `"base"`. |
|
|
227
|
+
| `add(obj): AnchorLayoutData` | Enable layout for `obj`: attaches a default `obj.layoutData`, registers it, and returns the data to configure. |
|
|
228
|
+
| `remove(obj): void` | Stop laying out `obj` and clear its `layoutData`. |
|
|
229
|
+
| `createZone(top?, right?, bottom?, left?): LayoutZone` | Create a custom screen-relative zone (sets its `base` margins). Assign it to `data.<variant>.targetZone` with `targetType: "custom"`. |
|
|
230
|
+
| `setVariant(variant): void` | Manually set the active variant (turns off auto) and re-resolve. |
|
|
231
|
+
| `autoVariant(enabled?): void` | Follow the screen orientation on every resize (`portrait` / `landscape`); disabling resets to `"base"`. |
|
|
232
|
+
| `get orientation()` | The screen's current orientation (`"portrait"` if `height > width`, else `"landscape"`). |
|
|
233
|
+
| `refresh(): void` | Re-resolve every enabled object now (full, ordered pass). |
|
|
234
|
+
| `events: Phaser.Events.EventEmitter` | Emits `layoutupdate` after each pass. |
|
|
235
|
+
| `on/once/off(...)` | Delegates to `events`. |
|
|
236
|
+
|
|
237
|
+
### `AnchorLayoutData` (`obj.layoutData`)
|
|
238
|
+
|
|
239
|
+
| Field | Type | Description |
|
|
240
|
+
| --- | --- | --- |
|
|
241
|
+
| `enabled` | `boolean` | When `false`, the object keeps its raw `x`/`y` and is skipped ("Absolute" mode). |
|
|
242
|
+
| `base` | `AnchorProps` | Baseline anchor properties; the resolver falls back here for unset variant fields. |
|
|
243
|
+
| `portrait` | `AnchorProps` | Overrides applied when `variant === "portrait"`. |
|
|
244
|
+
| `landscape` | `AnchorProps` | Overrides applied when `variant === "landscape"`. |
|
|
245
|
+
|
|
246
|
+
Defaults from `add(obj)`: `enabled: true`, `base` = `{ targetType: "screen", anchors
|
|
247
|
+
"none", zero offsets }`, empty `portrait` / `landscape` — i.e. inert until you choose
|
|
248
|
+
anchors.
|
|
249
|
+
|
|
250
|
+
### `AnchorProps` (`data.base` / `data.portrait` / `data.landscape`)
|
|
251
|
+
|
|
252
|
+
All fields optional; on `portrait` / `landscape` an unset field inherits from `base`.
|
|
253
|
+
|
|
254
|
+
| Field | Type | Description |
|
|
255
|
+
| --- | --- | --- |
|
|
256
|
+
| `targetType` | `"screen" \| "safeArea" \| "parent" \| "custom"` | What to anchor to: the screen, the device safe area, the object's parent-container bounds, or a custom zone. |
|
|
257
|
+
| `targetZone` | `LayoutZone?` | The zone to anchor to when `targetType === "custom"`. |
|
|
258
|
+
| `horizontalAnchor` | `"left" \| "center" \| "right" \| "none"` | Horizontal anchor edge. `none` keeps the current `x`. |
|
|
259
|
+
| `horizontalOffset` | `number` | Pixel offset applied after the horizontal anchor. |
|
|
260
|
+
| `verticalAnchor` | `"top" \| "center" \| "bottom" \| "none"` | Vertical anchor edge. `none` keeps the current `y`. |
|
|
261
|
+
| `verticalOffset` | `number` | Pixel offset applied after the vertical anchor. |
|
|
262
|
+
|
|
263
|
+
### `LayoutZone`
|
|
264
|
+
|
|
265
|
+
| Member | Description |
|
|
266
|
+
| --- | --- |
|
|
267
|
+
| `base: { marginTop, marginRight, marginBottom, marginLeft }` | Baseline insets from each screen edge, in pixels. |
|
|
268
|
+
| `portrait / landscape` | Partial margin overrides for those variants; unset sides inherit `base`. |
|
|
269
|
+
| `getRect(out?): Phaser.Geom.Rectangle` | The effective rect at the current screen size and active variant. Pass `out` to avoid allocations. |
|
|
270
|
+
|
|
271
|
+
## Resolution semantics
|
|
272
|
+
|
|
273
|
+
Given the target rect `t` and the object size `w`×`h` (its `displayWidth` /
|
|
274
|
+
`displayHeight`), each axis aligns the object's edge/center to the target's, accounting
|
|
275
|
+
for the object's `origin`:
|
|
276
|
+
|
|
277
|
+
- `left` / `top` → align the object's left/top edge to `t.left`/`t.top` + offset.
|
|
278
|
+
- `right` / `bottom` → align its right/bottom edge to `t.right`/`t.bottom` + offset.
|
|
279
|
+
- `center` → align its center to the target's center + offset.
|
|
280
|
+
- `none` → leave that axis unchanged.
|
|
281
|
+
|
|
282
|
+
For centered-origin objects (`origin = 0.5`) this reduces to the familiar
|
|
283
|
+
`x = t.left + offset + w / 2` form.
|
|
284
|
+
|
|
285
|
+
The properties used (`targetType`, anchors, offsets) and the zone rect `t` are first
|
|
286
|
+
resolved for the active variant as `active[prop] ?? base[prop]`, so portrait/landscape
|
|
287
|
+
overrides and per-variant zone margins both feed into the same alignment math.
|
|
288
|
+
|
|
289
|
+
## Notes & current limitations
|
|
290
|
+
|
|
291
|
+
- **Default camera assumed.** Zones are computed in screen pixels, treated as world
|
|
292
|
+
coordinates. Objects on a scrolled/zoomed camera are not yet special-cased.
|
|
293
|
+
- **Parent Bounds geometry.** With `targetType: "parent"`, the parent container's rect
|
|
294
|
+
is taken as `(0, 0, parent.width, parent.height)` in its local space, so call
|
|
295
|
+
`setSize(...)` on the container. Children are aligned within that rect; parent
|
|
296
|
+
rotation is not specially handled.
|
|
297
|
+
- **No stretch (v1).** Each axis anchors a single edge, so "fill width minus margins" is
|
|
298
|
+
not expressible yet.
|
|
299
|
+
- **Serialization is out of scope here.** This package is the *runtime*; the editor owns
|
|
300
|
+
how layout data and zone references are stored in `.scene` files.
|
|
301
|
+
|
|
302
|
+
## License
|
|
303
|
+
|
|
304
|
+
MIT
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import Phaser from "phaser";
|
|
2
|
+
import { LayoutZone } from "./LayoutZone";
|
|
3
|
+
import type { AnchorLayoutData, VariantName } from "./types";
|
|
4
|
+
/** Event fired by the plugin after each resolution pass. */
|
|
5
|
+
export declare const LAYOUT_UPDATE_EVENT = "layoutupdate";
|
|
6
|
+
/**
|
|
7
|
+
* Scene plugin that resolves responsive anchors and zones at run time.
|
|
8
|
+
*
|
|
9
|
+
* Reached as `this.layout` (like `this.physics`) once registered with
|
|
10
|
+
* `mapping: "layout"`. Per-object layout state lives on the object as
|
|
11
|
+
* `obj.layoutData`; the plugin keeps the set of enabled objects so it can
|
|
12
|
+
* re-resolve them when the screen changes.
|
|
13
|
+
*
|
|
14
|
+
* Register it in the game config:
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* plugins: {
|
|
18
|
+
* scene: [
|
|
19
|
+
* { key: "LayoutPlugin", plugin: LayoutPlugin, mapping: "layout" }
|
|
20
|
+
* ]
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare class LayoutPlugin extends Phaser.Plugins.ScenePlugin {
|
|
25
|
+
/** Screen inset by the device safe-area insets. The host sets `safeArea.margin*`. */
|
|
26
|
+
readonly safeArea: LayoutZone;
|
|
27
|
+
/** The full screen bounds (0,0 .. width,height). */
|
|
28
|
+
readonly screen: LayoutZone;
|
|
29
|
+
/**
|
|
30
|
+
* Event emitter that fires {@link LAYOUT_UPDATE_EVENT} after each resolution pass.
|
|
31
|
+
* Use `this.layout.events.on("layoutupdate", ...)` — or the `on`/`once`/`off`
|
|
32
|
+
* delegates on the plugin itself.
|
|
33
|
+
*/
|
|
34
|
+
readonly events: Phaser.Events.EventEmitter;
|
|
35
|
+
/**
|
|
36
|
+
* The active layout variant. `"base"` applies only the baseline; `"portrait"` /
|
|
37
|
+
* `"landscape"` apply their overrides on top of base. Defaults to `"base"`. Change
|
|
38
|
+
* it with {@link setVariant} (manual) or {@link autoVariant} (orientation-driven).
|
|
39
|
+
*/
|
|
40
|
+
variant: VariantName;
|
|
41
|
+
private readonly _scene;
|
|
42
|
+
private _auto;
|
|
43
|
+
private _designSize;
|
|
44
|
+
private readonly _objects;
|
|
45
|
+
private readonly _rect;
|
|
46
|
+
private readonly _mat;
|
|
47
|
+
private readonly _p1;
|
|
48
|
+
private readonly _p2;
|
|
49
|
+
constructor(scene: Phaser.Scene, pluginManager: Phaser.Plugins.PluginManager, pluginKey: string);
|
|
50
|
+
boot(): void;
|
|
51
|
+
/**
|
|
52
|
+
* The injected design size, or `null` when resolution follows the live scene size
|
|
53
|
+
* (`scale.gameSize`). Read by zones (the plugin is their {@link LayoutZone} provider).
|
|
54
|
+
*/
|
|
55
|
+
get designSize(): {
|
|
56
|
+
width: number;
|
|
57
|
+
height: number;
|
|
58
|
+
} | null;
|
|
59
|
+
/**
|
|
60
|
+
* Resolve against a fixed design size (e.g. 1080×1920) instead of the live canvas
|
|
61
|
+
* size, then re-resolve. Hosts that author/preview layouts at a target resolution
|
|
62
|
+
* (the editor) use this; games typically leave it unset and follow `scale.gameSize`.
|
|
63
|
+
*/
|
|
64
|
+
setDesignSize(width: number, height: number): void;
|
|
65
|
+
/** Clear the injected design size and fall back to the live scene size, then re-resolve. */
|
|
66
|
+
clearDesignSize(): void;
|
|
67
|
+
/** The effective size used for resolution: the injected design size, or the live game size. */
|
|
68
|
+
private _size;
|
|
69
|
+
/** The screen's current orientation, derived from the effective design size. */
|
|
70
|
+
get orientation(): "portrait" | "landscape";
|
|
71
|
+
/**
|
|
72
|
+
* Manually set the active variant and re-resolve. Turns off orientation
|
|
73
|
+
* auto-detection (see {@link autoVariant}).
|
|
74
|
+
*/
|
|
75
|
+
setVariant(variant: VariantName): void;
|
|
76
|
+
/**
|
|
77
|
+
* Enable (or disable) orientation-driven variant selection. When enabled, the active
|
|
78
|
+
* variant follows {@link orientation} (`"portrait"` / `"landscape"`) on every resize.
|
|
79
|
+
* Disabling resets the variant to `"base"`.
|
|
80
|
+
*/
|
|
81
|
+
autoVariant(enabled?: boolean): void;
|
|
82
|
+
private _onResize;
|
|
83
|
+
/**
|
|
84
|
+
* Enable layout for an object: attaches a default {@link AnchorLayoutData} as
|
|
85
|
+
* `obj.layoutData` (if it does not have one yet), registers the object for
|
|
86
|
+
* re-resolution, and returns the data so it can be configured.
|
|
87
|
+
*
|
|
88
|
+
* The `base` defaults are inert: `targetType: "screen"`, both anchors `"none"` and
|
|
89
|
+
* zero offsets, so the object does not move until you choose anchors. `portrait` and
|
|
90
|
+
* `landscape` start empty (they inherit `base`).
|
|
91
|
+
*/
|
|
92
|
+
add<T extends Phaser.GameObjects.GameObject>(obj: T): AnchorLayoutData;
|
|
93
|
+
/** Stop laying out an object and remove its `layoutData`. */
|
|
94
|
+
remove(obj: Phaser.GameObjects.GameObject): void;
|
|
95
|
+
private _onObjectDestroy;
|
|
96
|
+
/**
|
|
97
|
+
* Create a screen-relative zone. A factory only — the returned zone is not stored
|
|
98
|
+
* by the plugin; hold the reference and assign it to `data.targetZone`.
|
|
99
|
+
*/
|
|
100
|
+
createZone(marginTop?: number, marginRight?: number, marginBottom?: number, marginLeft?: number): LayoutZone;
|
|
101
|
+
/**
|
|
102
|
+
* Re-resolve every enabled object now. The plugin also runs this automatically on
|
|
103
|
+
* `scale` `resize` and once after the scene is created, so explicit calls are only
|
|
104
|
+
* needed after mutating layout data (or the `safeArea` margins) at run time.
|
|
105
|
+
*
|
|
106
|
+
* Objects are resolved parent → child so a child anchored to its parent's bounds
|
|
107
|
+
* sees the parent's already-resolved rect.
|
|
108
|
+
*/
|
|
109
|
+
refresh(): void;
|
|
110
|
+
/**
|
|
111
|
+
* Resolve a specific list of objects once, against the current variant / design size /
|
|
112
|
+
* zones, **without** registering them for future passes (no {@link add}, no re-resolve
|
|
113
|
+
* on resize). Hosts that drive resolution themselves — e.g. the editor's live preview —
|
|
114
|
+
* set each object's `layoutData`, call this, then read back the resolved `x`/`y`.
|
|
115
|
+
*
|
|
116
|
+
* Objects are still resolved parent → child, and any object whose `layoutData` is
|
|
117
|
+
* missing or disabled is skipped.
|
|
118
|
+
*/
|
|
119
|
+
resolveList(objects: Phaser.GameObjects.GameObject[]): void;
|
|
120
|
+
private _depth;
|
|
121
|
+
private _resolve;
|
|
122
|
+
/** Merge the active variant's overrides over `base` into concrete anchor properties. */
|
|
123
|
+
private _effective;
|
|
124
|
+
/** The zone a non-parent target resolves against. */
|
|
125
|
+
private _zoneFor;
|
|
126
|
+
/** Resolve against a zone's world rect, converting to parent-local space if nested. */
|
|
127
|
+
private _resolveAgainstZone;
|
|
128
|
+
/** Resolve against the object's parent container bounds (local space), or the screen. */
|
|
129
|
+
private _resolveAgainstParent;
|
|
130
|
+
/**
|
|
131
|
+
* Resolve one axis. Aligns the object's edge/center to the target edge/center,
|
|
132
|
+
* accounting for the object's origin so `"left"`/`"top"` align the left/top edge,
|
|
133
|
+
* `"center"` the center, and `"right"`/`"bottom"` the right/bottom edge.
|
|
134
|
+
*
|
|
135
|
+
* Reduces to the documented `t.left + offset + size / 2` form for centered-origin
|
|
136
|
+
* objects (`origin = 0.5`).
|
|
137
|
+
*/
|
|
138
|
+
private _axis;
|
|
139
|
+
private _sizeX;
|
|
140
|
+
private _sizeY;
|
|
141
|
+
on(event: string | symbol, fn: (...args: any[]) => void, context?: any): this;
|
|
142
|
+
once(event: string | symbol, fn: (...args: any[]) => void, context?: any): this;
|
|
143
|
+
off(event: string | symbol, fn?: (...args: any[]) => void, context?: any, once?: boolean): this;
|
|
144
|
+
shutdown(): void;
|
|
145
|
+
destroy(): void;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=LayoutPlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LayoutPlugin.d.ts","sourceRoot":"","sources":["../src/LayoutPlugin.ts"],"names":[],"mappings":"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"}
|