@number10/phaserjsx 0.4.0 → 0.4.2
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 +1 -1
- package/dist/{TransformOriginView-Bx81YEUU.cjs → TransformOriginView-CrzevUOh.cjs} +429 -388
- package/dist/TransformOriginView-CrzevUOh.cjs.map +1 -0
- package/dist/{TransformOriginView-DCvId72M.js → TransformOriginView-TeXhLqNs.js} +393 -369
- package/dist/TransformOriginView-TeXhLqNs.js.map +1 -0
- package/dist/camera/use-camera-fx.d.ts +4 -1
- package/dist/camera/use-camera-fx.d.ts.map +1 -1
- package/dist/components/appliers/applyBackground.d.ts +5 -1
- package/dist/components/appliers/applyBackground.d.ts.map +1 -1
- package/dist/components/appliers/applyGestures.d.ts +1 -1
- package/dist/components/appliers/applyGestures.d.ts.map +1 -1
- package/dist/components/appliers/applyGraphics.d.ts +4 -1
- package/dist/components/appliers/applyGraphics.d.ts.map +1 -1
- package/dist/components/appliers/applyGraphicsLayout.d.ts +4 -1
- package/dist/components/appliers/applyGraphicsLayout.d.ts.map +1 -1
- package/dist/components/appliers/applyImage.d.ts +4 -1
- package/dist/components/appliers/applyImage.d.ts.map +1 -1
- package/dist/components/appliers/applyImageLayout.d.ts +4 -1
- package/dist/components/appliers/applyImageLayout.d.ts.map +1 -1
- package/dist/components/appliers/applyNineSlice.d.ts +4 -1
- package/dist/components/appliers/applyNineSlice.d.ts.map +1 -1
- package/dist/components/appliers/applyNineSliceLayout.d.ts +4 -1
- package/dist/components/appliers/applyNineSliceLayout.d.ts.map +1 -1
- package/dist/components/appliers/applySprite.d.ts +4 -1
- package/dist/components/appliers/applySprite.d.ts.map +1 -1
- package/dist/components/appliers/applySpriteLayout.d.ts +4 -1
- package/dist/components/appliers/applySpriteLayout.d.ts.map +1 -1
- package/dist/components/appliers/applyTextLayout.d.ts +4 -1
- package/dist/components/appliers/applyTextLayout.d.ts.map +1 -1
- package/dist/components/appliers/applyTooltip.d.ts +5 -1
- package/dist/components/appliers/applyTooltip.d.ts.map +1 -1
- package/dist/components/creators/createBackground.d.ts +5 -1
- package/dist/components/creators/createBackground.d.ts.map +1 -1
- package/dist/components/creators/createGestures.d.ts +1 -1
- package/dist/components/creators/createGestures.d.ts.map +1 -1
- package/dist/components/creators/createGraphicsLayout.d.ts +4 -1
- package/dist/components/creators/createGraphicsLayout.d.ts.map +1 -1
- package/dist/components/creators/createImageLayout.d.ts +4 -1
- package/dist/components/creators/createImageLayout.d.ts.map +1 -1
- package/dist/components/creators/createNineSliceLayout.d.ts +4 -1
- package/dist/components/creators/createNineSliceLayout.d.ts.map +1 -1
- package/dist/components/creators/createSpriteLayout.d.ts +4 -1
- package/dist/components/creators/createSpriteLayout.d.ts.map +1 -1
- package/dist/components/creators/createTextLayout.d.ts +4 -1
- package/dist/components/creators/createTextLayout.d.ts.map +1 -1
- package/dist/components/custom/Graphics.d.ts +6 -1
- package/dist/components/custom/Graphics.d.ts.map +1 -1
- package/dist/components/custom/Image.d.ts +6 -1
- package/dist/components/custom/Image.d.ts.map +1 -1
- package/dist/components/custom/NineSlice.d.ts +6 -1
- package/dist/components/custom/NineSlice.d.ts.map +1 -1
- package/dist/components/custom/Sprite.d.ts +1 -1
- package/dist/components/custom/Sprite.d.ts.map +1 -1
- package/dist/components/custom/Text.d.ts +6 -1
- package/dist/components/custom/Text.d.ts.map +1 -1
- package/dist/components/custom/TileSprite.d.ts +1 -1
- package/dist/components/custom/TileSprite.d.ts.map +1 -1
- package/dist/components/custom/View.d.ts +6 -1
- package/dist/components/custom/View.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/graphics.d.ts +107 -1
- package/dist/components/primitives/graphics.d.ts.map +1 -1
- package/dist/components/primitives/image.d.ts +114 -1
- package/dist/components/primitives/image.d.ts.map +1 -1
- package/dist/components/primitives/nineslice.d.ts +161 -1
- package/dist/components/primitives/nineslice.d.ts.map +1 -1
- package/dist/components/primitives/sprite.d.ts +90 -1
- package/dist/components/primitives/sprite.d.ts.map +1 -1
- package/dist/components/primitives/text.d.ts +130 -1
- package/dist/components/primitives/text.d.ts.map +1 -1
- package/dist/components/primitives/tilesprite.d.ts +115 -1
- package/dist/components/primitives/tilesprite.d.ts.map +1 -1
- package/dist/components/primitives/view.d.ts +107 -1
- package/dist/components/primitives/view.d.ts.map +1 -1
- package/dist/core-types.d.ts +5 -1
- package/dist/core-types.d.ts.map +1 -1
- package/dist/design-tokens/design-token-types.d.ts +5 -1
- package/dist/design-tokens/design-token-types.d.ts.map +1 -1
- package/dist/gestures/gesture-manager.d.ts +5 -1
- package/dist/gestures/gesture-manager.d.ts.map +1 -1
- package/dist/gestures/gesture-types.d.ts +4 -1
- package/dist/gestures/gesture-types.d.ts.map +1 -1
- package/dist/hooks-svg.d.ts +5 -1
- package/dist/hooks-svg.d.ts.map +1 -1
- package/dist/host.d.ts +5 -1
- package/dist/host.d.ts.map +1 -1
- package/dist/index.cjs +28 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/layout/appliers/background-applier.d.ts +4 -1
- package/dist/layout/appliers/background-applier.d.ts.map +1 -1
- package/dist/layout/appliers/container-applier.d.ts +4 -1
- package/dist/layout/appliers/container-applier.d.ts.map +1 -1
- package/dist/layout/layout-engine-test-utils.d.ts +4 -1
- package/dist/layout/layout-engine-test-utils.d.ts.map +1 -1
- package/dist/layout/layout-engine.d.ts +5 -1
- package/dist/layout/layout-engine.d.ts.map +1 -1
- package/dist/layout/types.d.ts +4 -1
- package/dist/layout/types.d.ts.map +1 -1
- package/dist/layout/utils/child-utils.d.ts +4 -1
- package/dist/layout/utils/child-utils.d.ts.map +1 -1
- package/dist/particles/emit-zone.d.ts +4 -1
- package/dist/particles/emit-zone.d.ts.map +1 -1
- package/dist/particles/particle-types.d.ts +4 -1
- package/dist/particles/particle-types.d.ts.map +1 -1
- package/dist/particles/preset-registry.d.ts +4 -1
- package/dist/particles/preset-registry.d.ts.map +1 -1
- package/dist/plugin.d.ts +5 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/portal/portal-registry.d.ts +4 -1
- package/dist/portal/portal-registry.d.ts.map +1 -1
- package/dist/portal/portal-types.d.ts +5 -1
- package/dist/portal/portal-types.d.ts.map +1 -1
- package/dist/render-context.d.ts +5 -1
- package/dist/render-context.d.ts.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/dom-input-manager.d.ts +5 -1
- package/dist/utils/dom-input-manager.d.ts.map +1 -1
- package/dist/utils/fast-deep-equal.d.ts +4 -0
- package/dist/utils/fast-deep-equal.d.ts.map +1 -0
- package/dist/utils/svg-texture.d.ts +5 -1
- package/dist/utils/svg-texture.d.ts.map +1 -1
- package/dist/utils/texture-registry.d.ts +5 -1
- package/dist/utils/texture-registry.d.ts.map +1 -1
- package/dist/vdom.d.ts +1 -1
- package/dist/vdom.d.ts.map +1 -1
- package/package.json +11 -1
- package/dist/TransformOriginView-Bx81YEUU.cjs.map +0 -1
- package/dist/TransformOriginView-DCvId72M.js.map +0 -1
|
@@ -1,7 +1,113 @@
|
|
|
1
|
-
import { default as Phaser } from 'phaser';
|
|
2
1
|
import { LayoutProps, PhaserProps, TransformProps } from '../../core-props';
|
|
3
2
|
import { HostCreator, HostPatcher } from '../../host';
|
|
4
3
|
import { PropsDefaultExtension } from '../../types';
|
|
4
|
+
/**
|
|
5
|
+
* Graphics component - Phaser Graphics GameObject (custom shapes)
|
|
6
|
+
* Status: IMPLEMENTED ✅
|
|
7
|
+
*
|
|
8
|
+
* Design Decisions & Answers:
|
|
9
|
+
* ===========================
|
|
10
|
+
*
|
|
11
|
+
* 1. Headless Default: TRUE ✅
|
|
12
|
+
* Rationale: Graphics are typically decorative (custom shapes, effects).
|
|
13
|
+
* They should NOT affect layout unless explicitly configured.
|
|
14
|
+
* Use Cases:
|
|
15
|
+
* - ✅ Headless (default): Debug visualizations, particle trails, decorative effects
|
|
16
|
+
* - ❌ Layout-aware: Custom UI shapes (via headless=false + explicit width/height)
|
|
17
|
+
*
|
|
18
|
+
* 2. View Background vs. Graphics Component: CLEAR SEPARATION ✅
|
|
19
|
+
* View Background (internal):
|
|
20
|
+
* - Special role: Defines container dimensions
|
|
21
|
+
* - Automatically managed by View component
|
|
22
|
+
* - Marked with __isBackground flag
|
|
23
|
+
* - Always excluded from layout calculations
|
|
24
|
+
* Graphics Component (user-facing):
|
|
25
|
+
* - Custom shapes for any purpose
|
|
26
|
+
* - User controls drawing via onDraw callback
|
|
27
|
+
* - Can be headless OR layout-aware (explicit)
|
|
28
|
+
* - Independent GameObject, not tied to View
|
|
29
|
+
*
|
|
30
|
+
* 3. Layout Size Provider: EXPLICIT DIMENSIONS REQUIRED ✅
|
|
31
|
+
* Decision: Option A - Require explicit width/height props for layout participation
|
|
32
|
+
* Reasoning:
|
|
33
|
+
* - Graphics have no inherent dimensions until drawn
|
|
34
|
+
* - Calculating bounds dynamically is expensive (getBounds() forces geometry calc)
|
|
35
|
+
* - Bounds change with every draw call (unstable for layout)
|
|
36
|
+
* - Explicit dimensions = predictable layout behavior
|
|
37
|
+
* Implementation:
|
|
38
|
+
* - If headless=false: Require width/height props (throw error if missing)
|
|
39
|
+
* - __getLayoutSize = () => ({ width: props.width!, height: props.height! })
|
|
40
|
+
*
|
|
41
|
+
* 4. Drawing API: IMPERATIVE CALLBACK ✅
|
|
42
|
+
* Decision: Option A - onDraw callback (imperative)
|
|
43
|
+
* Reasoning:
|
|
44
|
+
* - Simplest API, full Phaser Graphics power
|
|
45
|
+
* - No abstraction overhead
|
|
46
|
+
* - Familiar to Phaser developers
|
|
47
|
+
* - Flexible for complex shapes
|
|
48
|
+
* Interface:
|
|
49
|
+
* onDraw?: (graphics: Phaser.GameObjects.Graphics, props: GraphicsBaseProps) => void
|
|
50
|
+
* Example:
|
|
51
|
+
* <Graphics onDraw={(g) => {
|
|
52
|
+
* g.fillStyle(0xff0000, 1)
|
|
53
|
+
* g.fillCircle(50, 50, 50)
|
|
54
|
+
* }} />
|
|
55
|
+
* Future: Consider declarative shape components if demand is high
|
|
56
|
+
*
|
|
57
|
+
* 5. Redraw Strategy: DEPENDENCY-BASED ✅
|
|
58
|
+
* Decision: Redraw when dependencies array changes (React useEffect style)
|
|
59
|
+
* Behavior:
|
|
60
|
+
* - autoClear=true (default): Clear graphics before each onDraw call
|
|
61
|
+
* - dependencies=[...]: Only redraw when dependencies change (shallow compare)
|
|
62
|
+
* - No dependencies: Redraw on every patch (expensive!)
|
|
63
|
+
* Implementation:
|
|
64
|
+
* - Store previous dependencies on graphics object
|
|
65
|
+
* - Compare with current dependencies in patcher
|
|
66
|
+
* - Call onDraw only if changed
|
|
67
|
+
*
|
|
68
|
+
* 6. Performance Optimization: GENERATETEXTURE PATH 🆕
|
|
69
|
+
* Strategy for static graphics:
|
|
70
|
+
* - Static graphics (no redraw) → Consider generateTexture() optimization
|
|
71
|
+
* - Converts geometry to texture (faster rendering, loses vector quality)
|
|
72
|
+
* - Trade-off: Memory (texture) vs. CPU (redraw)
|
|
73
|
+
* Props:
|
|
74
|
+
* - static?: boolean (if true, generate texture after first draw)
|
|
75
|
+
* - textureKey?: string (cache key for generated texture)
|
|
76
|
+
* Recommendation: Advanced feature, implement later if needed
|
|
77
|
+
*
|
|
78
|
+
* 7. Common Use Cases & Alternatives: DOCUMENTED ✅
|
|
79
|
+
* Use Graphics For:
|
|
80
|
+
* - ✅ Custom complex shapes (polygons, stars, bezier curves)
|
|
81
|
+
* - ✅ Dynamic visualizations (graphs, charts)
|
|
82
|
+
* - ✅ Progress bars with custom shapes
|
|
83
|
+
* - ✅ Debug overlays (hitboxes, grids)
|
|
84
|
+
* Use Alternatives For:
|
|
85
|
+
* - ❌ Simple rectangles → Use View with backgroundColor
|
|
86
|
+
* - ❌ Borders → Use View with borderColor/borderWidth
|
|
87
|
+
* - ❌ Static shapes → Consider Image with pre-rendered texture
|
|
88
|
+
* - ❌ Repeated patterns → Use TileSprite
|
|
89
|
+
*
|
|
90
|
+
* 8. Clear Behavior: CONFIGURABLE ✅
|
|
91
|
+
* Decision: autoClear=true by default
|
|
92
|
+
* Reasoning:
|
|
93
|
+
* - Most use cases: Single shape per Graphics object
|
|
94
|
+
* - Prevents accumulation of draw calls
|
|
95
|
+
* - Override with autoClear=false for additive drawing
|
|
96
|
+
* Edge Case: Multiple draw calls in onDraw → All executed, then cleared on next redraw
|
|
97
|
+
*
|
|
98
|
+
* Implementation Status:
|
|
99
|
+
* ======================
|
|
100
|
+
* [✅] Create graphics with scene.add.graphics()
|
|
101
|
+
* [✅] Apply transform props via applyTransformProps
|
|
102
|
+
* [✅] Setup onDraw callback invocation
|
|
103
|
+
* [✅] Implement dependency-based redraw logic
|
|
104
|
+
* [✅] Handle autoClear flag
|
|
105
|
+
* [✅] Setup layout size provider (explicit width/height)
|
|
106
|
+
* [✅] Validate width/height if headless=false
|
|
107
|
+
* [✅] Example component with interactive demos
|
|
108
|
+
* [❌] generateTexture optimization (future enhancement)
|
|
109
|
+
*/
|
|
110
|
+
import type * as Phaser from 'phaser';
|
|
5
111
|
/**
|
|
6
112
|
* Base props for Graphics component
|
|
7
113
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphics.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/graphics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyGG;AACH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"graphics.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/graphics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyGG;AACH,OAAO,KAAK,KAAK,MAAM,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAChF,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AASxD;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,cAAc,EAAE,WAAW,EAAE,WAAW;IACjF;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAA;IAElF;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,EAAE,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,aACf,SAAQ,iBAAiB,EACvB,qBAAqB,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC;CAAG;AAEzD;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,UAAU,CAqBnD,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,UAAU,CAYnD,CAAA"}
|
|
@@ -1,7 +1,120 @@
|
|
|
1
|
-
import { default as Phaser } from 'phaser';
|
|
2
1
|
import { LayoutProps, PhaserProps, TransformProps } from '../../core-props';
|
|
3
2
|
import { HostCreator, HostPatcher } from '../../host';
|
|
4
3
|
import { PropsDefaultExtension } from '../../types';
|
|
4
|
+
/**
|
|
5
|
+
* Image component - Phaser Image GameObject (static texture)
|
|
6
|
+
* Status: IMPLEMENTED ✅
|
|
7
|
+
*
|
|
8
|
+
* Design Overview:
|
|
9
|
+
* ================
|
|
10
|
+
*
|
|
11
|
+
* 1. Component Role: TEXTURE RENDERING
|
|
12
|
+
* Purpose: Display static textures in UI layouts (icons, avatars, illustrations)
|
|
13
|
+
* Phaser Type: Phaser.GameObjects.Image (texture-based rendering)
|
|
14
|
+
* Characteristics:
|
|
15
|
+
* - Layout-aware by default (participates in parent layout)
|
|
16
|
+
* - Auto-sizing based on texture dimensions (like HTML <img>)
|
|
17
|
+
* - Supports Phaser texture system (atlases, frames)
|
|
18
|
+
*
|
|
19
|
+
* 2. Headless Default: FALSE ✅
|
|
20
|
+
* Decision: Image participates in layout by default
|
|
21
|
+
* Reasoning:
|
|
22
|
+
* - Images are UI elements (icons, avatars, illustrations)
|
|
23
|
+
* - Should affect parent container dimensions
|
|
24
|
+
* - Similar to Text component behavior
|
|
25
|
+
* Use Cases:
|
|
26
|
+
* - ✅ Layout-aware (default): Icons, avatars, logos, UI illustrations
|
|
27
|
+
* - ❌ Headless (optional): Decorative backgrounds, overlays, parallax layers
|
|
28
|
+
* Usage:
|
|
29
|
+
* <Image texture="icon" /> // Layout-aware
|
|
30
|
+
* <Image texture="bg" headless={true} /> // Decorative (no layout impact)
|
|
31
|
+
*
|
|
32
|
+
* 3. Layout Size Provider: DISPLAY DIMENSIONS ✅
|
|
33
|
+
* Implementation: Uses image.displayWidth and image.displayHeight
|
|
34
|
+
* Behavior:
|
|
35
|
+
* - Returns scaled display dimensions
|
|
36
|
+
* - Rotation is IGNORED for layout-aware images (headless=false)
|
|
37
|
+
* - Rotation only works with headless=true (no layout impact)
|
|
38
|
+
* Reasoning:
|
|
39
|
+
* - Flow layout is incompatible with rotation (causes positioning issues)
|
|
40
|
+
* - Rotated images would overlap siblings in flow layout
|
|
41
|
+
* - Matches Text component behavior
|
|
42
|
+
* Example:
|
|
43
|
+
* <Image texture="icon" /> // ✅ Layout size: 64x64
|
|
44
|
+
* <Image texture="icon" rotation={Math.PI/4} /> // ⚠️ Rotation IGNORED, size: 64x64
|
|
45
|
+
* <Image texture="icon" rotation={Math.PI/4} headless={true} /> // ✅ Rotated, no layout
|
|
46
|
+
* Recommendation: Use rotation only with headless=true or absolute positioning
|
|
47
|
+
*
|
|
48
|
+
* 4. Sizing Strategy: HYBRID APPROACH ✅
|
|
49
|
+
* Auto-Size (default):
|
|
50
|
+
* - No displayWidth/displayHeight → Use texture dimensions
|
|
51
|
+
* - Like HTML <img> natural size
|
|
52
|
+
* Explicit Size:
|
|
53
|
+
* - displayWidth + displayHeight → Scale to fit
|
|
54
|
+
* - fit prop controls aspect ratio handling
|
|
55
|
+
* Example:
|
|
56
|
+
* <Image texture="icon" /> // Auto-size
|
|
57
|
+
* <Image texture="icon" displayWidth={64} displayHeight={64} fit="contain" />
|
|
58
|
+
*
|
|
59
|
+
* 5. Fit Modes: CSS-LIKE BEHAVIOR ✅
|
|
60
|
+
* Decision: Implement CSS object-fit equivalent
|
|
61
|
+
* Modes:
|
|
62
|
+
* - 'fill' (default): Stretch to fill bounds (may distort aspect ratio)
|
|
63
|
+
* - 'contain': Scale to fit within bounds, preserve aspect ratio (letterbox)
|
|
64
|
+
* - 'cover': Scale to cover bounds, preserve aspect ratio (crop)
|
|
65
|
+
* Implementation: Calculate scale in applier based on fit mode
|
|
66
|
+
*
|
|
67
|
+
* 6. Origin Behavior: HEADLESS-AWARE ✅
|
|
68
|
+
* Current: Like Text component
|
|
69
|
+
* - Layout-aware (headless=false): Origin (0, 0) - top-left, UI-friendly
|
|
70
|
+
* - Headless (headless=true): Origin (0.5, 0.5) - centered, game object semantics
|
|
71
|
+
* Reasoning:
|
|
72
|
+
* - UI elements align naturally with top-left origin
|
|
73
|
+
* - Game objects (headless) work better centered
|
|
74
|
+
* - Consistent with Text component behavior
|
|
75
|
+
*
|
|
76
|
+
* 7. Rotation Behavior: LIKE TEXT ✅
|
|
77
|
+
* Decision: Rotation only supported with headless=true
|
|
78
|
+
* Reasoning:
|
|
79
|
+
* - Flow layout is incompatible with rotation
|
|
80
|
+
* - Matches Text component constraints
|
|
81
|
+
* - Props normalized: rotation removed if headless=false
|
|
82
|
+
*
|
|
83
|
+
* 8. Common Patterns:
|
|
84
|
+
* Icon:
|
|
85
|
+
* <View direction="row" gap={10}>
|
|
86
|
+
* <Image texture="icon-user" />
|
|
87
|
+
* <Text text="Username" />
|
|
88
|
+
* </View>
|
|
89
|
+
* Avatar:
|
|
90
|
+
* <Image texture="avatar" displayWidth={64} displayHeight={64} fit="cover" />
|
|
91
|
+
* Background (headless):
|
|
92
|
+
* <Image texture="bg" headless={true} alpha={0.5} />
|
|
93
|
+
*
|
|
94
|
+
* 9. Performance Considerations:
|
|
95
|
+
* - Texture atlases recommended (reduce texture switches)
|
|
96
|
+
* - Static images are efficient (single draw call)
|
|
97
|
+
* - Texture changes trigger re-render
|
|
98
|
+
* - Scaling via displayWidth/displayHeight is GPU-accelerated
|
|
99
|
+
*
|
|
100
|
+
* 10. Known Limitations:
|
|
101
|
+
* - Rotation only supported with headless=true (ignored for layout-aware)
|
|
102
|
+
* - Missing textures show Phaser default (white square)
|
|
103
|
+
* - No built-in loading states
|
|
104
|
+
* - Texture must be preloaded before use
|
|
105
|
+
*
|
|
106
|
+
* Implementation Status:
|
|
107
|
+
* ======================
|
|
108
|
+
* [✅] Phaser Image creation with texture/frame support
|
|
109
|
+
* [✅] Transform props (position, scale, alpha)
|
|
110
|
+
* [✅] Layout system integration (__layoutProps, __getLayoutSize)
|
|
111
|
+
* [✅] Origin handling (headless-aware: 0,0 vs 0.5,0.5)
|
|
112
|
+
* [✅] Display size with fit modes (contain/cover/fill)
|
|
113
|
+
* [✅] Tint support
|
|
114
|
+
* [✅] Texture and frame patching
|
|
115
|
+
* [⚠️] Rotation - Only with headless=true (ignored for layout-aware)
|
|
116
|
+
*/
|
|
117
|
+
import type * as Phaser from 'phaser';
|
|
5
118
|
/**
|
|
6
119
|
* Base props for Image component
|
|
7
120
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/image.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgHG;AACH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/image.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgHG;AACH,OAAO,KAAK,KAAK,MAAM,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAChF,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AASxD;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,cAAc,EAAE,WAAW,EAAE,WAAW;IAC9E,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAA;IAEf,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAEvB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAEzB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAEjC,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAElC;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAA;IAElC,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,mBACf,SAAQ,cAAc,EACpB,qBAAqB,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC;CAAG;AAEtD;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,OAAO,CA4F7C,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,OAAO,CA+C7C,CAAA"}
|
|
@@ -1,7 +1,167 @@
|
|
|
1
|
-
import { default as Phaser } from 'phaser';
|
|
2
1
|
import { LayoutProps, PhaserProps, TransformProps } from '../../core-props';
|
|
3
2
|
import { HostCreator, HostPatcher } from '../../host';
|
|
4
3
|
import { PropsDefaultExtension } from '../../types';
|
|
4
|
+
/**
|
|
5
|
+
* NineSlice component - Phaser NineSlice GameObject for scalable UI panels
|
|
6
|
+
* Status: IMPLEMENTED ✅
|
|
7
|
+
*
|
|
8
|
+
* Design Overview:
|
|
9
|
+
* ================
|
|
10
|
+
*
|
|
11
|
+
* 1. Component Role: SCALABLE UI PANELS
|
|
12
|
+
* Purpose: Create resizable UI elements that preserve border/corner integrity
|
|
13
|
+
* Phaser Type: Phaser.GameObjects.NineSlice (9-slice scaling)
|
|
14
|
+
* Use Cases:
|
|
15
|
+
* - Buttons with fixed corner radius
|
|
16
|
+
* - Dialog boxes with preserved borders
|
|
17
|
+
* - Progress bars with capped ends
|
|
18
|
+
* - Panels that scale without distorting decorative edges
|
|
19
|
+
*
|
|
20
|
+
* 2. Nine-Slice Scaling Concept:
|
|
21
|
+
* Texture divided into 9 regions:
|
|
22
|
+
* ┌─────┬─────────┬─────┐
|
|
23
|
+
* │ TL │ Top │ TR │ (corners + edges)
|
|
24
|
+
* ├─────┼─────────┼─────┤
|
|
25
|
+
* │Left │ Center │Right│ (center scales, edges stretch)
|
|
26
|
+
* ├─────┼─────────┼─────┤
|
|
27
|
+
* │ BL │ Bottom │ BR │ (corners stay fixed)
|
|
28
|
+
* └─────┴─────────┴─────┘
|
|
29
|
+
* Behavior:
|
|
30
|
+
* - Corners: Never scale (preserve pixel-perfect)
|
|
31
|
+
* - Edges: Stretch along one axis (top/bottom: horizontal, left/right: vertical)
|
|
32
|
+
* - Center: Scales in both directions
|
|
33
|
+
* Benefit: UI elements scale to any size without visual distortion
|
|
34
|
+
*
|
|
35
|
+
* 3. Three-Slice Mode (Optional):
|
|
36
|
+
* Feature: Omit topHeight/bottomHeight for horizontal-only slicing
|
|
37
|
+
* Use Case: Horizontal buttons, progress bars
|
|
38
|
+
* Layout:
|
|
39
|
+
* ┌─────┬─────────────────┬─────┐
|
|
40
|
+
* │Left │ Center │Right│
|
|
41
|
+
* └─────┴─────────────────┴─────┘
|
|
42
|
+
* Props: Only leftWidth + rightWidth required
|
|
43
|
+
*
|
|
44
|
+
* 4. Headless Default: FALSE ✅
|
|
45
|
+
* Decision: NineSlice participates in layout by default
|
|
46
|
+
* Reasoning:
|
|
47
|
+
* - NineSlice is a UI element (buttons, panels, containers)
|
|
48
|
+
* - Should affect parent container dimensions
|
|
49
|
+
* - Similar to View component (container semantics)
|
|
50
|
+
* Use Cases:
|
|
51
|
+
* - ✅ Layout-aware (default): Buttons, panels, dialogs, cards
|
|
52
|
+
* - ❌ Headless (optional): Background overlays, decorative frames
|
|
53
|
+
* Usage:
|
|
54
|
+
* <NineSlice texture="panel" leftWidth={16} rightWidth={16} width={200} height={100} />
|
|
55
|
+
* <NineSlice texture="frame" headless={true} /> // Decorative
|
|
56
|
+
*
|
|
57
|
+
* 5. Layout Size Provider:
|
|
58
|
+
* Implementation: Uses explicit width/height (required props)
|
|
59
|
+
* Reasoning:
|
|
60
|
+
* - NineSlice requires explicit dimensions (Phaser constructor param)
|
|
61
|
+
* - No auto-sizing (unlike Text)
|
|
62
|
+
* - Dimensions always known and stable
|
|
63
|
+
* __getLayoutSize:
|
|
64
|
+
* return { width: nineSlice.width, height: nineSlice.height }
|
|
65
|
+
* Note: getBounds() not needed (no rotation typically applied)
|
|
66
|
+
*
|
|
67
|
+
* 6. Slice Configuration:
|
|
68
|
+
* Required Props:
|
|
69
|
+
* - texture: string (texture key)
|
|
70
|
+
* - leftWidth: number (pixels)
|
|
71
|
+
* - rightWidth: number (pixels)
|
|
72
|
+
* - width: number (total width)
|
|
73
|
+
* - height: number (total height)
|
|
74
|
+
* Optional Props:
|
|
75
|
+
* - topHeight: number (9-slice mode, default: 0 for 3-slice)
|
|
76
|
+
* - bottomHeight: number (9-slice mode, default: 0 for 3-slice)
|
|
77
|
+
* - frame: string | number (texture atlas frame)
|
|
78
|
+
* Validation:
|
|
79
|
+
* - Width must be >= leftWidth + rightWidth
|
|
80
|
+
* - Height must be >= topHeight + bottomHeight
|
|
81
|
+
* - Slice widths/heights define source texture regions
|
|
82
|
+
*
|
|
83
|
+
* 7. Inner Bounds Feature:
|
|
84
|
+
* Purpose: Calculate content area excluding slices
|
|
85
|
+
* Use Case: Position children inside panel borders
|
|
86
|
+
* Calculation:
|
|
87
|
+
* innerBounds = {
|
|
88
|
+
* x: leftWidth,
|
|
89
|
+
* y: topHeight,
|
|
90
|
+
* width: totalWidth - leftWidth - rightWidth,
|
|
91
|
+
* height: totalHeight - topHeight - bottomHeight
|
|
92
|
+
* }
|
|
93
|
+
* Access:
|
|
94
|
+
* const ref = useRef<NineSliceRef>(null)
|
|
95
|
+
* <NineSlice ref={ref} ... />
|
|
96
|
+
* console.log(ref.current?.innerBounds) // { x, y, width, height }
|
|
97
|
+
* Pattern: Useful for padding-aware content positioning
|
|
98
|
+
*
|
|
99
|
+
* 8. Ref Extension:
|
|
100
|
+
* Feature: NineSliceRef provides slice metadata
|
|
101
|
+
* Properties:
|
|
102
|
+
* - node: Phaser.GameObjects.NineSlice (the GameObject)
|
|
103
|
+
* - leftWidth, rightWidth, topHeight, bottomHeight: Slice dimensions
|
|
104
|
+
* - innerBounds: Content area calculation
|
|
105
|
+
* Usage:
|
|
106
|
+
* const panelRef = useRef<NineSliceRef>(null)
|
|
107
|
+
* // Access slice info for child positioning
|
|
108
|
+
* const { innerBounds } = panelRef.current
|
|
109
|
+
*
|
|
110
|
+
* 9. Common Patterns:
|
|
111
|
+
* Button:
|
|
112
|
+
* <NineSlice
|
|
113
|
+
* texture="button"
|
|
114
|
+
* leftWidth={16} rightWidth={16}
|
|
115
|
+
* topHeight={16} bottomHeight={16}
|
|
116
|
+
* width={200} height={60}
|
|
117
|
+
* >
|
|
118
|
+
* <Text text="Click Me" />
|
|
119
|
+
* </NineSlice>
|
|
120
|
+
* Dialog Box:
|
|
121
|
+
* <NineSlice
|
|
122
|
+
* texture="panel"
|
|
123
|
+
* leftWidth={32} rightWidth={32}
|
|
124
|
+
* topHeight={32} bottomHeight={32}
|
|
125
|
+
* width={400} height={300}
|
|
126
|
+
* >
|
|
127
|
+
* <View padding={32}> {/* Padding matches slice sizes * }
|
|
128
|
+
* <Text text="Dialog Content" />
|
|
129
|
+
* </View>
|
|
130
|
+
* </NineSlice>
|
|
131
|
+
* Progress Bar (3-slice):
|
|
132
|
+
* <NineSlice
|
|
133
|
+
* texture="progressbar"
|
|
134
|
+
* leftWidth={8} rightWidth={8}
|
|
135
|
+
* width={progress * 200} height={20}
|
|
136
|
+
* />
|
|
137
|
+
*
|
|
138
|
+
* 10. Performance Considerations:
|
|
139
|
+
* - Efficient rendering (single draw call per NineSlice)
|
|
140
|
+
* - Texture atlases recommended (reduce texture switches)
|
|
141
|
+
* - Scaling performance: No geometry regeneration needed
|
|
142
|
+
* - Slice configuration: Calculated once on creation
|
|
143
|
+
* - Dynamic resizing: Efficiently handled by Phaser
|
|
144
|
+
*
|
|
145
|
+
* 11. Known Limitations:
|
|
146
|
+
* - Requires pre-designed 9-slice texture
|
|
147
|
+
* - Slice dimensions must match source texture layout exactly
|
|
148
|
+
* - Rotation not recommended (distorts slice alignment)
|
|
149
|
+
* - Can't animate slice dimensions (only width/height)
|
|
150
|
+
* - No rounded corner support (must be in texture)
|
|
151
|
+
*
|
|
152
|
+
* Implementation Status:
|
|
153
|
+
* ======================
|
|
154
|
+
* [✅] Phaser NineSlice creation with slice configuration
|
|
155
|
+
* [✅] Transform props (position, scale, alpha, depth)
|
|
156
|
+
* [✅] Layout system integration (__layoutProps, __getLayoutSize)
|
|
157
|
+
* [✅] Width/height as layout props (explicit sizing)
|
|
158
|
+
* [✅] Three-slice mode support (optional topHeight/bottomHeight)
|
|
159
|
+
* [✅] NineSliceRef with innerBounds calculation
|
|
160
|
+
* [✅] Slice dimension validation
|
|
161
|
+
* [✅] Theme system integration
|
|
162
|
+
* [✅] Dynamic resizing support (width/height patching)
|
|
163
|
+
*/
|
|
164
|
+
import type * as Phaser from 'phaser';
|
|
5
165
|
/**
|
|
6
166
|
* Inner bounds of a NineSlice - the content area excluding slices
|
|
7
167
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nineslice.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/nineslice.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+JG;AACH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"nineslice.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/nineslice.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+JG;AACH,OAAO,KAAK,KAAK,MAAM,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAChF,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AASxD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,CAAC,EAAE,MAAM,CAAA;IACT;;OAEG;IACH,CAAC,EAAE,MAAM,CAAA;IACT;;OAEG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,SAAS,GAAG,IAAI,CAAA;IACzC;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,WAAW,EAAE,oBAAoB,CAAA;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IAEf;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAEzB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAEvB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAA;IAElB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,kBACf,SAAQ,cAAc,EACpB,WAAW,EACX,WAAW,EACX,sBAAsB;CAAG;AAE7B;;;GAGG;AACH,MAAM,WAAW,uBACf,SAAQ,kBAAkB,EACxB,qBAAqB,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC;CAAG;AAE1D;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,WAAW,CAmCrD,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,WAAW,CAYrD,CAAA"}
|
|
@@ -1,7 +1,96 @@
|
|
|
1
|
-
import { default as Phaser } from 'phaser';
|
|
2
1
|
import { LayoutProps, PhaserProps, TransformProps } from '../../core-props';
|
|
3
2
|
import { HostCreator, HostPatcher } from '../../host';
|
|
4
3
|
import { PropsDefaultExtension } from '../../types';
|
|
4
|
+
/**
|
|
5
|
+
* Sprite component - Phaser Sprite GameObject (animated texture)
|
|
6
|
+
* Status: IMPLEMENTED ✅
|
|
7
|
+
*
|
|
8
|
+
* Design Overview:
|
|
9
|
+
* ================
|
|
10
|
+
*
|
|
11
|
+
* 1. Component Role: ANIMATED GAME OBJECTS
|
|
12
|
+
* Purpose: Display animated sprites in game scenes (characters, effects, particles)
|
|
13
|
+
* Phaser Type: Phaser.GameObjects.Sprite (animation-capable texture rendering)
|
|
14
|
+
* Characteristics:
|
|
15
|
+
* - Always headless (does not affect parent layout)
|
|
16
|
+
* - Supports Phaser Animation system
|
|
17
|
+
* - Free positioning with rotation/scale
|
|
18
|
+
*
|
|
19
|
+
* 2. Headless Behavior: MANDATORY ✅
|
|
20
|
+
* Decision: Sprites are ALWAYS headless (not configurable)
|
|
21
|
+
* Reasoning:
|
|
22
|
+
* - Sprites are game objects, not UI elements
|
|
23
|
+
* - Should NOT affect parent layout dimensions
|
|
24
|
+
* - Free positioning with full transform support (rotation, scale)
|
|
25
|
+
* Layout Impact: Returns minimal size (0.01x0.01) - participates in alignment only
|
|
26
|
+
* Use Cases:
|
|
27
|
+
* - ✅ Game characters, particles, effects, free-floating objects
|
|
28
|
+
* - ✅ Animated decorations, background elements
|
|
29
|
+
* - ❌ NOT for layout-based UIs (use Image component instead)
|
|
30
|
+
*
|
|
31
|
+
* 3. Layout Size Provider: MINIMAL SIZE ✅
|
|
32
|
+
* Implementation: Always returns { width: 0.01, height: 0.01 }
|
|
33
|
+
* Reasoning:
|
|
34
|
+
* - Sprites don't affect layout spacing
|
|
35
|
+
* - Minimal size allows alignment but no spacing impact
|
|
36
|
+
* - Simpler than getBounds() with same result
|
|
37
|
+
*
|
|
38
|
+
* 4. Animation System: PHASER ANIMATIONS ✅
|
|
39
|
+
* Features:
|
|
40
|
+
* - animationKey: Play pre-registered animation
|
|
41
|
+
* - loop: Repeat animation indefinitely
|
|
42
|
+
* - repeatDelay: Delay between animation repeats (ms)
|
|
43
|
+
* Callbacks:
|
|
44
|
+
* - onAnimationStart: Triggered when animation begins
|
|
45
|
+
* - onAnimationComplete: Triggered when animation ends
|
|
46
|
+
* - onAnimationRepeat: Triggered on each repeat
|
|
47
|
+
* - onAnimationUpdate: Triggered on each frame update
|
|
48
|
+
* Note: Animations must be pre-registered in Phaser AnimationManager
|
|
49
|
+
*
|
|
50
|
+
* 5. Texture & Sizing: LIKE IMAGE ✅
|
|
51
|
+
* Props:
|
|
52
|
+
* - texture: Texture key (required)
|
|
53
|
+
* - frame: Frame from atlas/spritesheet
|
|
54
|
+
* - tint: Color tint (0xRRGGBB)
|
|
55
|
+
* - displayWidth/displayHeight: Scale sprite to fit
|
|
56
|
+
* - fit: 'fill' | 'contain' | 'cover' (aspect ratio handling)
|
|
57
|
+
* Error Handling: Missing texture → Phaser default (white square)
|
|
58
|
+
*
|
|
59
|
+
* 6. Origin Behavior: CENTERED (0.5, 0.5) ✅
|
|
60
|
+
* Decision: Default origin (0.5, 0.5) - centered
|
|
61
|
+
* Reasoning:
|
|
62
|
+
* - Phaser sprite default
|
|
63
|
+
* - Natural for rotation/scale pivot
|
|
64
|
+
* - Game object semantics
|
|
65
|
+
* Override: Use originX/originY props for custom origin
|
|
66
|
+
*
|
|
67
|
+
* 7. Performance: SPRITE BATCHING ✅
|
|
68
|
+
* Strategy:
|
|
69
|
+
* - Leverages Phaser's sprite batching (WebGL)
|
|
70
|
+
* - Props that preserve batching: tint, alpha, scale, position
|
|
71
|
+
* - Props that break batching: custom shaders, blend modes (use sparingly)
|
|
72
|
+
* - Texture atlases strongly recommended for multiple sprites
|
|
73
|
+
*
|
|
74
|
+
* 8. Common Patterns:
|
|
75
|
+
* Character:
|
|
76
|
+
* <Sprite texture="player" animationKey="walk" loop={true} />
|
|
77
|
+
* Particle Effect:
|
|
78
|
+
* <Sprite texture="explosion" animationKey="explode" onAnimationComplete={destroy} />
|
|
79
|
+
* Scaled Sprite:
|
|
80
|
+
* <Sprite texture="coin" displayWidth={32} displayHeight={32} fit="contain" />
|
|
81
|
+
*
|
|
82
|
+
* Implementation Status:
|
|
83
|
+
* ======================
|
|
84
|
+
* [✅] Phaser Sprite creation with texture/frame support
|
|
85
|
+
* [✅] Transform props (position, rotation, scale, alpha)
|
|
86
|
+
* [✅] Layout system integration (always headless)
|
|
87
|
+
* [✅] Origin handling (0.5, 0.5 default)
|
|
88
|
+
* [✅] Display size with fit modes (contain/cover/fill)
|
|
89
|
+
* [✅] Tint support
|
|
90
|
+
* [✅] Animation system (play, loop, callbacks)
|
|
91
|
+
* [✅] Texture and frame patching
|
|
92
|
+
*/
|
|
93
|
+
import type * as Phaser from 'phaser';
|
|
5
94
|
/**
|
|
6
95
|
* Base props for Sprite component
|
|
7
96
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sprite.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/sprite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwFG;AACH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"sprite.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/sprite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwFG;AACH,OAAO,KAAK,KAAK,MAAM,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAChF,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AASxD;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,cAAc,EAAE,WAAW,EAAE,WAAW;IAC/E,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAA;IAEf,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAEvB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAA;IAEb,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB,4CAA4C;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAA;IAElC,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB,sCAAsC;IACtC,IAAI,CAAC,EAAE,OAAO,CAAA;IAEd,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,qCAAqC;IACrC,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAExC,wCAAwC;IACxC,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAE3C,sCAAsC;IACtC,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAEzC,8CAA8C;IAC9C,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,cAAc,KAAK,IAAI,CAAA;IAElF,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,WACf,SAAQ,eAAe,EACrB,qBAAqB,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC;CAAG;AAEvD;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,QAAQ,CAiH/C,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,QAAQ,CAY/C,CAAA"}
|
|
@@ -1,7 +1,136 @@
|
|
|
1
|
-
import { default as Phaser } from 'phaser';
|
|
2
1
|
import { EdgeInsets, LayoutProps, PhaserProps, TextSpecificProps, TransformProps } from '../../core-props';
|
|
3
2
|
import { HostCreator, HostPatcher } from '../../host';
|
|
4
3
|
import { PropsDefaultExtension } from '../../types';
|
|
4
|
+
/**
|
|
5
|
+
* Text component - Phaser Text GameObject for rendering text
|
|
6
|
+
* Status: IMPLEMENTED ✅
|
|
7
|
+
*
|
|
8
|
+
* Design Overview:
|
|
9
|
+
* ================
|
|
10
|
+
*
|
|
11
|
+
* 1. Component Role: TEXT RENDERING
|
|
12
|
+
* Purpose: Display styled text in UI layouts
|
|
13
|
+
* Phaser Type: Phaser.GameObjects.Text (bitmap-based text rendering)
|
|
14
|
+
* Characteristics:
|
|
15
|
+
* - Layout-aware by default (participates in parent layout)
|
|
16
|
+
* - Auto-sizing based on text content + font metrics
|
|
17
|
+
* - Supports Phaser text styling (color, font, alignment, etc.)
|
|
18
|
+
*
|
|
19
|
+
* 2. Headless Default: FALSE ✅
|
|
20
|
+
* Decision: Text participates in layout by default
|
|
21
|
+
* Reasoning:
|
|
22
|
+
* - Text is a UI element (labels, paragraphs, buttons)
|
|
23
|
+
* - Should affect parent container dimensions
|
|
24
|
+
* - Similar to HTML text nodes
|
|
25
|
+
* Use Cases:
|
|
26
|
+
* - ✅ Layout-aware (default): Labels, buttons, paragraphs, UI text
|
|
27
|
+
* - ❌ Headless (optional): Floating damage numbers, debug text, tooltips
|
|
28
|
+
* Usage:
|
|
29
|
+
* <Text text="Label" /> // Layout-aware
|
|
30
|
+
* <Text text="+100" headless={true} /> // Floating (no layout impact)
|
|
31
|
+
*
|
|
32
|
+
* 3. Layout Size Provider: UN-ROTATED DIMENSIONS ✅
|
|
33
|
+
* Implementation: Uses text.width and text.height (un-rotated)
|
|
34
|
+
* Behavior:
|
|
35
|
+
* - Returns un-rotated text dimensions
|
|
36
|
+
* - Rotation is IGNORED for layout-aware text (headless=false)
|
|
37
|
+
* - Rotation only works with headless=true (no layout impact)
|
|
38
|
+
* Reasoning:
|
|
39
|
+
* - Flow layout is incompatible with rotation (causes positioning issues)
|
|
40
|
+
* - Rotated text would overlap siblings in flow layout
|
|
41
|
+
* - getBounds() position compensation is complex and error-prone
|
|
42
|
+
* Example:
|
|
43
|
+
* <Text text="Hello" /> // ✅ Layout size: 100x20
|
|
44
|
+
* <Text text="World" rotation={Math.PI/4} /> // ⚠️ Rotation IGNORED, size: 100x20
|
|
45
|
+
* <Text text="World" rotation={Math.PI/4} headless={true} /> // ✅ Rotated, no layout
|
|
46
|
+
* Recommendation: Use rotation only with headless=true or absolute positioning
|
|
47
|
+
*
|
|
48
|
+
* 4. Text Content & Styling:
|
|
49
|
+
* Props:
|
|
50
|
+
* - text: string (required, the text to display)
|
|
51
|
+
* - style: Phaser.Types.GameObjects.Text.TextStyle (font, color, etc.)
|
|
52
|
+
* - fontStyle, align, maxWidth: Convenience props (legacy)
|
|
53
|
+
* Styling Priority:
|
|
54
|
+
* 1. Inline style prop (highest)
|
|
55
|
+
* 2. Individual props (fontStyle, align)
|
|
56
|
+
* 3. Theme defaults (lowest)
|
|
57
|
+
* Example:
|
|
58
|
+
* <Text
|
|
59
|
+
* text="Hello"
|
|
60
|
+
* style={{ fontSize: '24px', color: '#ffffff', fontFamily: 'Arial' }}
|
|
61
|
+
* />
|
|
62
|
+
*
|
|
63
|
+
* 5. Margin Support:
|
|
64
|
+
* Feature: Text supports margin prop (unique among primitives)
|
|
65
|
+
* Reasoning:
|
|
66
|
+
* - Text often needs spacing from siblings (inline elements)
|
|
67
|
+
* - Margin affects layout calculations (added to text dimensions)
|
|
68
|
+
* - Similar to CSS inline element margin
|
|
69
|
+
* Usage:
|
|
70
|
+
* <Text text="Label" margin={{ left: 10, right: 10 }} />
|
|
71
|
+
* <Text text="Spaced" margin={8} /> // All sides
|
|
72
|
+
*
|
|
73
|
+
* 6. Layout Behavior:
|
|
74
|
+
* Sizing:
|
|
75
|
+
* - Auto-size: Text dimensions = rendered text bounds (default)
|
|
76
|
+
* - No explicit width/height props (text size determined by content)
|
|
77
|
+
* - maxWidth prop wraps text (Phaser feature)
|
|
78
|
+
* Positioning:
|
|
79
|
+
* - Positioned by parent layout engine (flexbox-style)
|
|
80
|
+
* - x/y props override layout position (absolute positioning)
|
|
81
|
+
*
|
|
82
|
+
* 7. Origin Behavior:
|
|
83
|
+
* Current: Phaser default origin (0, 0) - top-left
|
|
84
|
+
* Reasoning:
|
|
85
|
+
* - Text aligns naturally with layout flow
|
|
86
|
+
* - Top-left origin simplifies position calculations
|
|
87
|
+
* - Consistent with HTML text rendering
|
|
88
|
+
* Note: Origin affects rotation pivot (if rotation applied)
|
|
89
|
+
*
|
|
90
|
+
* 8. Common Patterns:
|
|
91
|
+
* Label:
|
|
92
|
+
* <View direction="row" gap={10}>
|
|
93
|
+
* <Text text="Name:" />
|
|
94
|
+
* <Text text={userName} />
|
|
95
|
+
* </View>
|
|
96
|
+
* Styled Text:
|
|
97
|
+
* <Text
|
|
98
|
+
* text="Title"
|
|
99
|
+
* style={{ fontSize: '32px', fontWeight: 'bold', color: '#ff0000' }}
|
|
100
|
+
* />
|
|
101
|
+
* Wrapped Text:
|
|
102
|
+
* <Text text={longParagraph} maxWidth={300} />
|
|
103
|
+
* Floating Damage:
|
|
104
|
+
* <Text text="-50 HP" headless={true} alpha={0.8} />
|
|
105
|
+
*
|
|
106
|
+
* 9. Performance Considerations:
|
|
107
|
+
* - Text rendering is relatively expensive (canvas-based)
|
|
108
|
+
* - Frequent text changes trigger re-render
|
|
109
|
+
* - Long text with maxWidth: word-wrap calculation cost
|
|
110
|
+
* - Consider BitmapText for better performance (future component)
|
|
111
|
+
* - Text batching: Multiple Text objects don't batch (separate draw calls)
|
|
112
|
+
*
|
|
113
|
+
* 10. Known Limitations:
|
|
114
|
+
* - Rotation only supported with headless=true (ignored for layout-aware text)
|
|
115
|
+
* → Flow layout is incompatible with rotation
|
|
116
|
+
* - No rich text support (HTML tags, colors within text)
|
|
117
|
+
* - Limited text effects (no shadows, outlines in base component)
|
|
118
|
+
* - WordWrap with maxWidth: Can't specify ellipsis truncation
|
|
119
|
+
* - Changing text frequently: Performance impact
|
|
120
|
+
*
|
|
121
|
+
* Implementation Status:
|
|
122
|
+
* ======================
|
|
123
|
+
* [✅] Phaser Text creation with style support
|
|
124
|
+
* [✅] Transform props (position, scale, alpha)
|
|
125
|
+
* [✅] Layout system integration (__layoutProps, __getLayoutSize)
|
|
126
|
+
* [✅] Margin support (unique feature)
|
|
127
|
+
* [✅] Text content and style patching
|
|
128
|
+
* [✅] Theme system integration
|
|
129
|
+
* [⚠️] Rotation - Only with headless=true (ignored for layout-aware text)
|
|
130
|
+
* [❌] Rich text support - Future feature
|
|
131
|
+
* [❌] Text effects (shadow, outline) - Future feature
|
|
132
|
+
*/
|
|
133
|
+
import type * as Phaser from 'phaser';
|
|
5
134
|
/**
|
|
6
135
|
* Base props for Text - composing shared prop groups
|
|
7
136
|
* Includes optional margin for layout engine use
|