@number10/phaserjsx 4.0.0 → 4.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/README.md +30 -0
- package/dist/chunk-C2EiDwsr.cjs +35 -0
- package/dist/clip/index.cjs +696 -0
- package/dist/clip/index.cjs.map +1 -0
- package/dist/clip/index.d.ts +3 -0
- package/dist/clip/index.d.ts.map +1 -0
- package/dist/clip/index.js +688 -0
- package/dist/clip/index.js.map +1 -0
- package/dist/clip/stencil-clip-extension.d.ts +18 -0
- package/dist/clip/stencil-clip-extension.d.ts.map +1 -0
- package/dist/clip/stencil-clip.d.ts +55 -7
- package/dist/clip/stencil-clip.d.ts.map +1 -1
- package/dist/components/appliers/applyBackground.d.ts +2 -1
- package/dist/components/appliers/applyBackground.d.ts.map +1 -1
- package/dist/components/appliers/applyTooltip.d.ts.map +1 -1
- package/dist/components/backgroundImage.d.ts +12 -0
- package/dist/components/backgroundImage.d.ts.map +1 -0
- package/dist/components/creators/createBackground.d.ts +2 -1
- package/dist/components/creators/createBackground.d.ts.map +1 -1
- package/dist/components/custom/Accordion.d.ts.map +1 -1
- package/dist/components/custom/Dropdown.d.ts.map +1 -1
- package/dist/components/custom/index.cjs +1 -1
- package/dist/components/custom/index.js +1 -1
- package/dist/components/primitives/view.d.ts.map +1 -1
- package/dist/{custom-oy3mBnrW.js → custom-C_w8D39m.js} +178 -481
- package/dist/custom-C_w8D39m.js.map +1 -0
- package/dist/{custom-BN31OAJq.cjs → custom-Dp3yAJdU.cjs} +187 -515
- package/dist/custom-Dp3yAJdU.cjs.map +1 -0
- package/dist/hooks.d.ts +9 -8
- package/dist/hooks.d.ts.map +1 -1
- package/dist/index.cjs +103 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +96 -22
- package/dist/index.js.map +1 -1
- package/dist/layout/appliers/background-applier.d.ts.map +1 -1
- package/dist/layout/layout-engine.d.ts.map +1 -1
- package/dist/layout/types.d.ts +2 -1
- package/dist/layout/types.d.ts.map +1 -1
- package/dist/scene-backgrounds.d.ts +51 -1
- package/dist/scene-backgrounds.d.ts.map +1 -1
- package/package.json +6 -1
- package/dist/custom-BN31OAJq.cjs.map +0 -1
- package/dist/custom-oy3mBnrW.js.map +0 -1
|
@@ -16571,6 +16571,111 @@ var tileSpritePatcher = (_node, _prev, _next) => {
|
|
|
16571
16571
|
throw new Error("TileSprite component not implemented yet. This is a placeholder for architecture planning.");
|
|
16572
16572
|
};
|
|
16573
16573
|
//#endregion
|
|
16574
|
+
//#region src/components/backgroundImage.ts
|
|
16575
|
+
var sceneBackgroundTextureCaches = /* @__PURE__ */ new WeakMap();
|
|
16576
|
+
function hasRenderableBackground(props) {
|
|
16577
|
+
const hasBackground = props.backgroundColor !== void 0;
|
|
16578
|
+
const hasBorder = (props.borderWidth ?? 0) > 0 && props.borderColor !== void 0;
|
|
16579
|
+
return hasBackground || hasBorder;
|
|
16580
|
+
}
|
|
16581
|
+
function drawBackground(graphics, props, width, height) {
|
|
16582
|
+
const bgColor = props.backgroundColor;
|
|
16583
|
+
const bgAlpha = props.backgroundAlpha ?? 1;
|
|
16584
|
+
const cornerRadius = props.cornerRadius ?? 0;
|
|
16585
|
+
const borderColor = props.borderColor;
|
|
16586
|
+
const borderWidth = props.borderWidth ?? 0;
|
|
16587
|
+
const borderAlpha = props.borderAlpha ?? 1;
|
|
16588
|
+
const hasBorder = borderWidth > 0 && borderColor !== void 0;
|
|
16589
|
+
if (bgColor !== void 0) graphics.fillStyle(bgColor, bgAlpha);
|
|
16590
|
+
if (hasBorder) graphics.lineStyle(borderWidth, borderColor, borderAlpha);
|
|
16591
|
+
if (cornerRadius !== 0) {
|
|
16592
|
+
if (bgColor !== void 0) graphics.fillRoundedRect(0, 0, width, height, cornerRadius);
|
|
16593
|
+
if (hasBorder) graphics.strokeRoundedRect(0, 0, width, height, cornerRadius);
|
|
16594
|
+
} else {
|
|
16595
|
+
if (bgColor !== void 0) graphics.fillRect(0, 0, width, height);
|
|
16596
|
+
if (hasBorder) graphics.strokeRect(0, 0, width, height);
|
|
16597
|
+
}
|
|
16598
|
+
}
|
|
16599
|
+
function getSceneBackgroundTextureCache(scene) {
|
|
16600
|
+
let cache = sceneBackgroundTextureCaches.get(scene);
|
|
16601
|
+
if (!cache) {
|
|
16602
|
+
cache = /* @__PURE__ */ new Map();
|
|
16603
|
+
sceneBackgroundTextureCaches.set(scene, cache);
|
|
16604
|
+
}
|
|
16605
|
+
return cache;
|
|
16606
|
+
}
|
|
16607
|
+
function hashCacheKey(value) {
|
|
16608
|
+
let hash = 2166136261;
|
|
16609
|
+
for (let i = 0; i < value.length; i++) {
|
|
16610
|
+
hash ^= value.charCodeAt(i);
|
|
16611
|
+
hash = Math.imul(hash, 16777619);
|
|
16612
|
+
}
|
|
16613
|
+
return (hash >>> 0).toString(36);
|
|
16614
|
+
}
|
|
16615
|
+
function normalizeCornerRadius$1(radius) {
|
|
16616
|
+
if (typeof radius === "number") return String(radius);
|
|
16617
|
+
if (!radius) return "0";
|
|
16618
|
+
return `${radius.tl ?? 0},${radius.tr ?? 0},${radius.bl ?? 0},${radius.br ?? 0}`;
|
|
16619
|
+
}
|
|
16620
|
+
function getBackgroundImageCacheKey(props, width, height) {
|
|
16621
|
+
return [
|
|
16622
|
+
Math.max(1, Math.ceil(width)),
|
|
16623
|
+
Math.max(1, Math.ceil(height)),
|
|
16624
|
+
props.backgroundColor ?? "none",
|
|
16625
|
+
props.backgroundAlpha ?? 1,
|
|
16626
|
+
normalizeCornerRadius$1(props.cornerRadius),
|
|
16627
|
+
props.borderWidth ?? 0,
|
|
16628
|
+
props.borderColor ?? "none",
|
|
16629
|
+
props.borderAlpha ?? 1
|
|
16630
|
+
].join("|");
|
|
16631
|
+
}
|
|
16632
|
+
function createBackgroundImage(scene, props, width, height) {
|
|
16633
|
+
if (!hasRenderableBackground(props)) return;
|
|
16634
|
+
const textureWidth = Math.max(1, Math.ceil(width));
|
|
16635
|
+
const textureHeight = Math.max(1, Math.ceil(height));
|
|
16636
|
+
const cacheKey = getBackgroundImageCacheKey(props, textureWidth, textureHeight);
|
|
16637
|
+
const textureKey = `__phaserjsx_bg_${hashCacheKey(cacheKey)}`;
|
|
16638
|
+
const cache = getSceneBackgroundTextureCache(scene);
|
|
16639
|
+
let entry = cache.get(cacheKey);
|
|
16640
|
+
if (!entry || !scene.textures.exists(entry.textureKey)) {
|
|
16641
|
+
const graphics = scene.add.graphics();
|
|
16642
|
+
drawBackground(graphics, props, textureWidth, textureHeight);
|
|
16643
|
+
graphics.generateTexture(textureKey, textureWidth, textureHeight);
|
|
16644
|
+
graphics.destroy();
|
|
16645
|
+
entry = {
|
|
16646
|
+
textureKey,
|
|
16647
|
+
refs: 0
|
|
16648
|
+
};
|
|
16649
|
+
cache.set(cacheKey, entry);
|
|
16650
|
+
}
|
|
16651
|
+
entry.refs++;
|
|
16652
|
+
const background = scene.add.image(0, 0, entry.textureKey);
|
|
16653
|
+
background.setOrigin(0, 0);
|
|
16654
|
+
background.__isBackground = true;
|
|
16655
|
+
background.__backgroundCacheKey = cacheKey;
|
|
16656
|
+
background.__backgroundTextureKey = entry.textureKey;
|
|
16657
|
+
background.once("destroy", () => releaseBackgroundImageTexture(background));
|
|
16658
|
+
return background;
|
|
16659
|
+
}
|
|
16660
|
+
function releaseBackgroundImageTexture(background) {
|
|
16661
|
+
if (background.__backgroundTextureReleased) return;
|
|
16662
|
+
const scene = background.scene;
|
|
16663
|
+
const cacheKey = background.__backgroundCacheKey;
|
|
16664
|
+
background.__backgroundTextureReleased = true;
|
|
16665
|
+
if (!scene || !cacheKey) return;
|
|
16666
|
+
const cache = sceneBackgroundTextureCaches.get(scene);
|
|
16667
|
+
const entry = cache?.get(cacheKey);
|
|
16668
|
+
if (!cache || !entry) return;
|
|
16669
|
+
entry.refs--;
|
|
16670
|
+
if (entry.refs <= 0) {
|
|
16671
|
+
if (scene.textures.exists(entry.textureKey)) scene.textures.remove(entry.textureKey);
|
|
16672
|
+
cache.delete(cacheKey);
|
|
16673
|
+
}
|
|
16674
|
+
}
|
|
16675
|
+
function destroyBackgroundImage(background) {
|
|
16676
|
+
background.destroy();
|
|
16677
|
+
}
|
|
16678
|
+
//#endregion
|
|
16574
16679
|
//#region src/components/appliers/applyBackground.ts
|
|
16575
16680
|
/**
|
|
16576
16681
|
* Applies background properties (color, alpha, corner radius, border)
|
|
@@ -16609,37 +16714,24 @@ function applyBackgroundProps(container, prev, next) {
|
|
|
16609
16714
|
const nextHasGraphics = nextBgColor !== void 0 || nextHasBorder;
|
|
16610
16715
|
if (prevHasGraphics && !nextHasGraphics) {
|
|
16611
16716
|
if (container.__background) {
|
|
16612
|
-
container.__background
|
|
16717
|
+
destroyBackgroundImage(container.__background);
|
|
16613
16718
|
delete container.__background;
|
|
16614
16719
|
}
|
|
16615
16720
|
} else if (!prevHasGraphics && nextHasGraphics) {
|
|
16616
16721
|
if (container.scene) {
|
|
16617
|
-
const background = container.scene
|
|
16618
|
-
if (
|
|
16619
|
-
if (nextHasBorder) background.lineStyle(nextBorderWidth, nextBorderColor, nextBorderAlpha);
|
|
16620
|
-
if (nextCornerRadius !== 0) {
|
|
16621
|
-
if (nextBgColor !== void 0) background.fillRoundedRect(0, 0, nextWidth, nextHeight, nextCornerRadius);
|
|
16622
|
-
if (nextHasBorder) background.strokeRoundedRect(0, 0, nextWidth, nextHeight, nextCornerRadius);
|
|
16623
|
-
} else {
|
|
16624
|
-
if (nextBgColor !== void 0) background.fillRect(0, 0, nextWidth, nextHeight);
|
|
16625
|
-
if (nextHasBorder) background.strokeRect(0, 0, nextWidth, nextHeight);
|
|
16626
|
-
}
|
|
16722
|
+
const background = createBackgroundImage(container.scene, next, nextWidth, nextHeight);
|
|
16723
|
+
if (!background) return;
|
|
16627
16724
|
container.addAt(background, 0);
|
|
16628
16725
|
container.__background = background;
|
|
16629
|
-
background.__isBackground = true;
|
|
16630
16726
|
}
|
|
16631
16727
|
} else if (container.__background && nextHasGraphics) {
|
|
16632
16728
|
if (prevBgColor !== nextBgColor || prevBgAlpha !== nextBgAlpha || prevWidth !== nextWidth || prevHeight !== nextHeight || prevCornerRadius !== nextCornerRadius || prevBorderWidth !== nextBorderWidth || prevBorderColor !== nextBorderColor || prevBorderAlpha !== nextBorderAlpha) {
|
|
16633
|
-
container.__background
|
|
16634
|
-
|
|
16635
|
-
if (
|
|
16636
|
-
|
|
16637
|
-
|
|
16638
|
-
|
|
16639
|
-
} else {
|
|
16640
|
-
if (nextBgColor !== void 0) container.__background.fillRect(0, 0, nextWidth, nextHeight);
|
|
16641
|
-
if (nextHasBorder) container.__background.strokeRect(0, 0, nextWidth, nextHeight);
|
|
16642
|
-
}
|
|
16729
|
+
const oldBackground = container.__background;
|
|
16730
|
+
const background = createBackgroundImage(container.scene, next, nextWidth, nextHeight);
|
|
16731
|
+
if (!background) return;
|
|
16732
|
+
container.addAt(background, 0);
|
|
16733
|
+
container.__background = background;
|
|
16734
|
+
destroyBackgroundImage(oldBackground);
|
|
16643
16735
|
}
|
|
16644
16736
|
}
|
|
16645
16737
|
}
|
|
@@ -17410,403 +17502,6 @@ function applyGesturesProps(scene, container, prev, next) {
|
|
|
17410
17502
|
}
|
|
17411
17503
|
}
|
|
17412
17504
|
//#endregion
|
|
17413
|
-
//#region src/clip/stencil-clip.ts
|
|
17414
|
-
/**
|
|
17415
|
-
* WebGL stencil-buffer clip for Phaser 4 Containers.
|
|
17416
|
-
*
|
|
17417
|
-
* Supports arbitrary nesting via the INCR/DECR model: each clip level
|
|
17418
|
-
* increments the stencil on enter and decrements on exit, so child clips are
|
|
17419
|
-
* automatically intersected with their parent clips at the hardware level.
|
|
17420
|
-
*
|
|
17421
|
-
* Shape variants:
|
|
17422
|
-
* - Plain rectangle (cornerRadius omitted or 0)
|
|
17423
|
-
* - Rounded rectangle (uniform radius or per-corner object)
|
|
17424
|
-
*
|
|
17425
|
-
* A single SDF-based shader handles both variants. For plain rectangles
|
|
17426
|
-
* u_radii is vec4(0) and the `discard` branch never fires — no overhead
|
|
17427
|
-
* compared to a rectangle-only shader.
|
|
17428
|
-
*
|
|
17429
|
-
* Transforms (translate, scale, rotation) are fully supported: the quad
|
|
17430
|
-
* corners are transformed through `container.getWorldTransformMatrix()` at
|
|
17431
|
-
* render time, so no per-layout world-position tracking is needed.
|
|
17432
|
-
*/
|
|
17433
|
-
/**
|
|
17434
|
-
* Shared depth counter per GL context.
|
|
17435
|
-
* Incremented before each clip's INCR pass, decremented after the DECR pass.
|
|
17436
|
-
* Reset to 0 at the start of every frame via a `prerender` hook.
|
|
17437
|
-
*/
|
|
17438
|
-
var _depthByGl = /* @__PURE__ */ new WeakMap();
|
|
17439
|
-
function getDepth(gl) {
|
|
17440
|
-
let d = _depthByGl.get(gl);
|
|
17441
|
-
if (!d) {
|
|
17442
|
-
d = { value: 0 };
|
|
17443
|
-
_depthByGl.set(gl, d);
|
|
17444
|
-
}
|
|
17445
|
-
return d;
|
|
17446
|
-
}
|
|
17447
|
-
var _prerenderHooked = /* @__PURE__ */ new WeakSet();
|
|
17448
|
-
/**
|
|
17449
|
-
* Registers a per-frame `prerender` listener that resets the depth counter.
|
|
17450
|
-
* Registered at most once per Phaser.Game instance.
|
|
17451
|
-
*/
|
|
17452
|
-
function ensurePrerenderReset(gl, game) {
|
|
17453
|
-
if (_prerenderHooked.has(game)) return;
|
|
17454
|
-
_prerenderHooked.add(game);
|
|
17455
|
-
game.events.on("prerender", () => {
|
|
17456
|
-
const d = _depthByGl.get(gl);
|
|
17457
|
-
if (d) d.value = 0;
|
|
17458
|
-
const fbo = _fboPatchByGl.get(gl);
|
|
17459
|
-
if (fbo) {
|
|
17460
|
-
fbo.current = null;
|
|
17461
|
-
fbo.saved = null;
|
|
17462
|
-
}
|
|
17463
|
-
});
|
|
17464
|
-
}
|
|
17465
|
-
var _fboPatchByGl = /* @__PURE__ */ new WeakMap();
|
|
17466
|
-
/**
|
|
17467
|
-
* Patches `gl.bindFramebuffer` once per GL context so that the stencil test
|
|
17468
|
-
* is automatically disabled when Phaser switches to an off-screen FBO (for
|
|
17469
|
-
* PostFX / RenderTexture rendering) and restored when switching back.
|
|
17470
|
-
*
|
|
17471
|
-
* Without this, a PostFX child rendered inside a stencil-clipped container
|
|
17472
|
-
* would be invisible: the FBO's stencil buffer starts at 0 while the active
|
|
17473
|
-
* stencil test requires `EQUAL(myDepth + 1)`, causing every fragment to fail.
|
|
17474
|
-
*
|
|
17475
|
-
* The patch is installed once per GL context and remains active for the
|
|
17476
|
-
* lifetime of the renderer. It is a no-op when no stencil clip is active.
|
|
17477
|
-
*/
|
|
17478
|
-
function ensureFboPatch(gl) {
|
|
17479
|
-
if (_fboPatchByGl.has(gl)) return;
|
|
17480
|
-
const state = {
|
|
17481
|
-
current: null,
|
|
17482
|
-
saved: null
|
|
17483
|
-
};
|
|
17484
|
-
_fboPatchByGl.set(gl, state);
|
|
17485
|
-
const origBind = gl.bindFramebuffer.bind(gl);
|
|
17486
|
-
gl.bindFramebuffer = (target, fb) => {
|
|
17487
|
-
const wasMain = state.current === null;
|
|
17488
|
-
const willBeMain = fb === null;
|
|
17489
|
-
const enteringOffscreen = wasMain && !willBeMain;
|
|
17490
|
-
const leavingOffscreen = !wasMain && willBeMain;
|
|
17491
|
-
if (enteringOffscreen && gl.getParameter(gl.STENCIL_TEST)) {
|
|
17492
|
-
state.saved = {
|
|
17493
|
-
func: gl.getParameter(gl.STENCIL_FUNC),
|
|
17494
|
-
ref: gl.getParameter(gl.STENCIL_REF),
|
|
17495
|
-
valueMask: gl.getParameter(gl.STENCIL_VALUE_MASK),
|
|
17496
|
-
fail: gl.getParameter(gl.STENCIL_FAIL),
|
|
17497
|
-
zfail: gl.getParameter(gl.STENCIL_PASS_DEPTH_FAIL),
|
|
17498
|
-
zpass: gl.getParameter(gl.STENCIL_PASS_DEPTH_PASS),
|
|
17499
|
-
writeMask: gl.getParameter(gl.STENCIL_WRITEMASK)
|
|
17500
|
-
};
|
|
17501
|
-
gl.disable(gl.STENCIL_TEST);
|
|
17502
|
-
}
|
|
17503
|
-
origBind(target, fb);
|
|
17504
|
-
state.current = fb;
|
|
17505
|
-
if (leavingOffscreen && state.saved) {
|
|
17506
|
-
gl.enable(gl.STENCIL_TEST);
|
|
17507
|
-
gl.stencilFunc(state.saved.func, state.saved.ref, state.saved.valueMask);
|
|
17508
|
-
gl.stencilOp(state.saved.fail, state.saved.zfail, state.saved.zpass);
|
|
17509
|
-
gl.stencilMask(state.saved.writeMask);
|
|
17510
|
-
state.saved = null;
|
|
17511
|
-
}
|
|
17512
|
-
};
|
|
17513
|
-
}
|
|
17514
|
-
/**
|
|
17515
|
-
* Vertex attributes:
|
|
17516
|
-
* a_ndc vec2 — NDC clip-space position (CPU-computed from world transform)
|
|
17517
|
-
* a_loc vec2 — position relative to the clip rect's center (for SDF)
|
|
17518
|
-
*
|
|
17519
|
-
* All four corners are pre-transformed on the CPU so the vertex shader is a
|
|
17520
|
-
* pure pass-through. This correctly handles translation, scale, and rotation
|
|
17521
|
-
* without a matrix uniform.
|
|
17522
|
-
*/
|
|
17523
|
-
var VERT_SRC = `
|
|
17524
|
-
attribute vec2 a_ndc;
|
|
17525
|
-
attribute vec2 a_loc;
|
|
17526
|
-
varying vec2 v_loc;
|
|
17527
|
-
void main(){gl_Position=vec4(a_ndc,0.,1.);v_loc=a_loc;}
|
|
17528
|
-
`;
|
|
17529
|
-
/**
|
|
17530
|
-
* SDF rounded-rectangle fragment shader.
|
|
17531
|
-
*
|
|
17532
|
-
* sdRoundedBox uses the IQ per-corner-radius technique:
|
|
17533
|
-
* r.xy = p.x > 0 ? r.yz : r.xw (right → tr/br, left → tl/bl)
|
|
17534
|
-
* r.x = p.y > 0 ? r.y : r.x (bottom or top within that pair)
|
|
17535
|
-
*
|
|
17536
|
-
* u_radii layout: (tl, tr, br, bl).
|
|
17537
|
-
*
|
|
17538
|
-
* For plain rectangles u_radii = vec4(0.0) and sdRoundedBox returns ≤ 0 for
|
|
17539
|
-
* all fragments inside the quad, so `discard` is never executed.
|
|
17540
|
-
*/
|
|
17541
|
-
var FRAG_SRC = `
|
|
17542
|
-
precision mediump float;
|
|
17543
|
-
varying vec2 v_loc;
|
|
17544
|
-
uniform vec2 u_halfSize;
|
|
17545
|
-
uniform vec4 u_radii;
|
|
17546
|
-
float sdRoundedBox(vec2 p,vec2 b,vec4 r){
|
|
17547
|
-
r.xy=p.x>0.?r.yz:r.xw;
|
|
17548
|
-
r.x =p.y>0.?r.y :r.x;
|
|
17549
|
-
vec2 q=abs(p)-b+r.x;
|
|
17550
|
-
return length(max(q,0.))+min(max(q.x,q.y),0.)-r.x;
|
|
17551
|
-
}
|
|
17552
|
-
void main(){
|
|
17553
|
-
if(sdRoundedBox(v_loc,u_halfSize,u_radii)>0.)discard;
|
|
17554
|
-
gl_FragColor=vec4(0.);
|
|
17555
|
-
}
|
|
17556
|
-
`;
|
|
17557
|
-
var _progByGl = /* @__PURE__ */ new WeakMap();
|
|
17558
|
-
/**
|
|
17559
|
-
* Returns (or lazily creates) the SDF stencil shader program for a GL context.
|
|
17560
|
-
* @param gl - The WebGL context.
|
|
17561
|
-
* @returns Compiled and linked WebGLProgram.
|
|
17562
|
-
*/
|
|
17563
|
-
function getStencilProg(gl) {
|
|
17564
|
-
let prog = _progByGl.get(gl);
|
|
17565
|
-
if (prog) return prog;
|
|
17566
|
-
const vs = gl.createShader(gl.VERTEX_SHADER);
|
|
17567
|
-
gl.shaderSource(vs, VERT_SRC);
|
|
17568
|
-
gl.compileShader(vs);
|
|
17569
|
-
const fs = gl.createShader(gl.FRAGMENT_SHADER);
|
|
17570
|
-
gl.shaderSource(fs, FRAG_SRC);
|
|
17571
|
-
gl.compileShader(fs);
|
|
17572
|
-
prog = gl.createProgram();
|
|
17573
|
-
gl.attachShader(prog, vs);
|
|
17574
|
-
gl.attachShader(prog, fs);
|
|
17575
|
-
gl.linkProgram(prog);
|
|
17576
|
-
_progByGl.set(gl, prog);
|
|
17577
|
-
return prog;
|
|
17578
|
-
}
|
|
17579
|
-
var _locsByProg = /* @__PURE__ */ new WeakMap();
|
|
17580
|
-
/**
|
|
17581
|
-
* Returns (or resolves and caches) the attribute/uniform locations for a program.
|
|
17582
|
-
* @param gl - The WebGL context.
|
|
17583
|
-
* @param prog - The shader program.
|
|
17584
|
-
* @returns Cached locations.
|
|
17585
|
-
*/
|
|
17586
|
-
function getShaderLocs(gl, prog) {
|
|
17587
|
-
let l = _locsByProg.get(prog);
|
|
17588
|
-
if (!l) {
|
|
17589
|
-
l = {
|
|
17590
|
-
ndc: gl.getAttribLocation(prog, "a_ndc"),
|
|
17591
|
-
loc: gl.getAttribLocation(prog, "a_loc"),
|
|
17592
|
-
halfSize: gl.getUniformLocation(prog, "u_halfSize"),
|
|
17593
|
-
radii: gl.getUniformLocation(prog, "u_radii")
|
|
17594
|
-
};
|
|
17595
|
-
_locsByProg.set(prog, l);
|
|
17596
|
-
}
|
|
17597
|
-
return l;
|
|
17598
|
-
}
|
|
17599
|
-
/**
|
|
17600
|
-
* Resolves the `cornerRadius` field to `[tl, tr, br, bl]` order matching the
|
|
17601
|
-
* `u_radii` vec4 uniform layout.
|
|
17602
|
-
* @param r - Raw corner radius value from the clip shape.
|
|
17603
|
-
* @returns Tuple `[tl, tr, br, bl]`.
|
|
17604
|
-
*/
|
|
17605
|
-
function resolveRadii(r) {
|
|
17606
|
-
if (!r) return [
|
|
17607
|
-
0,
|
|
17608
|
-
0,
|
|
17609
|
-
0,
|
|
17610
|
-
0
|
|
17611
|
-
];
|
|
17612
|
-
if (typeof r === "number") return [
|
|
17613
|
-
r,
|
|
17614
|
-
r,
|
|
17615
|
-
r,
|
|
17616
|
-
r
|
|
17617
|
-
];
|
|
17618
|
-
return [
|
|
17619
|
-
r.tl ?? 0,
|
|
17620
|
-
r.tr ?? 0,
|
|
17621
|
-
r.br ?? 0,
|
|
17622
|
-
r.bl ?? 0
|
|
17623
|
-
];
|
|
17624
|
-
}
|
|
17625
|
-
/** Stride in bytes: 4 floats × 4 bytes. */
|
|
17626
|
-
var STRIDE = 16;
|
|
17627
|
-
/**
|
|
17628
|
-
* Transforms the four clip-rect corners through the container's world matrix,
|
|
17629
|
-
* uploads them to the vertex buffer, and draws the quad into the stencil.
|
|
17630
|
-
*
|
|
17631
|
-
* Vertex buffer layout (16 floats / 4 vertices, TRIANGLE_FAN, TL→TR→BR→BL):
|
|
17632
|
-
* [ndcX, ndcY, locX, locY] × 4
|
|
17633
|
-
* where locX/Y is the position relative to the clip rect's center (for SDF).
|
|
17634
|
-
*
|
|
17635
|
-
* The three GL states tracked by Phaser's `WebGLGlobalWrapper`
|
|
17636
|
-
* (`CURRENT_PROGRAM`, `ARRAY_BUFFER_BINDING`, `VERTEX_ARRAY_BINDING`) are
|
|
17637
|
-
* saved and restored so its internal caches stay consistent.
|
|
17638
|
-
*
|
|
17639
|
-
* @param gl - The (VAO-polyfilled) WebGL context.
|
|
17640
|
-
* @param matrix - Container's current world transform matrix.
|
|
17641
|
-
* @param offsetX - Top-left X of the clip rect in local space.
|
|
17642
|
-
* @param offsetY - Top-left Y of the clip rect in local space.
|
|
17643
|
-
* @param w - Clip rect width in local units.
|
|
17644
|
-
* @param h - Clip rect height in local units.
|
|
17645
|
-
* @param logW - Logical game width (`renderer.width`).
|
|
17646
|
-
* @param logH - Logical game height (`renderer.height`).
|
|
17647
|
-
* @param radii - Per-corner radii tuple `[tl, tr, br, bl]`.
|
|
17648
|
-
* @param vertBuf - Persistent WebGLBuffer (64 bytes, DYNAMIC_DRAW).
|
|
17649
|
-
* @param verts - Reusable Float32Array(16) to avoid per-frame allocation.
|
|
17650
|
-
*/
|
|
17651
|
-
function drawMaskShape(gl, matrix, offsetX, offsetY, w, h, logW, logH, radii, vertBuf, verts) {
|
|
17652
|
-
const { a, b, c, d, tx, ty } = matrix;
|
|
17653
|
-
const hw = w / 2;
|
|
17654
|
-
const hh = h / 2;
|
|
17655
|
-
const cx = offsetX + hw;
|
|
17656
|
-
const cy = offsetY + hh;
|
|
17657
|
-
const corners = [
|
|
17658
|
-
[cx - hw, cy - hh],
|
|
17659
|
-
[cx + hw, cy - hh],
|
|
17660
|
-
[cx + hw, cy + hh],
|
|
17661
|
-
[cx - hw, cy + hh]
|
|
17662
|
-
];
|
|
17663
|
-
for (let i = 0; i < 4; i++) {
|
|
17664
|
-
const corner = corners[i];
|
|
17665
|
-
const lx = corner[0];
|
|
17666
|
-
const ly = corner[1];
|
|
17667
|
-
const wx = a * lx + c * ly + tx;
|
|
17668
|
-
const wy = b * lx + d * ly + ty;
|
|
17669
|
-
verts[i * 4 + 0] = wx / logW * 2 - 1;
|
|
17670
|
-
verts[i * 4 + 1] = 1 - wy / logH * 2;
|
|
17671
|
-
verts[i * 4 + 2] = lx - cx;
|
|
17672
|
-
verts[i * 4 + 3] = ly - cy;
|
|
17673
|
-
}
|
|
17674
|
-
const prevProg = gl.getParameter(gl.CURRENT_PROGRAM);
|
|
17675
|
-
const prevBuf = gl.getParameter(gl.ARRAY_BUFFER_BINDING);
|
|
17676
|
-
const prevVAO = gl.getParameter(34229);
|
|
17677
|
-
gl.bindVertexArray(null);
|
|
17678
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuf);
|
|
17679
|
-
gl.bufferSubData(gl.ARRAY_BUFFER, 0, verts);
|
|
17680
|
-
const prog = getStencilProg(gl);
|
|
17681
|
-
gl.useProgram(prog);
|
|
17682
|
-
const locs = getShaderLocs(gl, prog);
|
|
17683
|
-
gl.enableVertexAttribArray(locs.ndc);
|
|
17684
|
-
gl.vertexAttribPointer(locs.ndc, 2, gl.FLOAT, false, STRIDE, 0);
|
|
17685
|
-
gl.enableVertexAttribArray(locs.loc);
|
|
17686
|
-
gl.vertexAttribPointer(locs.loc, 2, gl.FLOAT, false, STRIDE, 8);
|
|
17687
|
-
gl.uniform2f(locs.halfSize, hw, hh);
|
|
17688
|
-
gl.uniform4f(locs.radii, radii[0], radii[1], radii[2], radii[3]);
|
|
17689
|
-
gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);
|
|
17690
|
-
gl.disableVertexAttribArray(locs.ndc);
|
|
17691
|
-
gl.disableVertexAttribArray(locs.loc);
|
|
17692
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, prevBuf);
|
|
17693
|
-
gl.useProgram(prevProg);
|
|
17694
|
-
gl.bindVertexArray(prevVAO);
|
|
17695
|
-
}
|
|
17696
|
-
var STENCIL_HANDLE = Symbol("stencilClipHandle");
|
|
17697
|
-
/**
|
|
17698
|
-
* Applies a WebGL stencil-buffer clip to a Phaser 4 Container.
|
|
17699
|
-
*
|
|
17700
|
-
* The clip rectangle is expressed in the container's **local coordinate
|
|
17701
|
-
* space**. `offsetX`/`offsetY` mark the top-left corner (default 0/0), so
|
|
17702
|
-
* a container whose visual area starts at its local origin can be clipped with
|
|
17703
|
-
* `applyStencilClip(container, { width, height })`.
|
|
17704
|
-
*
|
|
17705
|
-
* **Nesting** is handled transparently: each clip level occupies one stencil
|
|
17706
|
-
* value (0 = no clip, 1 = depth 0, 2 = depth 1, …). Child clips are always
|
|
17707
|
-
* the intersection of their own shape and all ancestor shapes.
|
|
17708
|
-
*
|
|
17709
|
-
* **Transforms** (translate, scale, rotation) are re-evaluated from
|
|
17710
|
-
* `container.getWorldTransformMatrix()` on every frame, so animated or
|
|
17711
|
-
* scroll-driven containers clip correctly without any manual update call.
|
|
17712
|
-
*
|
|
17713
|
-
* If a stencil clip is already attached to the container, calling this
|
|
17714
|
-
* function again calls `handle.update(shape)` on the existing handle and
|
|
17715
|
-
* returns it.
|
|
17716
|
-
*
|
|
17717
|
-
* @param container - The container to clip.
|
|
17718
|
-
* @param shape - Clip rect geometry in local units.
|
|
17719
|
-
* @returns A handle to modify dimensions / corner radii or remove the clip.
|
|
17720
|
-
*/
|
|
17721
|
-
function applyStencilClip(container, shape) {
|
|
17722
|
-
const obj = container;
|
|
17723
|
-
if (obj[STENCIL_HANDLE]) {
|
|
17724
|
-
obj[STENCIL_HANDLE].update(shape);
|
|
17725
|
-
return obj[STENCIL_HANDLE];
|
|
17726
|
-
}
|
|
17727
|
-
if (container.scene.renderer.type !== Phaser.WEBGL) return {
|
|
17728
|
-
update() {},
|
|
17729
|
-
destroy() {}
|
|
17730
|
-
};
|
|
17731
|
-
const gl = container.scene.renderer.gl;
|
|
17732
|
-
ensurePrerenderReset(gl, container.scene.game);
|
|
17733
|
-
ensureFboPatch(gl);
|
|
17734
|
-
const vertBuf = gl.createBuffer();
|
|
17735
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuf);
|
|
17736
|
-
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(16), gl.DYNAMIC_DRAW);
|
|
17737
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
17738
|
-
const verts = new Float32Array(16);
|
|
17739
|
-
let clipW = shape.width;
|
|
17740
|
-
let clipH = shape.height;
|
|
17741
|
-
let clipOffsetX = shape.offsetX ?? 0;
|
|
17742
|
-
let clipOffsetY = shape.offsetY ?? 0;
|
|
17743
|
-
let radii = resolveRadii(shape.cornerRadius);
|
|
17744
|
-
let destroyed = false;
|
|
17745
|
-
const wrapper = (webglRenderer, go, drawingContext, parentMatrix, renderStep = 0, displayList, displayListIndex) => {
|
|
17746
|
-
const renderNext = () => {
|
|
17747
|
-
go.renderWebGLStep(webglRenderer, go, drawingContext, parentMatrix, renderStep + 1, displayList, displayListIndex);
|
|
17748
|
-
};
|
|
17749
|
-
if (destroyed) {
|
|
17750
|
-
renderNext();
|
|
17751
|
-
return;
|
|
17752
|
-
}
|
|
17753
|
-
const matrix = container.getWorldTransformMatrix();
|
|
17754
|
-
const rn = webglRenderer.renderNodes;
|
|
17755
|
-
const depth = getDepth(gl);
|
|
17756
|
-
const myDepth = depth.value++;
|
|
17757
|
-
const logW = webglRenderer.width;
|
|
17758
|
-
const logH = webglRenderer.height;
|
|
17759
|
-
rn.finishBatch();
|
|
17760
|
-
if (myDepth === 0) gl.enable(gl.STENCIL_TEST);
|
|
17761
|
-
gl.colorMask(false, false, false, false);
|
|
17762
|
-
gl.stencilMask(255);
|
|
17763
|
-
gl.stencilFunc(gl.EQUAL, myDepth, 255);
|
|
17764
|
-
gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);
|
|
17765
|
-
drawMaskShape(gl, matrix, clipOffsetX, clipOffsetY, clipW, clipH, logW, logH, radii, vertBuf, verts);
|
|
17766
|
-
gl.colorMask(true, true, true, true);
|
|
17767
|
-
gl.stencilFunc(gl.EQUAL, myDepth + 1, 255);
|
|
17768
|
-
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
|
|
17769
|
-
gl.stencilMask(0);
|
|
17770
|
-
renderNext();
|
|
17771
|
-
rn.finishBatch();
|
|
17772
|
-
gl.colorMask(false, false, false, false);
|
|
17773
|
-
gl.stencilMask(255);
|
|
17774
|
-
gl.stencilFunc(gl.EQUAL, myDepth + 1, 255);
|
|
17775
|
-
gl.stencilOp(gl.KEEP, gl.KEEP, gl.DECR);
|
|
17776
|
-
drawMaskShape(gl, matrix, clipOffsetX, clipOffsetY, clipW, clipH, logW, logH, radii, vertBuf, verts);
|
|
17777
|
-
gl.colorMask(true, true, true, true);
|
|
17778
|
-
depth.value--;
|
|
17779
|
-
if (myDepth === 0) {
|
|
17780
|
-
gl.disable(gl.STENCIL_TEST);
|
|
17781
|
-
gl.stencilMask(255);
|
|
17782
|
-
} else {
|
|
17783
|
-
gl.stencilFunc(gl.EQUAL, myDepth, 255);
|
|
17784
|
-
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
|
|
17785
|
-
gl.stencilMask(0);
|
|
17786
|
-
}
|
|
17787
|
-
};
|
|
17788
|
-
const handle = {
|
|
17789
|
-
update(s) {
|
|
17790
|
-
if (s.width !== void 0) clipW = s.width;
|
|
17791
|
-
if (s.height !== void 0) clipH = s.height;
|
|
17792
|
-
if (s.offsetX !== void 0) clipOffsetX = s.offsetX;
|
|
17793
|
-
if (s.offsetY !== void 0) clipOffsetY = s.offsetY;
|
|
17794
|
-
if ("cornerRadius" in s) radii = resolveRadii(s.cornerRadius);
|
|
17795
|
-
},
|
|
17796
|
-
destroy() {
|
|
17797
|
-
if (destroyed) return;
|
|
17798
|
-
destroyed = true;
|
|
17799
|
-
gl.deleteBuffer(vertBuf);
|
|
17800
|
-
const index = obj._renderSteps.indexOf(wrapper);
|
|
17801
|
-
if (index !== -1) obj._renderSteps.splice(index, 1);
|
|
17802
|
-
delete obj[STENCIL_HANDLE];
|
|
17803
|
-
}
|
|
17804
|
-
};
|
|
17805
|
-
obj.addRenderStep(wrapper, 0);
|
|
17806
|
-
obj[STENCIL_HANDLE] = handle;
|
|
17807
|
-
return handle;
|
|
17808
|
-
}
|
|
17809
|
-
//#endregion
|
|
17810
17505
|
//#region src/core-props.ts
|
|
17811
17506
|
/**
|
|
17812
17507
|
* Normalize edge insets - converts number to all-sides object
|
|
@@ -17865,23 +17560,13 @@ function updateBackground(container, width, height) {
|
|
|
17865
17560
|
if (background) {
|
|
17866
17561
|
const layoutProps = container.__layoutProps;
|
|
17867
17562
|
if (layoutProps) {
|
|
17868
|
-
const
|
|
17869
|
-
|
|
17870
|
-
const
|
|
17871
|
-
|
|
17872
|
-
|
|
17873
|
-
|
|
17874
|
-
|
|
17875
|
-
background.clear();
|
|
17876
|
-
if (bgColor !== void 0) background.fillStyle(bgColor, bgAlpha);
|
|
17877
|
-
if (hasBorder) background.lineStyle(borderWidth, borderColor, borderAlpha);
|
|
17878
|
-
if (cornerRadius !== 0) {
|
|
17879
|
-
if (bgColor !== void 0) background.fillRoundedRect(0, 0, width, height, cornerRadius);
|
|
17880
|
-
if (hasBorder) background.strokeRoundedRect(0, 0, width, height, cornerRadius);
|
|
17881
|
-
} else {
|
|
17882
|
-
if (bgColor !== void 0) background.fillRect(0, 0, width, height);
|
|
17883
|
-
if (hasBorder) background.strokeRect(0, 0, width, height);
|
|
17884
|
-
}
|
|
17563
|
+
const cacheKey = getBackgroundImageCacheKey(layoutProps, width, height);
|
|
17564
|
+
if (background.__backgroundCacheKey === cacheKey) return;
|
|
17565
|
+
const nextBackground = createBackgroundImage(container.scene, layoutProps, width, height);
|
|
17566
|
+
if (!nextBackground) return;
|
|
17567
|
+
container.addAt(nextBackground, 0);
|
|
17568
|
+
container.__background = nextBackground;
|
|
17569
|
+
destroyBackgroundImage(background);
|
|
17885
17570
|
DebugLogger.log("layout", "Background redrawn to:", {
|
|
17886
17571
|
width,
|
|
17887
17572
|
height
|
|
@@ -18838,12 +18523,10 @@ function applyOverflowMask(container, containerProps, width, height) {
|
|
|
18838
18523
|
height
|
|
18839
18524
|
};
|
|
18840
18525
|
if (containerProps.cornerRadius !== void 0) shapeBase.cornerRadius = containerProps.cornerRadius;
|
|
18841
|
-
|
|
18526
|
+
container.setStencilClip(shapeBase);
|
|
18527
|
+
const handle = container.getStencilClipHandle();
|
|
18528
|
+
if (!handle) return;
|
|
18842
18529
|
ext.__overflowClip = handle;
|
|
18843
|
-
container.once("destroy", () => {
|
|
18844
|
-
handle.destroy();
|
|
18845
|
-
delete ext.__overflowClip;
|
|
18846
|
-
});
|
|
18847
18530
|
DebugLogger.log("overflowMask", "Created stencil clip");
|
|
18848
18531
|
} else {
|
|
18849
18532
|
const update = {
|
|
@@ -18851,10 +18534,10 @@ function applyOverflowMask(container, containerProps, width, height) {
|
|
|
18851
18534
|
height,
|
|
18852
18535
|
cornerRadius: containerProps.cornerRadius ?? 0
|
|
18853
18536
|
};
|
|
18854
|
-
|
|
18537
|
+
container.updateStencilClip(update);
|
|
18855
18538
|
}
|
|
18856
18539
|
else if (ext.__overflowClip) {
|
|
18857
|
-
|
|
18540
|
+
container.clearStencilClip();
|
|
18858
18541
|
delete ext.__overflowClip;
|
|
18859
18542
|
DebugLogger.log("overflowMask", "Removed stencil clip");
|
|
18860
18543
|
}
|
|
@@ -18872,6 +18555,7 @@ var LAYOUT_CYCLE_TIME_MS = 20;
|
|
|
18872
18555
|
var LAYOUT_CYCLE_MAX = 5;
|
|
18873
18556
|
var LAYOUT_MAX_SIZE = 2e5;
|
|
18874
18557
|
var layoutCycleGuard = /* @__PURE__ */ new WeakMap();
|
|
18558
|
+
var deferredParentInvalidations = /* @__PURE__ */ new WeakSet();
|
|
18875
18559
|
function isCloseSize(a, b, epsilon) {
|
|
18876
18560
|
return Math.abs(a.width - b.width) < epsilon && Math.abs(a.height - b.height) < epsilon;
|
|
18877
18561
|
}
|
|
@@ -18895,6 +18579,8 @@ function invalidateParentLayoutIfNeeded(container, oldSize, newWidth, newHeight)
|
|
|
18895
18579
|
height: newHeight
|
|
18896
18580
|
};
|
|
18897
18581
|
const now = Date.now();
|
|
18582
|
+
const parent = container.parentContainer;
|
|
18583
|
+
if (!parent || !parent.__layoutProps) return;
|
|
18898
18584
|
const guard = layoutCycleGuard.get(container);
|
|
18899
18585
|
if (guard) {
|
|
18900
18586
|
if ((guard.prev ? isCloseSize(guard.prev, newSize, LAYOUT_CYCLE_EPSILON) : false) && now - guard.lastTime < LAYOUT_CYCLE_TIME_MS) guard.count += 1;
|
|
@@ -18904,11 +18590,15 @@ function invalidateParentLayoutIfNeeded(container, oldSize, newWidth, newHeight)
|
|
|
18904
18590
|
guard.lastTime = now;
|
|
18905
18591
|
layoutCycleGuard.set(container, guard);
|
|
18906
18592
|
if (guard.count >= LAYOUT_CYCLE_MAX) {
|
|
18907
|
-
DebugLogger.
|
|
18593
|
+
DebugLogger.log("layout", "Layout cycle detected, deferring parent invalidation", {
|
|
18908
18594
|
container,
|
|
18909
18595
|
oldSize,
|
|
18910
18596
|
newSize
|
|
18911
18597
|
});
|
|
18598
|
+
guard.count = 0;
|
|
18599
|
+
guard.lastTime = 0;
|
|
18600
|
+
layoutCycleGuard.set(container, guard);
|
|
18601
|
+
deferParentLayoutInvalidation(container);
|
|
18912
18602
|
return;
|
|
18913
18603
|
}
|
|
18914
18604
|
} else layoutCycleGuard.set(container, {
|
|
@@ -18916,9 +18606,20 @@ function invalidateParentLayoutIfNeeded(container, oldSize, newWidth, newHeight)
|
|
|
18916
18606
|
count: 0,
|
|
18917
18607
|
lastTime: now
|
|
18918
18608
|
});
|
|
18609
|
+
DebugLogger.log("layout", "Container size changed, invalidating parent:", `${oldSize.width}x${oldSize.height} -> ${newWidth}x${newHeight}`);
|
|
18610
|
+
invalidateParentLayout(container);
|
|
18611
|
+
}
|
|
18612
|
+
function deferParentLayoutInvalidation(container) {
|
|
18613
|
+
if (deferredParentInvalidations.has(container)) return;
|
|
18614
|
+
deferredParentInvalidations.add(container);
|
|
18615
|
+
DeferredLayoutQueue.defer(() => {
|
|
18616
|
+
deferredParentInvalidations.delete(container);
|
|
18617
|
+
invalidateParentLayout(container);
|
|
18618
|
+
});
|
|
18619
|
+
}
|
|
18620
|
+
function invalidateParentLayout(container) {
|
|
18919
18621
|
const parent = container.parentContainer;
|
|
18920
18622
|
if (!parent || !parent.__layoutProps) return;
|
|
18921
|
-
DebugLogger.log("layout", "Container size changed, invalidating parent:", `${oldSize.width}x${oldSize.height} -> ${newWidth}x${newHeight}`);
|
|
18922
18623
|
const grandParent = parent.parentContainer;
|
|
18923
18624
|
let grandParentSize;
|
|
18924
18625
|
if (grandParent && grandParent.__getLayoutSize) {
|
|
@@ -20948,22 +20649,22 @@ function getLayoutProps(container) {
|
|
|
20948
20649
|
return container.__layoutProps;
|
|
20949
20650
|
}
|
|
20950
20651
|
/**
|
|
20951
|
-
* Utility function to get background
|
|
20952
|
-
* Returns the
|
|
20652
|
+
* Utility function to get background object from a container
|
|
20653
|
+
* Returns the Image object used for backgroundColor, border, cornerRadius
|
|
20953
20654
|
* Useful for custom animations or modifications
|
|
20954
20655
|
* @param container - Phaser container with background
|
|
20955
|
-
* @returns
|
|
20656
|
+
* @returns Background image or undefined if container has no background
|
|
20956
20657
|
*/
|
|
20957
20658
|
function getBackgroundGraphics(container) {
|
|
20958
20659
|
if (!container) return void 0;
|
|
20959
20660
|
return container.__background;
|
|
20960
20661
|
}
|
|
20961
20662
|
/**
|
|
20962
|
-
* Hook to get background
|
|
20963
|
-
* Returns the
|
|
20663
|
+
* Hook to get background image from a ref
|
|
20664
|
+
* Returns the Image object used for rendering the background
|
|
20964
20665
|
* Useful for animating background properties (tint, alpha, etc.)
|
|
20965
20666
|
* @param ref - Ref to a Phaser container
|
|
20966
|
-
* @returns
|
|
20667
|
+
* @returns Background image or undefined
|
|
20967
20668
|
*/
|
|
20968
20669
|
function useBackgroundGraphics(ref) {
|
|
20969
20670
|
return getBackgroundGraphics(ref.current);
|
|
@@ -22713,8 +22414,6 @@ function showTooltip(scene, container, config) {
|
|
|
22713
22414
|
const textHeight = text.height;
|
|
22714
22415
|
const bgWidth = textWidth + paddingX * 2;
|
|
22715
22416
|
const bgHeight = textHeight + paddingY * 2;
|
|
22716
|
-
const cornerRadius = tooltipTheme.cornerRadius ?? 6;
|
|
22717
|
-
const graphics = scene.add.graphics();
|
|
22718
22417
|
const bg = bgColor ?? "#000000dd";
|
|
22719
22418
|
let fillColor = 0;
|
|
22720
22419
|
let fillAlpha = .87;
|
|
@@ -22730,9 +22429,17 @@ function showTooltip(scene, container, config) {
|
|
|
22730
22429
|
}
|
|
22731
22430
|
}
|
|
22732
22431
|
}
|
|
22733
|
-
|
|
22734
|
-
|
|
22735
|
-
|
|
22432
|
+
const background = createBackgroundImage(scene, {
|
|
22433
|
+
backgroundColor: fillColor,
|
|
22434
|
+
backgroundAlpha: fillAlpha,
|
|
22435
|
+
cornerRadius: tooltipTheme.cornerRadius ?? 6
|
|
22436
|
+
}, bgWidth, bgHeight);
|
|
22437
|
+
if (!background) {
|
|
22438
|
+
text.destroy();
|
|
22439
|
+
return;
|
|
22440
|
+
}
|
|
22441
|
+
background.setOrigin(.5, .5);
|
|
22442
|
+
const tooltipContainer = scene.add.container(0, 0, [background, text]);
|
|
22736
22443
|
tooltipContainer.setDepth(1e4);
|
|
22737
22444
|
const textBounds = tooltipContainer.getBounds();
|
|
22738
22445
|
const pos = calculateTooltipPosition(targetBounds, position, offset, textBounds.width, textBounds.height);
|
|
@@ -22883,29 +22590,12 @@ function applyTooltip(scene, container, nextCallback, existingOnHoverStart, exis
|
|
|
22883
22590
|
*/
|
|
22884
22591
|
function createBackground(scene, container, props) {
|
|
22885
22592
|
const hasBackground = props.backgroundColor !== void 0;
|
|
22886
|
-
const hasBorder = props.borderColor !== void 0;
|
|
22593
|
+
const hasBorder = (props.borderWidth ?? 0) > 0 && props.borderColor !== void 0;
|
|
22887
22594
|
if (hasBackground || hasBorder) {
|
|
22888
|
-
const
|
|
22889
|
-
|
|
22890
|
-
const bgColor = props.backgroundColor;
|
|
22891
|
-
const bgAlpha = props.backgroundAlpha ?? 1;
|
|
22892
|
-
const cornerRadius = props.cornerRadius ?? 0;
|
|
22893
|
-
const borderColor = props.borderColor;
|
|
22894
|
-
const borderWidth = props.borderWidth ?? 0;
|
|
22895
|
-
const borderAlpha = props.borderAlpha ?? 1;
|
|
22896
|
-
const background = scene.add.graphics();
|
|
22897
|
-
if (bgColor !== void 0) background.fillStyle(bgColor, bgAlpha);
|
|
22898
|
-
if (borderWidth > 0 && borderColor !== void 0) background.lineStyle(borderWidth, borderColor, borderAlpha);
|
|
22899
|
-
if (cornerRadius !== 0) {
|
|
22900
|
-
if (bgColor !== void 0) background.fillRoundedRect(0, 0, width, height, cornerRadius);
|
|
22901
|
-
if (borderWidth > 0 && borderColor !== void 0) background.strokeRoundedRect(0, 0, width, height, cornerRadius);
|
|
22902
|
-
} else {
|
|
22903
|
-
if (bgColor !== void 0) background.fillRect(0, 0, width, height);
|
|
22904
|
-
if (borderWidth > 0 && borderColor !== void 0) background.strokeRect(0, 0, width, height);
|
|
22905
|
-
}
|
|
22595
|
+
const background = createBackgroundImage(scene, props, typeof props.width === "number" ? props.width : 100, typeof props.height === "number" ? props.height : 100);
|
|
22596
|
+
if (!background) return;
|
|
22906
22597
|
container.addAt(background, 0);
|
|
22907
22598
|
container.__background = background;
|
|
22908
|
-
background.__isBackground = true;
|
|
22909
22599
|
}
|
|
22910
22600
|
}
|
|
22911
22601
|
//#endregion
|
|
@@ -25366,6 +25056,9 @@ function Accordion(props) {
|
|
|
25366
25056
|
}, [isOpen, autoHeight]);
|
|
25367
25057
|
const [contentHeight, setContentHeight] = useSpring(animated ? isOpen ? autoHeight ? measuredHeight : maxHeight : 0 : isOpen ? autoHeight ? measuredHeight : maxHeight : 0, animationConfig, props.onAnimationEnd);
|
|
25368
25058
|
if (animated) useForceRedraw(20, contentHeight);
|
|
25059
|
+
const animatedContentHeight = Math.max(0, contentHeight.value);
|
|
25060
|
+
const resolvedContentHeight = animated ? animatedContentHeight : isOpen ? void 0 : 0;
|
|
25061
|
+
const resolvedContentVisible = animated ? animatedContentHeight > .5 : isOpen;
|
|
25369
25062
|
const handleToggle = () => {
|
|
25370
25063
|
const newState = !isOpen;
|
|
25371
25064
|
setInternalOpen(newState);
|
|
@@ -25399,6 +25092,9 @@ function Accordion(props) {
|
|
|
25399
25092
|
autoHeight && /* @__PURE__ */ jsx(View, {
|
|
25400
25093
|
visible: false,
|
|
25401
25094
|
direction: "stack",
|
|
25095
|
+
headless: true,
|
|
25096
|
+
width: 0,
|
|
25097
|
+
height: 0,
|
|
25402
25098
|
children: /* @__PURE__ */ jsx(View, {
|
|
25403
25099
|
ref: measurementRef,
|
|
25404
25100
|
...contentTheme,
|
|
@@ -25407,9 +25103,9 @@ function Accordion(props) {
|
|
|
25407
25103
|
}),
|
|
25408
25104
|
/* @__PURE__ */ jsx(View, {
|
|
25409
25105
|
direction: "column",
|
|
25410
|
-
height:
|
|
25106
|
+
height: resolvedContentHeight,
|
|
25411
25107
|
overflow: "hidden",
|
|
25412
|
-
visible:
|
|
25108
|
+
visible: resolvedContentVisible,
|
|
25413
25109
|
...contentTheme,
|
|
25414
25110
|
children: props.children
|
|
25415
25111
|
})
|
|
@@ -27719,6 +27415,7 @@ function Dropdown(props) {
|
|
|
27719
27415
|
useForceRedraw(20, overlayHeight);
|
|
27720
27416
|
const [arrowRotation, setArrowRotation] = useSpring(isOpen ? Math.PI : 0, animationConfig);
|
|
27721
27417
|
useForceRedraw(20, arrowRotation);
|
|
27418
|
+
const resolvedOverlayHeight = Math.max(0, overlayHeight.value);
|
|
27722
27419
|
const handleToggle = (event) => {
|
|
27723
27420
|
if (props.disabled) return;
|
|
27724
27421
|
event?.stopPropagation();
|
|
@@ -27890,7 +27587,7 @@ function Dropdown(props) {
|
|
|
27890
27587
|
})
|
|
27891
27588
|
});
|
|
27892
27589
|
const overlay = /* @__PURE__ */ jsx(View, {
|
|
27893
|
-
height:
|
|
27590
|
+
height: resolvedOverlayHeight,
|
|
27894
27591
|
width: overlayPosition.width,
|
|
27895
27592
|
overflow: "hidden",
|
|
27896
27593
|
children: /* @__PURE__ */ jsx(View, {
|
|
@@ -27898,7 +27595,7 @@ function Dropdown(props) {
|
|
|
27898
27595
|
direction: "column",
|
|
27899
27596
|
width: "fill",
|
|
27900
27597
|
height: "fill",
|
|
27901
|
-
visible: isOpen ||
|
|
27598
|
+
visible: isOpen || resolvedOverlayHeight > .1,
|
|
27902
27599
|
...overlayTheme,
|
|
27903
27600
|
children: placement === "top" ? /* @__PURE__ */ jsxs(Fragment, { children: [optionsList, filterInput] }) : /* @__PURE__ */ jsxs(Fragment, { children: [filterInput, optionsList] })
|
|
27904
27601
|
})
|
|
@@ -29559,4 +29256,4 @@ function TransformOriginView({ originX = .5, originY = .5, width, height, x = 0,
|
|
|
29559
29256
|
//#endregion
|
|
29560
29257
|
export { RadioButton as $, textCreator as $n, shouldComponentUpdate as $t, computed as A, midnightPreset as An, createTheme as At, DOMInputElement as B, hexToNumber as Bn, remountAll as Bt, CharText as C, defaultTextStyleTokens as Cn, graphicsCreator as Cr, createWiggleEffect as Ct, Modal as D, generateColorScale as Dn, register as Dr, useGameObjectEffect as Dt, Dialog as E, forestGreenPreset as En, nodeRegistry as Er, createZoomOutEffect as Et, SpringPhysics as F, darken as Fn, getMountStats as Ft, useSVGTextures as G, rgbToHsl as Gn, disposeCtx as Gt, releaseSVGTexture as H, lightenHex as Hn, unmountJSX as Ht, animatedSignal as I, darkenHex as In, mount as It, Particles as J, normalizeCornerRadius as Jn, getLayoutProps as Jt, svgToTexture as K, rgbToNumber as Kn, getBackgroundGraphics as Kt, isAnimatedSignal as L, ensureContrast as Ln, mountJSX as Lt, useSprings as M, presets as Mn, mergeThemes as Mt, DEFAULT_SPRING_CONFIG as N, alpha as Nn, themeRegistry as Nt, Portal as O, getPreset as On, viewCreator as Ot, SPRING_PRESETS as P, createTextStyle as Pn, createElement as Pt, RadioGroup as Q, tileSpritePatcher as Qn, shallowEqual as Qt, unwrapSignal as R, getContrastRatio as Rn, normalizeVNodeLike as Rt, CharTextInput as S, defaultSpacingTokens as Sn, imagePatcher as Sr, createTadaEffect as St, WrapText as T, applyLightMode as Tn, host as Tr, createZoomInEffect as Tt, releaseSVGTextures as U, numberToHex as Un, portalRegistry as Ut, releaseAllSVGTextures as V, lighten as Vn, unmount as Vt, useSVGTexture as W, numberToRgb as Wn, View as Wt, Text as X, normalizeGap as Xn, getLayoutSize as Xt, TileSprite as Y, normalizeEdgeInsets as Yn, getLayoutRect as Yt, Sprite as Z, tileSpriteCreator as Zn, getWorldLayoutRect as Zt, Dropdown as _, createDefaultTheme as _n, buildEmitZone as _r, createShakeEffect as _t, Tabs as a, useLayoutRect as an, spriteCreator as ar, resolveEffect as at, calculateSliderSize as b, defaultRadiusTokens as bn, nineSlicePatcher as br, createSpinEffect as bt, Sidebar as c, useRedraw as cn, particlesPatcher as cr, createFadeEffect as ct, NineSlice as d, useState as dn, applyEmitterConfig as dr, createFlipOutEffect as dt, useBackgroundGraphics as en, textPatcher as er, Graphics as et, Joystick as f, useTheme as fn, getFirstEmitter as fr, createFloatEffect as ft, Image$1 as g, getRenderContext as gn, buildDeathZonesFromLayout as gr, createPulseEffect as gt, useIconPreload as h, withHooks as hn, resolveParticlePreset as hr, createPressEffect as ht, TabPanel as i, useLayoutEffect as in, DevPresets as ir, applyEffectByName as it, useSpring as j, oceanBluePreset as jn, getThemedProps as jt, Accordion as k, getPresetWithMode as kn, viewPatcher as kt, RefOriginView as l, useRef as ln, applyDeathZone as lr, createFlashEffect as lt, createIconComponent as m, useWorldLayoutRect as mn, PARTICLE_PRESET_REGISTRY as mr, createNoneEffect as mt, Toggle as n, useEffect as nn, DebugLogger as nr, DEFAULT_EFFECT as nt, RangeSlider as o, useLayoutSize as on, spritePatcher as or, createBounceEffect as ot, Icon as p, useViewportSize as pn, isParticleEmitter as pr, createJelloEffect as pt, registerBuiltins as q, HexColor as qn, getCurrent as qt, Tab as r, useForceRedraw as rn, DevConfig as rr, EFFECT_REGISTRY as rt, Slider as s, useMemo as sn, particlesCreator as sr, createBreatheEffect as st, TransformOriginView as t, useCallback as tn, viewportRegistry as tr, Button as tt, NineSliceButton as u, useScene as un, applyEmitZone as ur, createFlipInEffect as ut, ScrollView as v, defaultTheme as vn, buildEmitZoneFromLayout as vr, createSlideInEffect as vt, AlertDialog as w, applyDarkMode as wn, graphicsPatcher as wr, createWobbleEffect as wt, Divider as x, defaultSizeTokens as xn, imageCreator as xr, createSwingEffect as xt, ScrollSlider as y, createTextStyleTokens as yn, nineSliceCreator as yr, createSlideOutEffect as yt, KeyboardInputManager as z, hex as zn, patchVNode as zt };
|
|
29561
29258
|
|
|
29562
|
-
//# sourceMappingURL=custom-
|
|
29259
|
+
//# sourceMappingURL=custom-C_w8D39m.js.map
|