hudini 0.17.2 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/card/card.d.ts +34 -9
- package/dist/components/card/card.d.ts.map +1 -1
- package/dist/components/card/card.js +118 -49
- package/dist/components/card/card.js.map +1 -1
- package/dist/components/card/card.spec.js +28 -1
- package/dist/components/card/card.spec.js.map +1 -1
- package/dist/components/circular-progress/circular-progress.d.ts +4 -4
- package/dist/components/circular-progress/circular-progress.d.ts.map +1 -1
- package/dist/components/circular-progress/circular-progress.js +9 -8
- package/dist/components/circular-progress/circular-progress.js.map +1 -1
- package/dist/components/circular-progress/circular-progress.spec.js +4 -4
- package/dist/components/circular-progress/circular-progress.spec.js.map +1 -1
- package/dist/components/container-interactive/container-interactive.d.ts +65 -0
- package/dist/components/container-interactive/container-interactive.d.ts.map +1 -0
- package/dist/components/container-interactive/container-interactive.js +99 -0
- package/dist/components/container-interactive/container-interactive.js.map +1 -0
- package/dist/components/container-interactive/index.d.ts +2 -0
- package/dist/components/container-interactive/index.d.ts.map +1 -0
- package/dist/components/container-interactive/index.js +2 -0
- package/dist/components/container-interactive/index.js.map +1 -0
- package/dist/components/flat-icon-button/flat-icon-button.d.ts +3 -0
- package/dist/components/flat-icon-button/flat-icon-button.d.ts.map +1 -1
- package/dist/components/flat-icon-button/flat-icon-button.js +111 -20
- package/dist/components/flat-icon-button/flat-icon-button.js.map +1 -1
- package/dist/components/flat-section-header/flat-section-header.d.ts +143 -0
- package/dist/components/flat-section-header/flat-section-header.d.ts.map +1 -0
- package/dist/components/flat-section-header/flat-section-header.js +275 -0
- package/dist/components/flat-section-header/flat-section-header.js.map +1 -0
- package/dist/components/flat-section-header/flat-section-header.spec.d.ts +2 -0
- package/dist/components/flat-section-header/flat-section-header.spec.d.ts.map +1 -0
- package/dist/components/flat-section-header/flat-section-header.spec.js +255 -0
- package/dist/components/flat-section-header/flat-section-header.spec.js.map +1 -0
- package/dist/components/flat-section-header/index.d.ts +2 -0
- package/dist/components/flat-section-header/index.d.ts.map +1 -0
- package/dist/components/flat-section-header/index.js +2 -0
- package/dist/components/flat-section-header/index.js.map +1 -0
- package/dist/components/flat-text-button/flat-text-button.d.ts +165 -0
- package/dist/components/flat-text-button/flat-text-button.d.ts.map +1 -0
- package/dist/components/flat-text-button/flat-text-button.js +325 -0
- package/dist/components/flat-text-button/flat-text-button.js.map +1 -0
- package/dist/components/flat-text-button/flat-text-button.spec.d.ts +2 -0
- package/dist/components/flat-text-button/flat-text-button.spec.d.ts.map +1 -0
- package/dist/components/flat-text-button/flat-text-button.spec.js +243 -0
- package/dist/components/flat-text-button/flat-text-button.spec.js.map +1 -0
- package/dist/components/flat-text-button/index.d.ts +2 -0
- package/dist/components/flat-text-button/index.d.ts.map +1 -0
- package/dist/components/flat-text-button/index.js +2 -0
- package/dist/components/flat-text-button/index.js.map +1 -0
- package/dist/components/icon-button/icon-button.d.ts +11 -3
- package/dist/components/icon-button/icon-button.d.ts.map +1 -1
- package/dist/components/icon-button/icon-button.js +126 -71
- package/dist/components/icon-button/icon-button.js.map +1 -1
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +4 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/panel/panel.d.ts +0 -1
- package/dist/components/panel/panel.d.ts.map +1 -1
- package/dist/components/panel/panel.js +7 -10
- package/dist/components/panel/panel.js.map +1 -1
- package/dist/components/section-header/section-header.d.ts +33 -39
- package/dist/components/section-header/section-header.d.ts.map +1 -1
- package/dist/components/section-header/section-header.js +124 -155
- package/dist/components/section-header/section-header.js.map +1 -1
- package/dist/components/section-header/section-header.spec.js +57 -17
- package/dist/components/section-header/section-header.spec.js.map +1 -1
- package/dist/components/text/index.d.ts +2 -0
- package/dist/components/text/index.d.ts.map +1 -0
- package/dist/components/text/index.js +2 -0
- package/dist/components/text/index.js.map +1 -0
- package/dist/components/text/text.d.ts +45 -0
- package/dist/components/text/text.d.ts.map +1 -0
- package/dist/components/text/text.js +35 -0
- package/dist/components/text/text.js.map +1 -0
- package/dist/components/text-button/text-button.d.ts +26 -23
- package/dist/components/text-button/text-button.d.ts.map +1 -1
- package/dist/components/text-button/text-button.js +114 -88
- package/dist/components/text-button/text-button.js.map +1 -1
- package/dist/components/text-button/text-button.spec.js +108 -9
- package/dist/components/text-button/text-button.spec.js.map +1 -1
- package/dist/hudini.js +4220 -467
- package/dist/hudini.min.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/loaders/index.d.ts +2 -0
- package/dist/loaders/index.d.ts.map +1 -0
- package/dist/loaders/index.js +2 -0
- package/dist/loaders/index.js.map +1 -0
- package/dist/loaders/load-fonts.d.ts +8 -0
- package/dist/loaders/load-fonts.d.ts.map +1 -0
- package/dist/loaders/load-fonts.js +41 -0
- package/dist/loaders/load-fonts.js.map +1 -0
- package/dist/test-setup.js +8 -2
- package/dist/test-setup.js.map +1 -1
- package/dist/utils/color-variants.d.ts +43 -0
- package/dist/utils/color-variants.d.ts.map +1 -0
- package/dist/utils/color-variants.js +72 -0
- package/dist/utils/color-variants.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/* eslint-disable sonarjs/no-duplicate-string */
|
|
2
|
+
/* eslint-disable max-lines-per-function */
|
|
3
|
+
/* eslint-disable no-magic-numbers */
|
|
4
|
+
import { Scene } from 'phaser';
|
|
5
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
6
|
+
// Mock phaser-wind
|
|
7
|
+
vi.mock('phaser-wind', () => ({
|
|
8
|
+
Color: {
|
|
9
|
+
rgb: vi.fn((color) => `rgb-${color}`),
|
|
10
|
+
hex: vi.fn((color) => `hex-${color}`),
|
|
11
|
+
},
|
|
12
|
+
}));
|
|
13
|
+
// Mock the getPWFromScene utility
|
|
14
|
+
vi.mock('../../utils/get-pw-from-scene', () => ({
|
|
15
|
+
getPWFromScene: vi.fn(() => ({
|
|
16
|
+
fontSize: {
|
|
17
|
+
px: vi.fn((size) => {
|
|
18
|
+
const sizes = { xs: 12, sm: 14, md: 16, lg: 18, xl: 20 };
|
|
19
|
+
return sizes[size] || 16;
|
|
20
|
+
}),
|
|
21
|
+
},
|
|
22
|
+
spacing: {
|
|
23
|
+
px: vi.fn((spacing) => {
|
|
24
|
+
const spacings = { xs: 4, sm: 8, md: 12, lg: 16, xl: 20 };
|
|
25
|
+
return spacings[spacing] || 12;
|
|
26
|
+
}),
|
|
27
|
+
},
|
|
28
|
+
radius: {
|
|
29
|
+
px: vi.fn((radius) => {
|
|
30
|
+
const radiuses = { none: 0, sm: 4, md: 8, lg: 12, xl: 16, full: 9999 };
|
|
31
|
+
return radiuses[radius] || 8;
|
|
32
|
+
}),
|
|
33
|
+
},
|
|
34
|
+
font: {
|
|
35
|
+
family: vi.fn((font) => {
|
|
36
|
+
const fonts = {
|
|
37
|
+
sans: 'Arial, sans-serif',
|
|
38
|
+
serif: 'Georgia, serif',
|
|
39
|
+
mono: 'Courier, monospace',
|
|
40
|
+
};
|
|
41
|
+
return fonts[font] || 'Arial, sans-serif';
|
|
42
|
+
}),
|
|
43
|
+
},
|
|
44
|
+
})),
|
|
45
|
+
}));
|
|
46
|
+
// Mock the Text component
|
|
47
|
+
vi.mock('../text', () => {
|
|
48
|
+
class MockText {
|
|
49
|
+
text;
|
|
50
|
+
style;
|
|
51
|
+
constructor(params) {
|
|
52
|
+
this.text = params.text;
|
|
53
|
+
this.style = {
|
|
54
|
+
fontSize: params.size ?? 22,
|
|
55
|
+
fontFamily: params.fontFamily ?? 'Bebas Neue',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
setText(text) {
|
|
59
|
+
this.text = text;
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
setOrigin() {
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
setFontSize(size) {
|
|
66
|
+
this.style['fontSize'] = size;
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
setFontFamily(family) {
|
|
70
|
+
this.style['fontFamily'] = family;
|
|
71
|
+
return this;
|
|
72
|
+
}
|
|
73
|
+
setColor(color) {
|
|
74
|
+
this.style['color'] = color;
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
getBounds() {
|
|
78
|
+
return getTextBounds(this.text, this.style['fontSize'] ?? 16);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return { Text: MockText };
|
|
82
|
+
});
|
|
83
|
+
// Helper function for getBounds
|
|
84
|
+
const getTextBounds = (text, fontSize) => {
|
|
85
|
+
const charWidth = 10;
|
|
86
|
+
const lineHeight = parseInt(String(fontSize)) || 16;
|
|
87
|
+
return {
|
|
88
|
+
width: text.length * charWidth,
|
|
89
|
+
height: lineHeight,
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
// Mock Phaser
|
|
93
|
+
vi.mock('phaser', () => {
|
|
94
|
+
class MockText {
|
|
95
|
+
text;
|
|
96
|
+
style;
|
|
97
|
+
constructor(_x, _y, text, style) {
|
|
98
|
+
this.text = text;
|
|
99
|
+
this.style = style;
|
|
100
|
+
}
|
|
101
|
+
setText(text) {
|
|
102
|
+
this.text = text;
|
|
103
|
+
return this;
|
|
104
|
+
}
|
|
105
|
+
setOrigin() {
|
|
106
|
+
return this;
|
|
107
|
+
}
|
|
108
|
+
setFontSize(size) {
|
|
109
|
+
this.style['fontSize'] = size;
|
|
110
|
+
return this;
|
|
111
|
+
}
|
|
112
|
+
setFontFamily(family) {
|
|
113
|
+
this.style['fontFamily'] = family;
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
setColor(color) {
|
|
117
|
+
this.style['color'] = color;
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
120
|
+
getBounds() {
|
|
121
|
+
return getTextBounds(this.text, this.style['fontSize'] ?? 16);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
class MockSprite {
|
|
125
|
+
// eslint-disable-next-line no-unused-vars
|
|
126
|
+
constructor(_x, _y, _texture) { }
|
|
127
|
+
setOrigin() {
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
setInteractive() {
|
|
131
|
+
return this;
|
|
132
|
+
}
|
|
133
|
+
setTexture() {
|
|
134
|
+
return this;
|
|
135
|
+
}
|
|
136
|
+
on() {
|
|
137
|
+
return this;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
class MockGraphics {
|
|
141
|
+
fillStyle() {
|
|
142
|
+
return this;
|
|
143
|
+
}
|
|
144
|
+
fillRoundedRect() {
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
lineStyle() {
|
|
148
|
+
return this;
|
|
149
|
+
}
|
|
150
|
+
strokeRoundedRect() {
|
|
151
|
+
return this;
|
|
152
|
+
}
|
|
153
|
+
generateTexture() {
|
|
154
|
+
return this;
|
|
155
|
+
}
|
|
156
|
+
destroy() {
|
|
157
|
+
return this;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
class MockContainer {
|
|
161
|
+
// eslint-disable-next-line no-unused-vars
|
|
162
|
+
constructor(_scene, _x, _y) {
|
|
163
|
+
this.scene = _scene;
|
|
164
|
+
}
|
|
165
|
+
add() {
|
|
166
|
+
return this;
|
|
167
|
+
}
|
|
168
|
+
scene;
|
|
169
|
+
}
|
|
170
|
+
class Scene {
|
|
171
|
+
add = {
|
|
172
|
+
text: vi.fn((x, y, text, style) => new MockText(x, y, text, style)),
|
|
173
|
+
sprite: vi.fn((x, y, texture) => new MockSprite(x, y, texture)),
|
|
174
|
+
graphics: vi.fn(() => new MockGraphics()),
|
|
175
|
+
};
|
|
176
|
+
tweens = { add: vi.fn() };
|
|
177
|
+
}
|
|
178
|
+
class BasePlugin {
|
|
179
|
+
constructor() { }
|
|
180
|
+
}
|
|
181
|
+
const GameObjects = { Container: MockContainer };
|
|
182
|
+
const Plugins = { BasePlugin };
|
|
183
|
+
return { GameObjects, Scene, Plugins };
|
|
184
|
+
});
|
|
185
|
+
import { FlatTextButton } from './flat-text-button';
|
|
186
|
+
describe('FlatTextButton', () => {
|
|
187
|
+
it('should create a FlatTextButton instance', () => {
|
|
188
|
+
const scene = new Scene();
|
|
189
|
+
const textButton = new FlatTextButton({
|
|
190
|
+
scene,
|
|
191
|
+
x: 100,
|
|
192
|
+
y: 100,
|
|
193
|
+
text: 'Click Me',
|
|
194
|
+
});
|
|
195
|
+
expect(textButton).toBeInstanceOf(FlatTextButton);
|
|
196
|
+
});
|
|
197
|
+
it('should create with custom properties', () => {
|
|
198
|
+
const scene = new Scene();
|
|
199
|
+
const textButton = new FlatTextButton({
|
|
200
|
+
scene,
|
|
201
|
+
x: 100,
|
|
202
|
+
y: 100,
|
|
203
|
+
text: 'Custom Button',
|
|
204
|
+
fontSize: 'lg',
|
|
205
|
+
color: 'red',
|
|
206
|
+
textColor: 'white',
|
|
207
|
+
borderRadius: 'lg',
|
|
208
|
+
padding: '4',
|
|
209
|
+
});
|
|
210
|
+
expect(textButton).toBeInstanceOf(FlatTextButton);
|
|
211
|
+
});
|
|
212
|
+
it('should support method chaining', () => {
|
|
213
|
+
const scene = new Scene();
|
|
214
|
+
const textButton = new FlatTextButton({
|
|
215
|
+
scene,
|
|
216
|
+
x: 100,
|
|
217
|
+
y: 100,
|
|
218
|
+
text: 'Test',
|
|
219
|
+
});
|
|
220
|
+
const result = textButton
|
|
221
|
+
.setText('Chained')
|
|
222
|
+
.setFontSize('lg')
|
|
223
|
+
.setColor('green')
|
|
224
|
+
.setBorderRadius('lg')
|
|
225
|
+
.setPadding('4');
|
|
226
|
+
expect(result).toBe(textButton);
|
|
227
|
+
});
|
|
228
|
+
it('should handle borderRadius full correctly', () => {
|
|
229
|
+
const scene = new Scene();
|
|
230
|
+
const textButton = new FlatTextButton({
|
|
231
|
+
scene,
|
|
232
|
+
x: 100,
|
|
233
|
+
y: 100,
|
|
234
|
+
text: 'Full Radius Test',
|
|
235
|
+
borderRadius: 'full',
|
|
236
|
+
});
|
|
237
|
+
expect(textButton).toBeInstanceOf(FlatTextButton);
|
|
238
|
+
// Test setBorderRadius with 'full'
|
|
239
|
+
const result = textButton.setBorderRadius('full');
|
|
240
|
+
expect(result).toBe(textButton);
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
//# sourceMappingURL=flat-text-button.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flat-text-button.spec.js","sourceRoot":"","sources":["../../../src/components/flat-text-button/flat-text-button.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/flat-text-button/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/flat-text-button/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
|
|
@@ -14,20 +14,28 @@ export type IconButtonParams = {
|
|
|
14
14
|
};
|
|
15
15
|
export declare class IconButton extends GameObjects.Container {
|
|
16
16
|
backgroundSprite: GameObjects.Sprite;
|
|
17
|
-
|
|
17
|
+
whiteBorderSprite: GameObjects.Sprite;
|
|
18
18
|
iconText: IconText;
|
|
19
19
|
private pw;
|
|
20
20
|
private baseColor;
|
|
21
|
+
private colorButton;
|
|
22
|
+
private lightColorButton;
|
|
23
|
+
private darkColorButton;
|
|
21
24
|
private sizePx;
|
|
22
25
|
private borderRadiusPx;
|
|
23
26
|
constructor({ scene, x, y, icon, size, color, onClick, borderRadius, }: IconButtonParams);
|
|
24
27
|
setBorderRadius(borderRadius: RadiusKey | number): this;
|
|
25
28
|
setButtonSize(size: FontSizeKey | number): this;
|
|
26
|
-
private createShadowSprite;
|
|
27
|
-
private createShadowTexture;
|
|
28
29
|
private updateSize;
|
|
30
|
+
private createWhiteBorderSprite;
|
|
29
31
|
private createBackgroundSprite;
|
|
32
|
+
private createWhiteBorderTexture;
|
|
30
33
|
private createBackgroundTexture;
|
|
34
|
+
/**
|
|
35
|
+
* Draws gradient using a centered light overlay on CSS color.
|
|
36
|
+
* For round buttons, uses a smaller centered graphic with light color.
|
|
37
|
+
*/
|
|
38
|
+
private drawCssColorGradient;
|
|
31
39
|
private createIconText;
|
|
32
40
|
private setupContainer;
|
|
33
41
|
private setupInteractivity;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon-button.d.ts","sourceRoot":"","sources":["../../../src/components/icon-button/icon-button.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"icon-button.d.ts","sourceRoot":"","sources":["../../../src/components/icon-button/icon-button.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,KAAK,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,SAAS,EACf,MAAM,aAAa,CAAC;AAKrB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,KAAK,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC5B,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC;IAC1C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,+FAA+F;IAC/F,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CACnC,CAAC;AAmCF,qBAAa,UAAW,SAAQ,WAAW,CAAC,SAAS;IAC5C,gBAAgB,EAAG,WAAW,CAAC,MAAM,CAAC;IACtC,iBAAiB,EAAG,WAAW,CAAC,MAAM,CAAC;IACvC,QAAQ,EAAG,QAAQ,CAAC;IAE3B,OAAO,CAAC,EAAE,CAAuB;IACjC,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,gBAAgB,CAAU;IAClC,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,cAAc,CAAU;gBAEpB,EACV,KAAK,EACL,CAAC,EACD,CAAC,EACD,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,OAAO,EACP,YAAY,GACb,EAAE,gBAAgB;IA+BZ,eAAe,CAAC,YAAY,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI;IAyBvD,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI;IA0BtD,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,uBAAuB;IAc/B,OAAO,CAAC,sBAAsB;IAgB9B,OAAO,CAAC,wBAAwB;IAkChC,OAAO,CAAC,uBAAuB;IAyB/B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAyC5B,OAAO,CAAC,cAAc;IAoCtB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,kBAAkB;IA+C1B;;;OAGG;IACH,IAAW,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,GAAG,KAAK,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,MAAM,CAAC,CAQ9G;IAED;;;;OAIG;IACa,SAAS,CACvB,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,GAC7B,MAAM,CAAC,IAAI,CAAC,SAAS;CAoBzB"}
|
|
@@ -1,28 +1,45 @@
|
|
|
1
|
+
/* eslint-disable max-lines-per-function */
|
|
1
2
|
/* eslint-disable max-lines */
|
|
2
3
|
import { IconText } from 'font-awesome-for-phaser';
|
|
3
4
|
import { GameObjects } from 'phaser';
|
|
4
5
|
import { Color, } from 'phaser-wind';
|
|
6
|
+
import { getColorVariant } from '../../utils/color-variants';
|
|
5
7
|
import { getPWFromScene } from '../../utils/get-pw-from-scene';
|
|
6
8
|
const durations = {
|
|
7
|
-
click:
|
|
8
|
-
hover:
|
|
9
|
+
click: 60,
|
|
10
|
+
hover: 100,
|
|
9
11
|
};
|
|
10
12
|
const BUTTON_SCALE = 2.2;
|
|
11
13
|
const CENTER_OFFSET = 1.1;
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
14
|
+
const HOVER_SCALE = 1.05;
|
|
15
|
+
const POINTER_DOWN_SCALE = 0.95;
|
|
16
|
+
const TOKEN_LIGHTER_DIFF = -100;
|
|
17
|
+
const COLOR_LIGHTER_AMOUNT = 30;
|
|
18
|
+
// Border constants
|
|
19
|
+
const BLACK_BORDER_THICKNESS = 2;
|
|
20
|
+
const WHITE_BORDER_EXTRA_PIXELS_PER_SIDE = 2;
|
|
21
|
+
// eslint-disable-next-line no-magic-numbers
|
|
22
|
+
const WHITE_BORDER_TOTAL_EXTRA_PIXELS = WHITE_BORDER_EXTRA_PIXELS_PER_SIDE * 3; // 5 pixels total
|
|
23
|
+
const WHITE_BORDER_RADIUS_EXTRA = 2;
|
|
24
|
+
// Overlay constants
|
|
25
|
+
const LIGHT_OVERLAY_SCALE = 0.6;
|
|
26
|
+
// Icon constants
|
|
27
|
+
const ICON_STROKE_THICKNESS = 3;
|
|
28
|
+
const ICON_SHADOW_OFFSET_X = 0;
|
|
29
|
+
const ICON_SHADOW_OFFSET_Y = 3;
|
|
30
|
+
const ICON_SHADOW_BLUR = 0;
|
|
31
|
+
const ICON_OFFSET_Y = -1.5; // Half of shadow offset to keep visually centered
|
|
32
|
+
// Origin constants
|
|
33
|
+
const SPRITE_ORIGIN = 0.5;
|
|
20
34
|
export class IconButton extends GameObjects.Container {
|
|
21
35
|
backgroundSprite;
|
|
22
|
-
|
|
36
|
+
whiteBorderSprite;
|
|
23
37
|
iconText;
|
|
24
38
|
pw;
|
|
25
39
|
baseColor;
|
|
40
|
+
colorButton;
|
|
41
|
+
lightColorButton;
|
|
42
|
+
darkColorButton;
|
|
26
43
|
sizePx;
|
|
27
44
|
borderRadiusPx;
|
|
28
45
|
constructor({ scene, x, y, icon, size, color, onClick, borderRadius, }) {
|
|
@@ -31,17 +48,21 @@ export class IconButton extends GameObjects.Container {
|
|
|
31
48
|
const sizePx = typeof size === 'number'
|
|
32
49
|
? size
|
|
33
50
|
: this.pw.fontSize.px(size ?? 'md');
|
|
34
|
-
const baseColor = color ?? '
|
|
51
|
+
const baseColor = color ?? 'blue-500';
|
|
35
52
|
this.sizePx = sizePx;
|
|
36
53
|
this.updateSize();
|
|
37
54
|
this.baseColor = baseColor;
|
|
55
|
+
this.colorButton = Color.rgb(baseColor);
|
|
56
|
+
this.lightColorButton = getColorVariant(baseColor, TOKEN_LIGHTER_DIFF, COLOR_LIGHTER_AMOUNT);
|
|
57
|
+
// this.darkColorButton = getColorVariant(baseColor as string, TOKEN_DARKER_DIFF, COLOR_DARKER_AMOUNT);
|
|
58
|
+
this.darkColorButton = Color.blackHex();
|
|
38
59
|
this.borderRadiusPx =
|
|
39
60
|
typeof borderRadius === 'number'
|
|
40
61
|
? borderRadius
|
|
41
62
|
: this.pw.radius.px((borderRadius ?? 'full'));
|
|
42
|
-
this.
|
|
63
|
+
this.createWhiteBorderSprite(scene, sizePx, this.borderRadiusPx);
|
|
43
64
|
this.createBackgroundSprite(scene, sizePx, baseColor, this.borderRadiusPx);
|
|
44
|
-
this.createIconText(scene, icon, sizePx
|
|
65
|
+
this.createIconText(scene, icon, sizePx);
|
|
45
66
|
this.setupContainer();
|
|
46
67
|
this.setupInteractivity(onClick);
|
|
47
68
|
}
|
|
@@ -52,10 +73,10 @@ export class IconButton extends GameObjects.Container {
|
|
|
52
73
|
if (this.borderRadiusPx === newRadiusPx)
|
|
53
74
|
return this;
|
|
54
75
|
this.borderRadiusPx = newRadiusPx;
|
|
55
|
-
// Regenerate textures for
|
|
56
|
-
const
|
|
76
|
+
// Regenerate textures for white border and background
|
|
77
|
+
const whiteBorderTexture = this.createWhiteBorderTexture(this.scene, this.sizePx, this.borderRadiusPx);
|
|
57
78
|
const backgroundTexture = this.createBackgroundTexture(this.scene, this.sizePx, this.baseColor, this.borderRadiusPx);
|
|
58
|
-
this.
|
|
79
|
+
this.whiteBorderSprite.setTexture(whiteBorderTexture);
|
|
59
80
|
this.backgroundSprite.setTexture(backgroundTexture);
|
|
60
81
|
return this;
|
|
61
82
|
}
|
|
@@ -66,42 +87,43 @@ export class IconButton extends GameObjects.Container {
|
|
|
66
87
|
: this.pw.fontSize.px(size ?? 'md');
|
|
67
88
|
this.iconText.setFontSize(`${this.sizePx}px`);
|
|
68
89
|
this.updateSize();
|
|
69
|
-
const
|
|
90
|
+
const whiteBorderTexture = this.createWhiteBorderTexture(this.scene, this.sizePx, this.borderRadiusPx);
|
|
70
91
|
const backgroundTexture = this.createBackgroundTexture(this.scene, this.sizePx, this.baseColor, this.borderRadiusPx);
|
|
71
|
-
this.
|
|
92
|
+
this.whiteBorderSprite.setTexture(whiteBorderTexture);
|
|
72
93
|
this.backgroundSprite.setTexture(backgroundTexture);
|
|
73
94
|
return this;
|
|
74
95
|
}
|
|
75
|
-
createShadowSprite(scene, size, baseColor, borderRadiusPx) {
|
|
76
|
-
const shadowTexture = this.createShadowTexture(scene, size, baseColor, borderRadiusPx);
|
|
77
|
-
this.shadowSprite = scene.add.sprite(1, SHADOW_OFFSET, shadowTexture);
|
|
78
|
-
this.shadowSprite.setOrigin(0.5, 0.5);
|
|
79
|
-
}
|
|
80
|
-
createShadowTexture(scene, size, baseColor, borderRadiusPx) {
|
|
81
|
-
const textureKey = `iconButton_shadow_r${borderRadiusPx}_${baseColor}_${size}`;
|
|
82
|
-
const textureSize = size * BUTTON_SCALE;
|
|
83
|
-
const centerX = size * CENTER_OFFSET;
|
|
84
|
-
const centerY = size * CENTER_OFFSET;
|
|
85
|
-
const graphics = scene.add.graphics();
|
|
86
|
-
const sideOuter = size * 2 * CENTER_OFFSET;
|
|
87
|
-
const side = size * 2;
|
|
88
|
-
const radiusOuter = Math.min(borderRadiusPx, sideOuter / 2);
|
|
89
|
-
const radius = Math.min(borderRadiusPx, side / 2);
|
|
90
|
-
graphics.fillStyle(Color.hex('black'), SHADOW_OPACITY);
|
|
91
|
-
graphics.fillRoundedRect(centerX + 1 - sideOuter / 2, centerY - sideOuter / 2, sideOuter, sideOuter, radiusOuter);
|
|
92
|
-
graphics.fillStyle(Color.hex(`${baseColor}-900`), MAIN_SHADOW_OPACITY);
|
|
93
|
-
graphics.fillRoundedRect(centerX - side / 2, centerY - CLICK_OFFSET - side / 2, side, side, radius);
|
|
94
|
-
graphics.generateTexture(textureKey, textureSize, textureSize);
|
|
95
|
-
graphics.destroy();
|
|
96
|
-
return textureKey;
|
|
97
|
-
}
|
|
98
96
|
updateSize() {
|
|
99
97
|
this.setSize(this.sizePx * BUTTON_SCALE, this.sizePx * BUTTON_SCALE);
|
|
100
98
|
}
|
|
99
|
+
createWhiteBorderSprite(scene, size, borderRadiusPx) {
|
|
100
|
+
const whiteBorderTexture = this.createWhiteBorderTexture(scene, size, borderRadiusPx);
|
|
101
|
+
this.whiteBorderSprite = scene.add.sprite(0, 0, whiteBorderTexture);
|
|
102
|
+
this.whiteBorderSprite.setOrigin(SPRITE_ORIGIN, SPRITE_ORIGIN);
|
|
103
|
+
}
|
|
101
104
|
createBackgroundSprite(scene, size, baseColor, borderRadiusPx) {
|
|
102
105
|
const backgroundTexture = this.createBackgroundTexture(scene, size, baseColor, borderRadiusPx);
|
|
103
|
-
this.backgroundSprite = scene.add.sprite(
|
|
104
|
-
this.backgroundSprite.setOrigin(
|
|
106
|
+
this.backgroundSprite = scene.add.sprite(0, 0, backgroundTexture);
|
|
107
|
+
this.backgroundSprite.setOrigin(SPRITE_ORIGIN, SPRITE_ORIGIN);
|
|
108
|
+
}
|
|
109
|
+
createWhiteBorderTexture(scene, size, borderRadiusPx) {
|
|
110
|
+
const textureKey = `iconButton_whiteBorder_r${borderRadiusPx}_${size}`;
|
|
111
|
+
// White border is larger on each side
|
|
112
|
+
const side = size * 2 + WHITE_BORDER_TOTAL_EXTRA_PIXELS;
|
|
113
|
+
// Increase texture size to accommodate the larger border
|
|
114
|
+
const textureSize = size * BUTTON_SCALE + WHITE_BORDER_TOTAL_EXTRA_PIXELS;
|
|
115
|
+
const centerX = textureSize / 2;
|
|
116
|
+
const centerY = textureSize / 2;
|
|
117
|
+
const graphics = scene.add.graphics();
|
|
118
|
+
const maxRadius = Math.floor(Math.min(side / 2, side / 2));
|
|
119
|
+
const effectiveRadius = Math.min(borderRadiusPx + WHITE_BORDER_RADIUS_EXTRA, maxRadius);
|
|
120
|
+
const finalRadius = Math.max(0, effectiveRadius);
|
|
121
|
+
// White border (outer)
|
|
122
|
+
graphics.fillStyle(Color.hex('white'), 1);
|
|
123
|
+
graphics.fillRoundedRect(centerX - side / 2, centerY - side / 2, side, side, finalRadius);
|
|
124
|
+
graphics.generateTexture(textureKey, textureSize, textureSize);
|
|
125
|
+
graphics.destroy();
|
|
126
|
+
return textureKey;
|
|
105
127
|
}
|
|
106
128
|
createBackgroundTexture(scene, size, baseColor, borderRadiusPx) {
|
|
107
129
|
const textureKey = `iconButton_r${borderRadiusPx}_${baseColor}_${size}`;
|
|
@@ -110,67 +132,100 @@ export class IconButton extends GameObjects.Container {
|
|
|
110
132
|
const centerY = size * CENTER_OFFSET;
|
|
111
133
|
const graphics = scene.add.graphics();
|
|
112
134
|
const side = size * 2;
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
graphics.fillStyle(Color.hex(`${baseColor}-600`), 1);
|
|
118
|
-
graphics.fillRoundedRect(centerX - mainSide / 2, centerY - mainSide / 2, mainSide, mainSide, mainRadius);
|
|
119
|
-
graphics.fillStyle(Color.hex(`${baseColor}-500`), INNER_OVERLAY_OPACITY);
|
|
120
|
-
graphics.fillRoundedRect(centerX - innerSide / 2, centerY - innerSide / 2, innerSide, innerSide, innerRadius);
|
|
135
|
+
const maxRadius = Math.floor(Math.min(side / 2, side / 2));
|
|
136
|
+
const effectiveRadius = Math.min(borderRadiusPx, maxRadius);
|
|
137
|
+
const finalRadius = Math.max(0, effectiveRadius);
|
|
138
|
+
this.drawCssColorGradient(graphics, centerX, centerY, side, finalRadius);
|
|
121
139
|
graphics.generateTexture(textureKey, textureSize, textureSize);
|
|
122
140
|
graphics.destroy();
|
|
123
141
|
return textureKey;
|
|
124
142
|
}
|
|
125
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Draws gradient using a centered light overlay on CSS color.
|
|
145
|
+
* For round buttons, uses a smaller centered graphic with light color.
|
|
146
|
+
*/
|
|
147
|
+
drawCssColorGradient(graphics, centerX, centerY, side, effectiveRadius) {
|
|
148
|
+
// Main background
|
|
149
|
+
graphics.fillStyle(Color.hex(this.colorButton), 1);
|
|
150
|
+
graphics.fillRoundedRect(centerX - side / 2, centerY - side / 2, side, side, effectiveRadius);
|
|
151
|
+
// Centered light overlay (smaller, circular/rounded)
|
|
152
|
+
const overlaySide = side * LIGHT_OVERLAY_SCALE;
|
|
153
|
+
const overlayRadius = Math.min(effectiveRadius, overlaySide / 2);
|
|
154
|
+
graphics.fillStyle(this.lightColorButton, 1);
|
|
155
|
+
graphics.fillRoundedRect(centerX - overlaySide / 2, centerY - overlaySide / 2, overlaySide, overlaySide, overlayRadius);
|
|
156
|
+
// Black stroke border
|
|
157
|
+
graphics.lineStyle(BLACK_BORDER_THICKNESS, Color.hex('black'), 1);
|
|
158
|
+
graphics.strokeRoundedRect(centerX - side / 2, centerY - side / 2, side, side, effectiveRadius);
|
|
159
|
+
}
|
|
160
|
+
createIconText(scene, icon, size) {
|
|
161
|
+
// Convert darkColorButton (number) to RGB string
|
|
162
|
+
const darkColorObj = Phaser.Display.Color.ValueToColor(this.darkColorButton);
|
|
163
|
+
const RGB_MASK = 0xff;
|
|
164
|
+
const RGB_SHIFT_R = 16;
|
|
165
|
+
const RGB_SHIFT_G = 8;
|
|
166
|
+
const darkColorString = `rgb(${darkColorObj.color32 >> RGB_SHIFT_R & RGB_MASK}, ${darkColorObj.color32 >> RGB_SHIFT_G & RGB_MASK}, ${darkColorObj.color32 & RGB_MASK})`;
|
|
126
167
|
this.iconText = new IconText({
|
|
127
168
|
scene,
|
|
128
|
-
x:
|
|
129
|
-
y:
|
|
169
|
+
x: 0,
|
|
170
|
+
y: ICON_OFFSET_Y,
|
|
130
171
|
icon,
|
|
131
172
|
size,
|
|
132
173
|
style: {
|
|
133
174
|
color: Color.rgb('white'),
|
|
134
|
-
strokeThickness:
|
|
135
|
-
stroke:
|
|
175
|
+
strokeThickness: ICON_STROKE_THICKNESS,
|
|
176
|
+
stroke: darkColorString,
|
|
177
|
+
shadow: {
|
|
178
|
+
offsetX: ICON_SHADOW_OFFSET_X,
|
|
179
|
+
offsetY: ICON_SHADOW_OFFSET_Y,
|
|
180
|
+
color: darkColorString,
|
|
181
|
+
blur: ICON_SHADOW_BLUR,
|
|
182
|
+
stroke: true,
|
|
183
|
+
fill: true,
|
|
184
|
+
},
|
|
136
185
|
},
|
|
137
186
|
});
|
|
138
187
|
this.iconText.setFontStyle('900');
|
|
139
|
-
this.iconText.setOrigin(
|
|
188
|
+
this.iconText.setOrigin(SPRITE_ORIGIN, SPRITE_ORIGIN);
|
|
140
189
|
}
|
|
141
190
|
setupContainer() {
|
|
142
|
-
this.add([this.
|
|
191
|
+
this.add([this.whiteBorderSprite, this.backgroundSprite, this.iconText]);
|
|
143
192
|
}
|
|
144
193
|
setupInteractivity(onClick) {
|
|
145
194
|
this.backgroundSprite.setInteractive({ useHandCursor: true });
|
|
195
|
+
// Hover effects
|
|
146
196
|
this.backgroundSprite.on('pointerover', () => {
|
|
147
197
|
this.scene.tweens.add({
|
|
148
|
-
targets: this
|
|
149
|
-
scale: HOVER_SCALE,
|
|
198
|
+
targets: this,
|
|
150
199
|
duration: durations.hover,
|
|
151
|
-
|
|
200
|
+
scaleX: HOVER_SCALE,
|
|
201
|
+
scaleY: HOVER_SCALE,
|
|
202
|
+
ease: 'Back.easeOut',
|
|
152
203
|
});
|
|
153
204
|
});
|
|
154
205
|
this.backgroundSprite.on('pointerout', () => {
|
|
155
206
|
this.scene.tweens.add({
|
|
156
|
-
targets: this
|
|
157
|
-
scale: 1,
|
|
207
|
+
targets: this,
|
|
158
208
|
duration: durations.hover,
|
|
159
|
-
|
|
209
|
+
scaleX: 1,
|
|
210
|
+
scaleY: 1,
|
|
211
|
+
ease: 'Back.easeOut',
|
|
160
212
|
});
|
|
161
213
|
});
|
|
214
|
+
// Click effects
|
|
162
215
|
this.backgroundSprite.on('pointerdown', () => {
|
|
163
216
|
this.scene.tweens.add({
|
|
164
|
-
targets: [this.backgroundSprite, this.iconText],
|
|
165
|
-
|
|
217
|
+
targets: [this.whiteBorderSprite, this.backgroundSprite, this.iconText],
|
|
218
|
+
scaleX: POINTER_DOWN_SCALE,
|
|
219
|
+
scaleY: POINTER_DOWN_SCALE,
|
|
166
220
|
duration: durations.click,
|
|
167
221
|
ease: 'Linear',
|
|
168
222
|
});
|
|
169
223
|
});
|
|
170
224
|
this.backgroundSprite.on('pointerup', () => {
|
|
171
225
|
this.scene.tweens.add({
|
|
172
|
-
targets: [this.backgroundSprite, this.iconText],
|
|
173
|
-
|
|
226
|
+
targets: [this.whiteBorderSprite, this.backgroundSprite, this.iconText],
|
|
227
|
+
scaleX: 1,
|
|
228
|
+
scaleY: 1,
|
|
174
229
|
duration: durations.click,
|
|
175
230
|
ease: 'Linear',
|
|
176
231
|
});
|
|
@@ -196,8 +251,8 @@ export class IconButton extends GameObjects.Container {
|
|
|
196
251
|
* @returns Rectangle with the button bounds
|
|
197
252
|
*/
|
|
198
253
|
getBounds(output) {
|
|
199
|
-
const width = this.
|
|
200
|
-
const height = this.
|
|
254
|
+
const width = this.backgroundSprite.displayWidth ?? this.backgroundSprite.width;
|
|
255
|
+
const height = this.backgroundSprite.displayHeight ?? this.backgroundSprite.height;
|
|
201
256
|
if (output) {
|
|
202
257
|
return output.setTo(this.x - width / 2, this.y - height / 2, width, height);
|
|
203
258
|
}
|