phaser-wind 0.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/LICENSE +21 -0
- package/README.md +446 -0
- package/dist/color/color-picker.d.ts +13 -0
- package/dist/color/color-picker.d.ts.map +1 -0
- package/dist/color/color-picker.js +61 -0
- package/dist/color/color-picker.js.map +1 -0
- package/dist/color/color-picker.spec.d.ts +2 -0
- package/dist/color/color-picker.spec.d.ts.map +1 -0
- package/dist/color/color-picker.spec.js +41 -0
- package/dist/color/color-picker.spec.js.map +1 -0
- package/dist/color/index.d.ts +3 -0
- package/dist/color/index.d.ts.map +1 -0
- package/dist/color/index.js +3 -0
- package/dist/color/index.js.map +1 -0
- package/dist/color/pallete.d.ts +291 -0
- package/dist/color/pallete.d.ts.map +1 -0
- package/dist/color/pallete.js +292 -0
- package/dist/color/pallete.js.map +1 -0
- package/dist/font/font-size-picker.d.ts +19 -0
- package/dist/font/font-size-picker.d.ts.map +1 -0
- package/dist/font/font-size-picker.js +24 -0
- package/dist/font/font-size-picker.js.map +1 -0
- package/dist/font/font-size-picker.spec.d.ts +2 -0
- package/dist/font/font-size-picker.spec.d.ts.map +1 -0
- package/dist/font/font-size-picker.spec.js +48 -0
- package/dist/font/font-size-picker.spec.js.map +1 -0
- package/dist/font/index.d.ts +2 -0
- package/dist/font/index.d.ts.map +1 -0
- package/dist/font/index.js +2 -0
- package/dist/font/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/package.json +70 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 CassinoDev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
# 🌪️ Phaser Wind
|
|
2
|
+
|
|
3
|
+
<center>
|
|
4
|
+
<img src="data/image.png" height="350" style="margin: 0 auto;" alt="Phaser + TailWIND">
|
|
5
|
+
</center>
|
|
6
|
+
|
|
7
|
+
> **Tired of fighting with Phaser layouts and colors?**
|
|
8
|
+
>
|
|
9
|
+
> **Love Tailwind CSS but stuck with Phaser?**
|
|
10
|
+
>
|
|
11
|
+
> **Welcome to Phaser Wind** - bringing the joy and simplicity of Tailwind CSS design tokens to Phaser games! 🎮✨
|
|
12
|
+
|
|
13
|
+
[](https://www.npmjs.com/package/phaser-wind)
|
|
14
|
+
[](https://opensource.org/licenses/MIT)
|
|
15
|
+
[](https://www.typescriptlang.org/)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 🎯 Why Phaser Wind?
|
|
20
|
+
|
|
21
|
+
### The Problem 😫
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// Ugh... more magic numbers and random colors
|
|
25
|
+
const button = this.add.text(100, 50, 'Click me!', {
|
|
26
|
+
fontSize: '18px', // Is this too big? Too small? 🤷♂️
|
|
27
|
+
fill: '#3B82F6', // What color is this again?
|
|
28
|
+
backgroundColor: '#1F2937', // Does this even look good?
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const title = this.add.text(200, 100, 'Game Title', {
|
|
32
|
+
fontSize: '32px', // Different magic number...
|
|
33
|
+
fill: '#EF4444', // Another random hex...
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### The Solution 🌟
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { ColorPicker, FontSizePicker } from 'phaser-wind';
|
|
41
|
+
|
|
42
|
+
// Clean, semantic, consistent!
|
|
43
|
+
const button = this.add.text(100, 50, 'Click me!', {
|
|
44
|
+
fontSize: FontSizePicker.css('lg'), // Clear intention!
|
|
45
|
+
fill: ColorPicker.rgb('blue-500'), // Beautiful blue
|
|
46
|
+
backgroundColor: ColorPicker.rgb('gray-800'), // Perfect contrast
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const title = this.add.text(200, 100, 'Game Title', {
|
|
50
|
+
fontSize: FontSizePicker.css('3xl'), // Clearly bigger!
|
|
51
|
+
fill: ColorPicker.rgb('red-500'), // Vibrant red
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 🚀 Features
|
|
58
|
+
|
|
59
|
+
- 🎨 **Complete Tailwind Color Palette** - All 22 color families with 11 shades each
|
|
60
|
+
- 📐 **Semantic Font Sizes** - From `xs` to `6xl`, just like Tailwind
|
|
61
|
+
- 🔧 **TypeScript First** - Full type safety and IntelliSense
|
|
62
|
+
- 🎮 **Phaser Ready** - Designed specifically for Phaser 3 games
|
|
63
|
+
- 🌈 **Consistent Design** - No more guessing colors and sizes
|
|
64
|
+
- 📦 **Tiny Bundle** - Zero runtime overhead, just better DX
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 📦 Installation
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npm install phaser-wind
|
|
72
|
+
# or
|
|
73
|
+
yarn add phaser-wind
|
|
74
|
+
# or
|
|
75
|
+
pnpm add phaser-wind
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 🎨 Color System
|
|
81
|
+
|
|
82
|
+
### Complete Tailwind Palette
|
|
83
|
+
|
|
84
|
+
Access all Tailwind colors with semantic naming:
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { ColorPicker } from 'phaser-wind';
|
|
88
|
+
|
|
89
|
+
// RGB strings (for Phaser text styles)
|
|
90
|
+
const blueText = ColorPicker.rgb('blue-500'); // 'rgb(59, 130, 246)'
|
|
91
|
+
const redButton = ColorPicker.rgb('red-600'); // 'rgb(220, 38, 38)'
|
|
92
|
+
|
|
93
|
+
// Hex numbers (for Phaser graphics)
|
|
94
|
+
const greenRect = ColorPicker.hex('green-400'); // 0x4ADE80
|
|
95
|
+
const purpleCircle = ColorPicker.hex('purple-300'); // 0xD8B4FE
|
|
96
|
+
|
|
97
|
+
// Basic colors
|
|
98
|
+
const blackText = ColorPicker.rgb('black'); // 'rgb(0, 0, 0)'
|
|
99
|
+
const whiteBackground = ColorPicker.hex('white'); // 0xFFFFFF
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Available Colors
|
|
103
|
+
|
|
104
|
+
**Grays:** `slate`, `gray`, `zinc`, `neutral`, `stone`
|
|
105
|
+
**Colors:** `red`, `orange`, `amber`, `yellow`, `lime`, `green`, `emerald`, `teal`, `cyan`, `sky`, `blue`, `indigo`, `violet`, `purple`, `fuchsia`, `pink`, `rose`
|
|
106
|
+
**Shades:** `50`, `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`, `950`
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 📏 Font Size System
|
|
111
|
+
|
|
112
|
+
### Semantic Sizing
|
|
113
|
+
|
|
114
|
+
Stop guessing font sizes and use semantic tokens:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
import { FontSizePicker } from 'phaser-wind';
|
|
118
|
+
|
|
119
|
+
// Get pixel values
|
|
120
|
+
const smallText = FontSizePicker.px('sm'); // 14
|
|
121
|
+
const normalText = FontSizePicker.px('md'); // 16
|
|
122
|
+
const largeTitle = FontSizePicker.px('3xl'); // 30
|
|
123
|
+
|
|
124
|
+
// Get CSS strings (perfect for Phaser)
|
|
125
|
+
const buttonText = FontSizePicker.css('lg'); // '18px'
|
|
126
|
+
const heroTitle = FontSizePicker.css('6xl'); // '60px'
|
|
127
|
+
|
|
128
|
+
// Get rem values (if needed)
|
|
129
|
+
const responsiveText = FontSizePicker.rem('xl'); // 1.25
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Font Size Scale
|
|
133
|
+
|
|
134
|
+
| Token | Pixels | Use Case |
|
|
135
|
+
| ----- | ------ | ----------------------- |
|
|
136
|
+
| `xs` | 12px | Small labels, captions |
|
|
137
|
+
| `sm` | 14px | Body text, descriptions |
|
|
138
|
+
| `md` | 16px | Default text size |
|
|
139
|
+
| `lg` | 18px | Slightly larger text |
|
|
140
|
+
| `xl` | 20px | Subheadings |
|
|
141
|
+
| `2xl` | 24px | Headings |
|
|
142
|
+
| `3xl` | 30px | Large headings |
|
|
143
|
+
| `4xl` | 36px | Hero text |
|
|
144
|
+
| `5xl` | 48px | Display text |
|
|
145
|
+
| `6xl` | 60px | Giant display text |
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## 💡 Real-World Examples
|
|
150
|
+
|
|
151
|
+
### Game UI Components
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
import { ColorPicker, FontSizePicker } from 'phaser-wind';
|
|
155
|
+
|
|
156
|
+
export class GameScene extends Phaser.Scene {
|
|
157
|
+
create() {
|
|
158
|
+
// Main title
|
|
159
|
+
this.add
|
|
160
|
+
.text(400, 100, 'SPACE RAIDERS', {
|
|
161
|
+
fontSize: FontSizePicker.css('5xl'),
|
|
162
|
+
fill: ColorPicker.rgb('yellow-400'),
|
|
163
|
+
stroke: ColorPicker.rgb('yellow-800'),
|
|
164
|
+
strokeThickness: 2,
|
|
165
|
+
})
|
|
166
|
+
.setOrigin(0.5);
|
|
167
|
+
|
|
168
|
+
// Score display
|
|
169
|
+
this.add.text(50, 50, 'Score: 12,500', {
|
|
170
|
+
fontSize: FontSizePicker.css('xl'),
|
|
171
|
+
fill: ColorPicker.rgb('green-400'),
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// Health bar background
|
|
175
|
+
const healthBg = this.add.graphics();
|
|
176
|
+
healthBg.fillStyle(ColorPicker.hex('red-900'));
|
|
177
|
+
healthBg.fillRect(50, 100, 200, 20);
|
|
178
|
+
|
|
179
|
+
// Health bar fill
|
|
180
|
+
const healthFill = this.add.graphics();
|
|
181
|
+
healthFill.fillStyle(ColorPicker.hex('red-500'));
|
|
182
|
+
healthFill.fillRect(52, 102, 156, 16); // 80% health
|
|
183
|
+
|
|
184
|
+
// Game over screen
|
|
185
|
+
this.add.rectangle(400, 300, 600, 400, ColorPicker.hex('slate-900'), 0.9);
|
|
186
|
+
|
|
187
|
+
this.add
|
|
188
|
+
.text(400, 250, 'GAME OVER', {
|
|
189
|
+
fontSize: FontSizePicker.css('4xl'),
|
|
190
|
+
fill: ColorPicker.rgb('red-500'),
|
|
191
|
+
})
|
|
192
|
+
.setOrigin(0.5);
|
|
193
|
+
|
|
194
|
+
this.add
|
|
195
|
+
.text(400, 320, 'Final Score: 12,500', {
|
|
196
|
+
fontSize: FontSizePicker.css('2xl'),
|
|
197
|
+
fill: ColorPicker.rgb('slate-300'),
|
|
198
|
+
})
|
|
199
|
+
.setOrigin(0.5);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Button System
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
class GameButton {
|
|
208
|
+
constructor(
|
|
209
|
+
scene: Phaser.Scene,
|
|
210
|
+
x: number,
|
|
211
|
+
y: number,
|
|
212
|
+
text: string,
|
|
213
|
+
variant: 'primary' | 'secondary' | 'danger' = 'primary'
|
|
214
|
+
) {
|
|
215
|
+
const colors = {
|
|
216
|
+
primary: {
|
|
217
|
+
bg: ColorPicker.hex('blue-600'),
|
|
218
|
+
bgHover: ColorPicker.hex('blue-700'),
|
|
219
|
+
text: ColorPicker.rgb('white'),
|
|
220
|
+
},
|
|
221
|
+
secondary: {
|
|
222
|
+
bg: ColorPicker.hex('slate-600'),
|
|
223
|
+
bgHover: ColorPicker.hex('slate-700'),
|
|
224
|
+
text: ColorPicker.rgb('slate-100'),
|
|
225
|
+
},
|
|
226
|
+
danger: {
|
|
227
|
+
bg: ColorPicker.hex('red-600'),
|
|
228
|
+
bgHover: ColorPicker.hex('red-700'),
|
|
229
|
+
text: ColorPicker.rgb('white'),
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
const style = colors[variant];
|
|
234
|
+
|
|
235
|
+
// Background
|
|
236
|
+
this.background = scene.add
|
|
237
|
+
.rectangle(x, y, 200, 50, style.bg)
|
|
238
|
+
.setInteractive()
|
|
239
|
+
.on('pointerover', () => this.background.setFillStyle(style.bgHover))
|
|
240
|
+
.on('pointerout', () => this.background.setFillStyle(style.bg));
|
|
241
|
+
|
|
242
|
+
// Text
|
|
243
|
+
this.text = scene.add
|
|
244
|
+
.text(x, y, text, {
|
|
245
|
+
fontSize: FontSizePicker.css('lg'),
|
|
246
|
+
fill: style.text,
|
|
247
|
+
})
|
|
248
|
+
.setOrigin(0.5);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Usage
|
|
253
|
+
const playButton = new GameButton(this, 400, 200, 'PLAY', 'primary');
|
|
254
|
+
const settingsButton = new GameButton(this, 400, 280, 'SETTINGS', 'secondary');
|
|
255
|
+
const quitButton = new GameButton(this, 400, 360, 'QUIT', 'danger');
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Particle Effects with Color Harmony
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
// Create harmonious particle effects
|
|
262
|
+
this.add.particles(player.x, player.y, 'sparkle', {
|
|
263
|
+
speed: { min: 50, max: 100 },
|
|
264
|
+
tint: [
|
|
265
|
+
ColorPicker.hex('blue-400'),
|
|
266
|
+
ColorPicker.hex('blue-500'),
|
|
267
|
+
ColorPicker.hex('blue-600'),
|
|
268
|
+
ColorPicker.hex('cyan-400'),
|
|
269
|
+
ColorPicker.hex('cyan-500'),
|
|
270
|
+
],
|
|
271
|
+
lifespan: 1000,
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## 🎮 Integration with Phaser
|
|
278
|
+
|
|
279
|
+
### Scene Setup
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
import { ColorPicker, FontSizePicker } from 'phaser-wind';
|
|
283
|
+
|
|
284
|
+
export class MenuScene extends Phaser.Scene {
|
|
285
|
+
constructor() {
|
|
286
|
+
super({ key: 'MenuScene' });
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
create() {
|
|
290
|
+
// Background gradient effect
|
|
291
|
+
const bg = this.add.graphics();
|
|
292
|
+
bg.fillGradientStyle(
|
|
293
|
+
ColorPicker.hex('slate-900'), // top-left
|
|
294
|
+
ColorPicker.hex('slate-800'), // top-right
|
|
295
|
+
ColorPicker.hex('slate-800'), // bottom-left
|
|
296
|
+
ColorPicker.hex('slate-700') // bottom-right
|
|
297
|
+
);
|
|
298
|
+
bg.fillRect(0, 0, this.cameras.main.width, this.cameras.main.height);
|
|
299
|
+
|
|
300
|
+
// Consistent UI elements
|
|
301
|
+
this.createTitle();
|
|
302
|
+
this.createMenu();
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
private createTitle() {
|
|
306
|
+
this.add
|
|
307
|
+
.text(this.cameras.main.centerX, 150, 'MY AWESOME GAME', {
|
|
308
|
+
fontSize: FontSizePicker.css('4xl'),
|
|
309
|
+
fill: ColorPicker.rgb('yellow-400'),
|
|
310
|
+
stroke: ColorPicker.rgb('yellow-700'),
|
|
311
|
+
strokeThickness: 3,
|
|
312
|
+
})
|
|
313
|
+
.setOrigin(0.5);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
private createMenu() {
|
|
317
|
+
const menuItems = ['Play', 'Options', 'Credits', 'Quit'];
|
|
318
|
+
|
|
319
|
+
menuItems.forEach((item, index) => {
|
|
320
|
+
this.add
|
|
321
|
+
.text(this.cameras.main.centerX, 250 + index * 60, item, {
|
|
322
|
+
fontSize: FontSizePicker.css('xl'),
|
|
323
|
+
fill: ColorPicker.rgb('slate-300'),
|
|
324
|
+
})
|
|
325
|
+
.setOrigin(0.5)
|
|
326
|
+
.setInteractive()
|
|
327
|
+
.on('pointerover', function () {
|
|
328
|
+
this.setTint(ColorPicker.hex('yellow-400'));
|
|
329
|
+
})
|
|
330
|
+
.on('pointerout', function () {
|
|
331
|
+
this.clearTint();
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## 🔧 Advanced Usage
|
|
341
|
+
|
|
342
|
+
### Custom Color Schemes
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
// Create consistent themes
|
|
346
|
+
const darkTheme = {
|
|
347
|
+
background: ColorPicker.hex('slate-900'),
|
|
348
|
+
surface: ColorPicker.hex('slate-800'),
|
|
349
|
+
primary: ColorPicker.hex('blue-500'),
|
|
350
|
+
secondary: ColorPicker.hex('slate-600'),
|
|
351
|
+
text: ColorPicker.rgb('slate-100'),
|
|
352
|
+
textMuted: ColorPicker.rgb('slate-400'),
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
const lightTheme = {
|
|
356
|
+
background: ColorPicker.hex('slate-50'),
|
|
357
|
+
surface: ColorPicker.hex('white'),
|
|
358
|
+
primary: ColorPicker.hex('blue-600'),
|
|
359
|
+
secondary: ColorPicker.hex('slate-200'),
|
|
360
|
+
text: ColorPicker.rgb('slate-900'),
|
|
361
|
+
textMuted: ColorPicker.rgb('slate-600'),
|
|
362
|
+
};
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Responsive Text Sizing
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
// Scale text based on screen size
|
|
369
|
+
const getResponsiveTextSize = (baseSize: FontSizeKey): string => {
|
|
370
|
+
const scale = this.cameras.main.width / 1920; // Base on 1920px width
|
|
371
|
+
const basePixels = FontSizePicker.px(baseSize);
|
|
372
|
+
return `${Math.round(basePixels * scale)}px`;
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
this.add.text(x, y, 'Responsive Text', {
|
|
376
|
+
fontSize: getResponsiveTextSize('2xl'),
|
|
377
|
+
fill: ColorPicker.rgb('blue-500'),
|
|
378
|
+
});
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## 🤝 Why "Wind" instead of "Tailwind"?
|
|
384
|
+
|
|
385
|
+
We love Tailwind CSS, but we're not affiliated with them. "Phaser Wind" captures the essence:
|
|
386
|
+
|
|
387
|
+
- **Wind** = Fast, natural, refreshing (like your development experience)
|
|
388
|
+
- **Wind** = Carries things forward (like your game development)
|
|
389
|
+
- **Wind** = Invisible but powerful (like good design tokens)
|
|
390
|
+
|
|
391
|
+
Plus, `phaser-wind` is way easier to type than `phaser-tailwind-css-design-tokens-for-games` 😉
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## 📚 Compared to Raw Phaser
|
|
396
|
+
|
|
397
|
+
| Without Phaser Wind | With Phaser Wind |
|
|
398
|
+
| ------------------------ | ------------------------------------ |
|
|
399
|
+
| `fill: '#3B82F6'` | `fill: ColorPicker.rgb('blue-500')` |
|
|
400
|
+
| `fontSize: '18px'` | `fontSize: FontSizePicker.css('lg')` |
|
|
401
|
+
| `tint: 0x4ADE80` | `tint: ColorPicker.hex('green-400')` |
|
|
402
|
+
| Magic numbers everywhere | Semantic, consistent tokens |
|
|
403
|
+
| Color picking hell | Harmonious color palettes |
|
|
404
|
+
| Inconsistent sizing | Perfect typography scale |
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## 🔮 Coming Soon
|
|
409
|
+
|
|
410
|
+
- 🎯 **Spacing System** - Consistent margins and padding tokens
|
|
411
|
+
- 📐 **Layout Utilities** - Flexbox-inspired alignment helpers
|
|
412
|
+
- 🎨 **Theme System** - Easy dark/light mode switching
|
|
413
|
+
- 📱 **Responsive Utilities** - Breakpoint-based design tokens
|
|
414
|
+
- ⚡ **Animation Presets** - Smooth, consistent transitions
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
## 🤝 Contributing
|
|
419
|
+
|
|
420
|
+
We'd love your help making Phaser Wind even better!
|
|
421
|
+
|
|
422
|
+
1. Fork the repository
|
|
423
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
424
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
425
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
426
|
+
5. Open a Pull Request
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## 📄 License
|
|
431
|
+
|
|
432
|
+
MIT © [CassinoDev](https://github.com/cassinodev)
|
|
433
|
+
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
## 🌟 Show Your Support
|
|
437
|
+
|
|
438
|
+
If Phaser Wind makes your game development life better, give us a ⭐ on GitHub!
|
|
439
|
+
|
|
440
|
+
**Happy Gaming!** 🎮✨
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
> _"Making Phaser development as enjoyable as Tailwind CSS"_
|
|
445
|
+
>
|
|
446
|
+
> — The Phaser Wind Team
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { pallete } from './pallete';
|
|
2
|
+
export type ColorKey = keyof typeof pallete;
|
|
3
|
+
export type ShadeKey = '50' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' | '950';
|
|
4
|
+
export type ColorToken = `${ColorKey}-${ShadeKey}` | 'black' | 'white';
|
|
5
|
+
export declare class ColorPicker {
|
|
6
|
+
private colorKey;
|
|
7
|
+
constructor(colorKey: ColorKey);
|
|
8
|
+
static rgb(color: ColorToken): string;
|
|
9
|
+
static hex(color: ColorToken): number;
|
|
10
|
+
getRgb(shade: ShadeKey): string;
|
|
11
|
+
getHex(shade: ShadeKey): number;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=color-picker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-picker.d.ts","sourceRoot":"","sources":["../../src/color/color-picker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,OAAO,CAAC;AAC5C,MAAM,MAAM,QAAQ,GAChB,IAAI,GACJ,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,CAAC;AACV,MAAM,MAAM,UAAU,GAAG,GAAG,QAAQ,IAAI,QAAQ,EAAE,GAAG,OAAO,GAAG,OAAO,CAAC;AAEvE,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ;gBAAR,QAAQ,EAAE,QAAQ;IAEtC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM;IAUrC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM;IAoBrC,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM;IAQ/B,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM;CAmBhC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/* eslint-disable no-magic-numbers */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
3
|
+
import { pallete } from './pallete';
|
|
4
|
+
export class ColorPicker {
|
|
5
|
+
colorKey;
|
|
6
|
+
constructor(colorKey) {
|
|
7
|
+
this.colorKey = colorKey;
|
|
8
|
+
}
|
|
9
|
+
static rgb(color) {
|
|
10
|
+
const parts = color.split('-');
|
|
11
|
+
if (parts.length === 2) {
|
|
12
|
+
const colorKey = parts[0];
|
|
13
|
+
const shade = parts[1];
|
|
14
|
+
return pallete[colorKey][shade];
|
|
15
|
+
}
|
|
16
|
+
return pallete[color];
|
|
17
|
+
}
|
|
18
|
+
static hex(color) {
|
|
19
|
+
const parts = color.split('-');
|
|
20
|
+
if (parts.length === 2) {
|
|
21
|
+
const colorKey = parts[0];
|
|
22
|
+
const shade = parts[1];
|
|
23
|
+
const colorPicker = new ColorPicker(colorKey);
|
|
24
|
+
return colorPicker.getHex(shade);
|
|
25
|
+
}
|
|
26
|
+
const colorToConvert = pallete[color];
|
|
27
|
+
// Handle 3-digit hex values like #fff by expanding them to 6 digits
|
|
28
|
+
const hex = colorToConvert.slice(1);
|
|
29
|
+
if (hex.length === 3) {
|
|
30
|
+
const r = parseInt(hex[0] + hex[0], 16);
|
|
31
|
+
const g = parseInt(hex[1] + hex[1], 16);
|
|
32
|
+
const b = parseInt(hex[2] + hex[2], 16);
|
|
33
|
+
return (r << 16) + (g << 8) + b;
|
|
34
|
+
}
|
|
35
|
+
return parseInt(hex, 16);
|
|
36
|
+
}
|
|
37
|
+
getRgb(shade) {
|
|
38
|
+
const color = pallete[this.colorKey];
|
|
39
|
+
if (typeof color === 'string') {
|
|
40
|
+
return color;
|
|
41
|
+
}
|
|
42
|
+
return color[shade];
|
|
43
|
+
}
|
|
44
|
+
getHex(shade) {
|
|
45
|
+
const rgb = this.getRgb(shade);
|
|
46
|
+
if (rgb.startsWith('#')) {
|
|
47
|
+
return parseInt(rgb.slice(1), 16);
|
|
48
|
+
}
|
|
49
|
+
// Extract RGB values from string like 'rgb(x, y, z)'
|
|
50
|
+
const matches = rgb.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
|
|
51
|
+
if (!matches) {
|
|
52
|
+
throw new Error(`Invalid RGB format: ${rgb}`);
|
|
53
|
+
}
|
|
54
|
+
const r = parseInt(matches[1]);
|
|
55
|
+
const g = parseInt(matches[2]);
|
|
56
|
+
const b = parseInt(matches[3]);
|
|
57
|
+
// Convert to hex number format 0xRRGGBB
|
|
58
|
+
return (r << 16) + (g << 8) + b;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=color-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-picker.js","sourceRoot":"","sources":["../../src/color/color-picker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-picker.spec.d.ts","sourceRoot":"","sources":["../../src/color/color-picker.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/* eslint-disable no-magic-numbers */
|
|
2
|
+
/* eslint-disable max-lines-per-function */
|
|
3
|
+
import { describe, expect, it } from 'vitest';
|
|
4
|
+
import { ColorPicker } from './color-picker';
|
|
5
|
+
describe('ColorPicker', () => {
|
|
6
|
+
it('should get the correct hex value for a shade', () => {
|
|
7
|
+
const colorPicker = new ColorPicker('slate');
|
|
8
|
+
expect(colorPicker.getHex('50')).toBe(0xf8fafc);
|
|
9
|
+
});
|
|
10
|
+
it.each([
|
|
11
|
+
['slate', '50', 0xf8fafc],
|
|
12
|
+
['slate', '900', 0x0f172a],
|
|
13
|
+
['rose', '500', 0xf43f5e],
|
|
14
|
+
['fuchsia', '400', 0xe879f9],
|
|
15
|
+
['zinc', '200', 0xe4e4e7],
|
|
16
|
+
['gray', '600', 0x4b5563],
|
|
17
|
+
['pink', '300', 0xf9a8d4],
|
|
18
|
+
['stone', '700', 0x44403c],
|
|
19
|
+
])('should convert %s-%s to hex %s', (color, shade, expected) => {
|
|
20
|
+
const colorPicker = new ColorPicker(color);
|
|
21
|
+
expect(colorPicker.getHex(shade)).toBe(expected);
|
|
22
|
+
});
|
|
23
|
+
it('should convert color token to rgb using static method', () => {
|
|
24
|
+
expect(ColorPicker.rgb('slate-50')).toBe('rgb(248, 250, 252)');
|
|
25
|
+
expect(ColorPicker.rgb('black')).toBe('#000');
|
|
26
|
+
expect(ColorPicker.rgb('white')).toBe('#fff');
|
|
27
|
+
});
|
|
28
|
+
it('should convert color token to hex using static method', () => {
|
|
29
|
+
expect(ColorPicker.hex('slate-50')).toBe(0xf8fafc);
|
|
30
|
+
expect(ColorPicker.hex('black')).toBe(0x000000);
|
|
31
|
+
expect(ColorPicker.hex('white')).toBe(0xffffff);
|
|
32
|
+
expect(ColorPicker.hex('slate-900')).toBe(0x0f172a);
|
|
33
|
+
expect(ColorPicker.hex('slate-500')).toBe(0x64748b);
|
|
34
|
+
expect(ColorPicker.hex('slate-200')).toBe(0xe2e8f0);
|
|
35
|
+
expect(ColorPicker.hex('slate-100')).toBe(0xf1f5f9);
|
|
36
|
+
expect(ColorPicker.hex('slate-50')).toBe(0xf8fafc);
|
|
37
|
+
expect(ColorPicker.hex('slate-950')).toBe(0x020617);
|
|
38
|
+
expect(ColorPicker.hex('slate-800')).toBe(0x1e293b);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=color-picker.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-picker.spec.js","sourceRoot":"","sources":["../../src/color/color-picker.spec.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,2CAA2C;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAgC,MAAM,gBAAgB,CAAC;AAE3E,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC;QACN,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC;QACzB,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC;QAC1B,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC;QACzB,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,CAAC;QAC5B,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC;QACzB,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC;QACzB,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC;QACzB,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC;KAC3B,CAAC,CAAC,gCAAgC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;QAC9D,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,KAAiB,CAAC,CAAC;QACvD,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAC/D,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9C,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/color/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/color/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC"}
|