phaser-wind 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +243 -215
- package/dist/components/column.d.ts +1 -0
- package/dist/components/column.d.ts.map +1 -0
- package/dist/components/column.js +7 -0
- package/dist/components/column.js.map +1 -0
- package/dist/core/color.d.ts +154 -0
- package/dist/core/color.d.ts.map +1 -0
- package/dist/core/color.js +205 -0
- package/dist/core/color.js.map +1 -0
- package/dist/core/color.spec.d.ts +2 -0
- package/dist/core/color.spec.d.ts.map +1 -0
- package/dist/core/color.spec.js +243 -0
- package/dist/core/color.spec.js.map +1 -0
- package/dist/core/font-size.d.ts +55 -0
- package/dist/core/font-size.d.ts.map +1 -0
- package/dist/core/font-size.js +63 -0
- package/dist/core/font-size.js.map +1 -0
- package/dist/core/font-size.spec.d.ts +2 -0
- package/dist/core/font-size.spec.d.ts.map +1 -0
- package/dist/core/font-size.spec.js +85 -0
- package/dist/core/font-size.spec.js.map +1 -0
- package/dist/core/font.d.ts +21 -0
- package/dist/core/font.d.ts.map +1 -0
- package/dist/core/font.js +37 -0
- package/dist/core/font.js.map +1 -0
- package/dist/core/font.spec.d.ts +2 -0
- package/dist/core/font.spec.d.ts.map +1 -0
- package/dist/core/font.spec.js +80 -0
- package/dist/core/font.spec.js.map +1 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +8 -0
- package/dist/core/index.js.map +1 -0
- package/dist/{color/pallete.d.ts → core/palette.d.ts} +2 -2
- package/dist/core/palette.d.ts.map +1 -0
- package/dist/{color/pallete.js → core/palette.js} +2 -2
- package/dist/core/palette.js.map +1 -0
- package/dist/core/radius.d.ts +29 -0
- package/dist/core/radius.d.ts.map +1 -0
- package/dist/core/radius.js +38 -0
- package/dist/core/radius.js.map +1 -0
- package/dist/core/radius.spec.d.ts +2 -0
- package/dist/core/radius.spec.d.ts.map +1 -0
- package/dist/core/radius.spec.js +56 -0
- package/dist/core/radius.spec.js.map +1 -0
- package/dist/core/shadow.d.ts +31 -0
- package/dist/core/shadow.d.ts.map +1 -0
- package/dist/core/shadow.js +33 -0
- package/dist/core/shadow.js.map +1 -0
- package/dist/core/shadow.spec.d.ts +2 -0
- package/dist/core/shadow.spec.d.ts.map +1 -0
- package/dist/core/shadow.spec.js +21 -0
- package/dist/core/shadow.spec.js.map +1 -0
- package/dist/core/spacing.d.ts +32 -0
- package/dist/core/spacing.d.ts.map +1 -0
- package/dist/core/spacing.js +70 -0
- package/dist/core/spacing.js.map +1 -0
- package/dist/core/spacing.spec.d.ts +2 -0
- package/dist/core/spacing.spec.d.ts.map +1 -0
- package/dist/core/spacing.spec.js +38 -0
- package/dist/core/spacing.spec.js.map +1 -0
- package/dist/exceptions.d.ts +1 -0
- package/dist/exceptions.d.ts.map +1 -0
- package/dist/exceptions.js +2 -0
- package/dist/exceptions.js.map +1 -0
- package/dist/font/index.d.ts +2 -2
- package/dist/font/index.d.ts.map +1 -1
- package/dist/font/index.js +2 -2
- package/dist/font/index.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/plugin/index.d.ts +2 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +2 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/plugin.d.ts +71 -0
- package/dist/plugin/plugin.d.ts.map +1 -0
- package/dist/plugin/plugin.js +91 -0
- package/dist/plugin/plugin.js.map +1 -0
- package/dist/theme/theme-config.d.ts +44 -132
- package/dist/theme/theme-config.d.ts.map +1 -1
- package/dist/theme/theme-config.js +15 -52
- package/dist/theme/theme-config.js.map +1 -1
- package/dist/theme/theme-manager.d.ts +2 -95
- package/dist/theme/theme-manager.d.ts.map +1 -1
- package/dist/theme/theme-manager.js +3 -170
- package/dist/theme/theme-manager.js.map +1 -1
- package/dist/theme/type.d.ts +48 -0
- package/dist/theme/type.d.ts.map +1 -1
- package/dist/theme/type.js +1 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/is-valid-color.d.ts +13 -0
- package/dist/utils/is-valid-color.d.ts.map +1 -0
- package/dist/utils/is-valid-color.js +32 -0
- package/dist/utils/is-valid-color.js.map +1 -0
- package/dist/utils/is-valid-color.spec.d.ts +2 -0
- package/dist/utils/is-valid-color.spec.d.ts.map +1 -0
- package/dist/utils/is-valid-color.spec.js +82 -0
- package/dist/utils/is-valid-color.spec.js.map +1 -0
- package/package.json +6 -4
- package/dist/color/color-picker.d.ts +0 -23
- package/dist/color/color-picker.d.ts.map +0 -1
- package/dist/color/color-picker.js +0 -118
- package/dist/color/color-picker.js.map +0 -1
- package/dist/color/color-picker.spec.d.ts +0 -2
- package/dist/color/color-picker.spec.d.ts.map +0 -1
- package/dist/color/color-picker.spec.js +0 -60
- package/dist/color/color-picker.spec.js.map +0 -1
- package/dist/color/index.d.ts +0 -3
- package/dist/color/index.d.ts.map +0 -1
- package/dist/color/index.js +0 -3
- package/dist/color/index.js.map +0 -1
- package/dist/color/pallete.d.ts.map +0 -1
- package/dist/color/pallete.js.map +0 -1
- package/dist/examples/nested-theme-example.d.ts +0 -28
- package/dist/examples/nested-theme-example.d.ts.map +0 -1
- package/dist/examples/nested-theme-example.js +0 -313
- package/dist/examples/nested-theme-example.js.map +0 -1
- package/dist/examples/usage-example.d.ts +0 -17
- package/dist/examples/usage-example.d.ts.map +0 -1
- package/dist/examples/usage-example.js +0 -158
- package/dist/examples/usage-example.js.map +0 -1
- package/dist/font/font-picker.d.ts +0 -93
- package/dist/font/font-picker.d.ts.map +0 -1
- package/dist/font/font-picker.js +0 -212
- package/dist/font/font-picker.js.map +0 -1
- package/dist/font/font-size-picker.d.ts +0 -19
- package/dist/font/font-size-picker.d.ts.map +0 -1
- package/dist/font/font-size-picker.js +0 -24
- package/dist/font/font-size-picker.js.map +0 -1
- package/dist/font/font-size-picker.spec.d.ts +0 -2
- package/dist/font/font-size-picker.spec.d.ts.map +0 -1
- package/dist/font/font-size-picker.spec.js +0 -48
- package/dist/font/font-size-picker.spec.js.map +0 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
>
|
|
9
9
|
> **Love Tailwind CSS but stuck with Phaser?**
|
|
10
10
|
>
|
|
11
|
-
> **Welcome to Phaser Wind** -
|
|
11
|
+
> **Welcome to Phaser Wind** - bring the joy and simplicity of Tailwind-like design tokens to Phaser games! 🎮✨
|
|
12
12
|
|
|
13
13
|
[](https://www.npmjs.com/package/phaser-wind)
|
|
14
14
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -37,18 +37,19 @@ const title = this.add.text(200, 100, 'Game Title', {
|
|
|
37
37
|
### The Solution 🌟
|
|
38
38
|
|
|
39
39
|
```typescript
|
|
40
|
-
|
|
40
|
+
// No theme needed. Just import and go!
|
|
41
|
+
import { Color, FontSize } from 'phaser-wind';
|
|
41
42
|
|
|
42
43
|
// Clean, semantic, consistent!
|
|
43
44
|
const button = this.add.text(100, 50, 'Click me!', {
|
|
44
|
-
fontSize:
|
|
45
|
-
fill:
|
|
46
|
-
backgroundColor:
|
|
45
|
+
fontSize: FontSize.css('lg'), // Clear intention!
|
|
46
|
+
fill: Color.rgb('blue-500'), // Beautiful blue
|
|
47
|
+
backgroundColor: Color.rgb('gray-800'), // Perfect contrast
|
|
47
48
|
});
|
|
48
49
|
|
|
49
50
|
const title = this.add.text(200, 100, 'Game Title', {
|
|
50
|
-
fontSize:
|
|
51
|
-
fill:
|
|
51
|
+
fontSize: FontSize.css('3xl'), // Clearly bigger!
|
|
52
|
+
fill: Color.rgb('red-500'), // Vibrant red
|
|
52
53
|
});
|
|
53
54
|
```
|
|
54
55
|
|
|
@@ -56,15 +57,14 @@ const title = this.add.text(200, 100, 'Game Title', {
|
|
|
56
57
|
|
|
57
58
|
## 🚀 Features
|
|
58
59
|
|
|
59
|
-
- 🎨 **Complete Tailwind Color Palette** -
|
|
60
|
-
- 📐 **Semantic Font Sizes** - From `xs` to `6xl
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
- 🎯 **Smart Token Resolution** - Themes can reference other theme tokens automatically
|
|
60
|
+
- 🎨 **Complete Tailwind-like Color Palette** - 22 families × 11 shades
|
|
61
|
+
- 📐 **Semantic Font Sizes** - From `xs` to `6xl`
|
|
62
|
+
- 🧩 **Default constants ready-to-use** - `Color`, `FontSize`, `Spacing`, `Radius`, `Shadow`
|
|
63
|
+
- 🧭 **Optional theme system (typed)** - Add your own tokens with strong typing
|
|
64
64
|
- 🔧 **TypeScript First** - Full type safety and IntelliSense
|
|
65
|
-
- 🎮 **Phaser Ready** -
|
|
65
|
+
- 🎮 **Phaser Ready** - Global plugin for easy access in scenes
|
|
66
66
|
- 🌈 **Consistent Design** - No more guessing colors and sizes
|
|
67
|
-
- 📦 **Tiny Bundle** -
|
|
67
|
+
- 📦 **Tiny Bundle** - Great DX, minimal overhead
|
|
68
68
|
|
|
69
69
|
---
|
|
70
70
|
|
|
@@ -80,26 +80,26 @@ pnpm add phaser-wind
|
|
|
80
80
|
|
|
81
81
|
---
|
|
82
82
|
|
|
83
|
-
## 🎨 Color System
|
|
83
|
+
## 🎨 Color System (no theme)
|
|
84
84
|
|
|
85
|
-
### Complete
|
|
85
|
+
### Complete Palette
|
|
86
86
|
|
|
87
87
|
Access all Tailwind colors with semantic naming:
|
|
88
88
|
|
|
89
89
|
```typescript
|
|
90
|
-
import {
|
|
90
|
+
import { Color } from 'phaser-wind';
|
|
91
91
|
|
|
92
92
|
// RGB strings (for Phaser text styles)
|
|
93
|
-
const blueText =
|
|
94
|
-
const redButton =
|
|
93
|
+
const blueText = Color.rgb('blue-500'); // 'rgb(59, 130, 246)'
|
|
94
|
+
const redButton = Color.rgb('red-600'); // 'rgb(220, 38, 38)'
|
|
95
95
|
|
|
96
96
|
// Hex numbers (for Phaser graphics)
|
|
97
|
-
const greenRect =
|
|
98
|
-
const purpleCircle =
|
|
97
|
+
const greenRect = Color.hex('green-400'); // 0x4ADE80
|
|
98
|
+
const purpleCircle = Color.hex('purple-300'); // 0xD8B4FE
|
|
99
99
|
|
|
100
100
|
// Basic colors
|
|
101
|
-
const blackText =
|
|
102
|
-
const whiteBackground =
|
|
101
|
+
const blackText = Color.rgb('black'); // 'rgb(0, 0, 0)'
|
|
102
|
+
const whiteBackground = Color.hex('white'); // 0xFFFFFF
|
|
103
103
|
```
|
|
104
104
|
|
|
105
105
|
### Available Colors
|
|
@@ -110,185 +110,217 @@ const whiteBackground = ColorPicker.hex('white'); // 0xFFFFFF
|
|
|
110
110
|
|
|
111
111
|
---
|
|
112
112
|
|
|
113
|
-
## 📏 Font Size System
|
|
113
|
+
## 📏 Font Size System (no theme)
|
|
114
114
|
|
|
115
115
|
### Semantic Sizing
|
|
116
116
|
|
|
117
117
|
Stop guessing font sizes and use semantic tokens:
|
|
118
118
|
|
|
119
119
|
```typescript
|
|
120
|
-
import {
|
|
120
|
+
import { FontSize } from 'phaser-wind';
|
|
121
121
|
|
|
122
122
|
// Get pixel values
|
|
123
|
-
const smallText =
|
|
124
|
-
const normalText =
|
|
125
|
-
const largeTitle =
|
|
123
|
+
const smallText = FontSize.px('sm'); // 14
|
|
124
|
+
const normalText = FontSize.px('base'); // 16
|
|
125
|
+
const largeTitle = FontSize.px('3xl'); // 30
|
|
126
126
|
|
|
127
127
|
// Get CSS strings (perfect for Phaser)
|
|
128
|
-
const buttonText =
|
|
129
|
-
const heroTitle =
|
|
128
|
+
const buttonText = FontSize.css('lg'); // '18px'
|
|
129
|
+
const heroTitle = FontSize.css('6xl'); // '60px'
|
|
130
130
|
|
|
131
131
|
// Get rem values (if needed)
|
|
132
|
-
const responsiveText =
|
|
132
|
+
const responsiveText = FontSize.rem('xl'); // 1.25
|
|
133
133
|
```
|
|
134
134
|
|
|
135
135
|
### Font Size Scale
|
|
136
136
|
|
|
137
|
-
| Token
|
|
138
|
-
|
|
|
139
|
-
| `xs`
|
|
140
|
-
| `sm`
|
|
141
|
-
| `
|
|
142
|
-
| `lg`
|
|
143
|
-
| `xl`
|
|
144
|
-
| `2xl`
|
|
145
|
-
| `3xl`
|
|
146
|
-
| `4xl`
|
|
147
|
-
| `5xl`
|
|
148
|
-
| `6xl`
|
|
137
|
+
| Token | Pixels | Use Case |
|
|
138
|
+
| ------ | ------ | ----------------------- |
|
|
139
|
+
| `xs` | 12px | Small labels, captions |
|
|
140
|
+
| `sm` | 14px | Body text, descriptions |
|
|
141
|
+
| `base` | 16px | Default text size |
|
|
142
|
+
| `lg` | 18px | Slightly larger text |
|
|
143
|
+
| `xl` | 20px | Subheadings |
|
|
144
|
+
| `2xl` | 24px | Headings |
|
|
145
|
+
| `3xl` | 30px | Large headings |
|
|
146
|
+
| `4xl` | 36px | Hero text |
|
|
147
|
+
| `5xl` | 48px | Display text |
|
|
148
|
+
| `6xl` | 60px | Giant display text |
|
|
149
149
|
|
|
150
150
|
---
|
|
151
151
|
|
|
152
|
-
##
|
|
152
|
+
## 🧪 Strong typing (no theme)
|
|
153
153
|
|
|
154
|
-
|
|
154
|
+
All APIs are strongly typed. Invalid tokens break at compile time:
|
|
155
155
|
|
|
156
|
-
|
|
156
|
+
```ts
|
|
157
|
+
import { Color, FontSize, Spacing, Radius, Shadow } from 'phaser-wind';
|
|
157
158
|
|
|
158
|
-
|
|
159
|
-
|
|
159
|
+
// ✅ OK
|
|
160
|
+
Color.rgb('blue-500');
|
|
161
|
+
FontSize.css('lg');
|
|
162
|
+
Spacing.px('16');
|
|
163
|
+
Radius.css('sm');
|
|
164
|
+
Shadow.get('md');
|
|
165
|
+
|
|
166
|
+
// ❌ Compile-time errors
|
|
167
|
+
// Color.rgb('blue-501');
|
|
168
|
+
// FontSize.css('huge');
|
|
169
|
+
// Spacing.px('97');
|
|
170
|
+
// Radius.css('xxl');
|
|
171
|
+
// Shadow.get('mega');
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## 🧱 Token Reference
|
|
177
|
+
|
|
178
|
+
### Colors
|
|
179
|
+
|
|
180
|
+
- Families: `slate`, `gray`, `zinc`, `neutral`, `stone`, `red`, `orange`, `amber`, `yellow`, `lime`, `green`, `emerald`, `teal`, `cyan`, `sky`, `blue`, `indigo`, `violet`, `purple`, `fuchsia`, `pink`, `rose`
|
|
181
|
+
- Shades: `50`, `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`, `950`
|
|
182
|
+
- Special: `black`, `white`
|
|
183
|
+
|
|
184
|
+
### Font Size
|
|
185
|
+
|
|
186
|
+
- Keys: `xs`, `sm`, `base`, `lg`, `xl`, `2xl`, `3xl`, `4xl`, `5xl`, `6xl`
|
|
187
|
+
|
|
188
|
+
### Spacing
|
|
189
|
+
|
|
190
|
+
- Keys (px scale ×4): `0`, `px(=1)`, `0.5`, `1`, `1.5`, `2`, `2.5`, `3`, `3.5`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `14`, `16`, `20`, `24`, `28`, `32`, `36`, `40`, `44`, `48`, `52`, `56`, `60`, `64`, `72`, `80`, `96`
|
|
191
|
+
|
|
192
|
+
### Radius
|
|
160
193
|
|
|
161
|
-
|
|
194
|
+
- Keys: `none`, `sm`, `default`, `md`, `lg`, `xl`, `2xl`, `3xl`, `full`
|
|
195
|
+
|
|
196
|
+
### Shadow
|
|
197
|
+
|
|
198
|
+
- Default keys: `sm`, `md`, `lg`, `xl`, `2xl`, `inner`
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## 🎨 Theming (optional, typed)
|
|
203
|
+
|
|
204
|
+
Phaser Wind also provides a typed theme system via a Phaser plugin. You get the same API surface (`color`, `fontSize`, `spacing`, `radius`, `font`, `shadow`) but narrowed to your custom tokens.
|
|
205
|
+
|
|
206
|
+
### 1) Create a theme
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
import { createTheme, type CreateTheme } from 'phaser-wind';
|
|
210
|
+
|
|
211
|
+
export const theme = createTheme({
|
|
162
212
|
fonts: {
|
|
163
213
|
primary: 'Inter, system-ui, sans-serif',
|
|
164
|
-
display: 'Orbitron, monospace',
|
|
165
|
-
|
|
214
|
+
display: 'Orbitron, monospace',
|
|
215
|
+
},
|
|
216
|
+
fontSizes: {
|
|
217
|
+
// optional overrides
|
|
166
218
|
},
|
|
167
219
|
colors: {
|
|
168
|
-
primary: '
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
'player-health': 'green-500',
|
|
172
|
-
'enemy-health': 'red-600',
|
|
220
|
+
primary: 'blue-600',
|
|
221
|
+
background: 'slate-900',
|
|
222
|
+
danger: 'red-500',
|
|
173
223
|
},
|
|
174
224
|
spacing: {
|
|
175
|
-
|
|
176
|
-
sm: 8,
|
|
177
|
-
md: 16,
|
|
178
|
-
lg: 24,
|
|
179
|
-
xl: 32,
|
|
225
|
+
gutter: 24,
|
|
180
226
|
},
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
fontSize: '2xl',
|
|
184
|
-
fontFamily: 'fonts.display', // 🔗 References fonts.display!
|
|
185
|
-
fontWeight: 600,
|
|
186
|
-
lineHeight: 1.2,
|
|
187
|
-
},
|
|
188
|
-
body: {
|
|
189
|
-
fontSize: 'md',
|
|
190
|
-
fontFamily: 'fonts.primary',
|
|
191
|
-
fontWeight: 400,
|
|
192
|
-
lineHeight: 1.5,
|
|
193
|
-
},
|
|
227
|
+
radius: {
|
|
228
|
+
card: 12,
|
|
194
229
|
},
|
|
195
230
|
effects: {
|
|
196
|
-
|
|
197
|
-
blur: 8,
|
|
198
|
-
color: 'colors.primary', // 🔗 References colors.primary!
|
|
199
|
-
alpha: 0.6,
|
|
200
|
-
},
|
|
231
|
+
glow: { blur: 8, offsetX: 0, offsetY: 0, alpha: 0.6 },
|
|
201
232
|
},
|
|
202
|
-
|
|
203
|
-
animations: {
|
|
204
|
-
duration: 300,
|
|
205
|
-
easing: 'ease-out',
|
|
206
|
-
},
|
|
207
|
-
});
|
|
233
|
+
} satisfies CreateTheme<any>);
|
|
208
234
|
|
|
209
|
-
|
|
210
|
-
ThemeManager.init(gameTheme);
|
|
235
|
+
export type ThemeType = typeof theme;
|
|
211
236
|
```
|
|
212
237
|
|
|
213
|
-
###
|
|
238
|
+
### 2) Install the plugin in Phaser
|
|
214
239
|
|
|
215
|
-
```
|
|
240
|
+
```ts
|
|
216
241
|
import {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
TypographyPicker,
|
|
221
|
-
EffectPicker,
|
|
242
|
+
PhaserWindPlugin,
|
|
243
|
+
PHASER_WIND_KEY,
|
|
244
|
+
defaultLightTheme,
|
|
222
245
|
} from 'phaser-wind';
|
|
246
|
+
import { theme } from './theme';
|
|
247
|
+
|
|
248
|
+
new Phaser.Game({
|
|
249
|
+
plugins: {
|
|
250
|
+
global: [
|
|
251
|
+
{
|
|
252
|
+
key: PHASER_WIND_KEY,
|
|
253
|
+
plugin: PhaserWindPlugin,
|
|
254
|
+
mapping: PHASER_WIND_KEY, // scene.pw
|
|
255
|
+
data: { theme }, // or { theme: defaultLightTheme }
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
```
|
|
223
261
|
|
|
224
|
-
|
|
225
|
-
const primaryColor = ColorPicker.rgb('primary'); // Gets colors.primary
|
|
226
|
-
const uiBackground = ColorPicker.hex('ui-background'); // Gets colors.ui-background
|
|
227
|
-
|
|
228
|
-
// Fonts
|
|
229
|
-
const displayFont = FontPicker.family('display'); // Gets fonts.display
|
|
230
|
-
const primaryFont = FontPicker.family('primary'); // Gets fonts.primary
|
|
231
|
-
|
|
232
|
-
// Spacing
|
|
233
|
-
const mediumSpace = SpacingPicker.px('md'); // Gets spacing.md (16px)
|
|
234
|
-
const largeSpace = SpacingPicker.px('lg'); // Gets spacing.lg (24px)
|
|
235
|
-
|
|
236
|
-
// Complete typography styles
|
|
237
|
-
const headingStyle = TypographyPicker.phaserStyle('heading');
|
|
238
|
-
// Returns: { fontSize: '24px', fontFamily: 'Orbitron, monospace', fontStyle: 'bold' }
|
|
262
|
+
### 3) (Optional) Module augmentation for better typing in scenes
|
|
239
263
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
264
|
+
```ts
|
|
265
|
+
// types/phaser-wind.d.ts
|
|
266
|
+
import 'phaser';
|
|
267
|
+
import type { PhaserWindPlugin } from 'phaser-wind';
|
|
268
|
+
import type { ThemeType } from './theme';
|
|
243
269
|
|
|
244
|
-
|
|
245
|
-
|
|
270
|
+
declare module 'phaser' {
|
|
271
|
+
interface Scene {
|
|
272
|
+
pw: PhaserWindPlugin<ThemeType>;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
246
275
|
```
|
|
247
276
|
|
|
248
|
-
###
|
|
249
|
-
|
|
250
|
-
```typescript
|
|
251
|
-
// Register multiple themes
|
|
252
|
-
ThemeManager.registerTheme('light', lightTheme);
|
|
253
|
-
ThemeManager.registerTheme('dark', darkTheme);
|
|
254
|
-
ThemeManager.registerTheme('cyberpunk', cyberpunkTheme);
|
|
255
|
-
|
|
256
|
-
// Switch themes instantly
|
|
257
|
-
ThemeManager.setTheme('dark');
|
|
258
|
-
|
|
259
|
-
// Listen for theme changes
|
|
260
|
-
ThemeManager.onThemeChange(newTheme => {
|
|
261
|
-
console.log('Theme changed!', newTheme);
|
|
262
|
-
// Update your game UI here
|
|
263
|
-
});
|
|
277
|
+
### 4) Typed usage in scenes
|
|
264
278
|
|
|
265
|
-
|
|
266
|
-
|
|
279
|
+
```ts
|
|
280
|
+
export class GameScene extends Phaser.Scene {
|
|
281
|
+
create() {
|
|
282
|
+
const { color, fontSize, spacing, radius, font, shadow } = this.pw;
|
|
283
|
+
|
|
284
|
+
// ✅ Type-narrowed to your theme
|
|
285
|
+
color.rgb('primary');
|
|
286
|
+
fontSize.css('lg');
|
|
287
|
+
spacing.px('gutter');
|
|
288
|
+
radius.css('card');
|
|
289
|
+
font.family('display');
|
|
290
|
+
shadow.get('glow');
|
|
291
|
+
|
|
292
|
+
// ❌ Compile-time errors
|
|
293
|
+
// color.rgb('blue-501');
|
|
294
|
+
// spacing.px('unknown');
|
|
295
|
+
}
|
|
296
|
+
}
|
|
267
297
|
```
|
|
268
298
|
|
|
299
|
+
> Note: The old `ThemeManager` API is deprecated and has been removed from the docs.
|
|
300
|
+
|
|
269
301
|
### 🎮 **Real Game Example**
|
|
270
302
|
|
|
271
303
|
```typescript
|
|
272
304
|
export class GameScene extends Phaser.Scene {
|
|
273
305
|
create() {
|
|
274
306
|
// Player health bar with theme colors
|
|
275
|
-
const healthWidth =
|
|
276
|
-
const healthHeight =
|
|
307
|
+
const healthWidth = Spacing.px('24'); // 96px
|
|
308
|
+
const healthHeight = Spacing.px('4'); // 16px
|
|
277
309
|
|
|
278
310
|
this.add.rectangle(
|
|
279
311
|
50,
|
|
280
312
|
50,
|
|
281
313
|
healthWidth,
|
|
282
314
|
healthHeight,
|
|
283
|
-
|
|
315
|
+
Color.hex('player-health')
|
|
284
316
|
); // Green from theme
|
|
285
317
|
|
|
286
318
|
// Game title with theme typography
|
|
287
|
-
const titleStyle = TypographyPicker.phaserStyle('heading');
|
|
288
319
|
this.add
|
|
289
320
|
.text(400, 50, 'CYBER QUEST', {
|
|
290
|
-
|
|
291
|
-
|
|
321
|
+
fontSize: FontSize.css('4xl'),
|
|
322
|
+
fontFamily: Font.family('display'),
|
|
323
|
+
color: Color.rgb('primary'), // Purple from theme
|
|
292
324
|
})
|
|
293
325
|
.setOrigin(0.5);
|
|
294
326
|
|
|
@@ -297,8 +329,8 @@ export class GameScene extends Phaser.Scene {
|
|
|
297
329
|
400,
|
|
298
330
|
400,
|
|
299
331
|
'START GAME',
|
|
300
|
-
|
|
301
|
-
|
|
332
|
+
Spacing.px('16'), // 64px width
|
|
333
|
+
Spacing.px('6') // 24px height
|
|
302
334
|
);
|
|
303
335
|
}
|
|
304
336
|
|
|
@@ -310,20 +342,16 @@ export class GameScene extends Phaser.Scene {
|
|
|
310
342
|
height: number
|
|
311
343
|
) {
|
|
312
344
|
const button = this.add
|
|
313
|
-
.rectangle(x, y, width, height,
|
|
345
|
+
.rectangle(x, y, width, height, Color.hex('ui-background'))
|
|
314
346
|
.setInteractive()
|
|
315
|
-
.on('pointerover', () =>
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
.on('pointerout', () =>
|
|
319
|
-
button.setFillStyle(ColorPicker.hex('ui-background'))
|
|
320
|
-
);
|
|
321
|
-
|
|
322
|
-
const buttonText = TypographyPicker.phaserStyle('body');
|
|
347
|
+
.on('pointerover', () => button.setFillStyle(Color.hex('secondary')))
|
|
348
|
+
.on('pointerout', () => button.setFillStyle(Color.hex('ui-background')));
|
|
349
|
+
|
|
323
350
|
this.add
|
|
324
351
|
.text(x, y, text, {
|
|
325
|
-
|
|
326
|
-
|
|
352
|
+
fontSize: FontSize.css('base'),
|
|
353
|
+
fontFamily: Font.family('primary'),
|
|
354
|
+
color: Color.rgb('primary'),
|
|
327
355
|
})
|
|
328
356
|
.setOrigin(0.5);
|
|
329
357
|
}
|
|
@@ -382,50 +410,50 @@ const theme = createTheme({
|
|
|
382
410
|
### Game UI Components
|
|
383
411
|
|
|
384
412
|
```typescript
|
|
385
|
-
import {
|
|
413
|
+
import { Color, FontSize } from 'phaser-wind';
|
|
386
414
|
|
|
387
415
|
export class GameScene extends Phaser.Scene {
|
|
388
416
|
create() {
|
|
389
417
|
// Main title
|
|
390
418
|
this.add
|
|
391
419
|
.text(400, 100, 'SPACE RAIDERS', {
|
|
392
|
-
fontSize:
|
|
393
|
-
fill:
|
|
394
|
-
stroke:
|
|
420
|
+
fontSize: FontSize.css('5xl'),
|
|
421
|
+
fill: Color.rgb('yellow-400'),
|
|
422
|
+
stroke: Color.rgb('yellow-800'),
|
|
395
423
|
strokeThickness: 2,
|
|
396
424
|
})
|
|
397
425
|
.setOrigin(0.5);
|
|
398
426
|
|
|
399
427
|
// Score display
|
|
400
428
|
this.add.text(50, 50, 'Score: 12,500', {
|
|
401
|
-
fontSize:
|
|
402
|
-
fill:
|
|
429
|
+
fontSize: FontSize.css('xl'),
|
|
430
|
+
fill: Color.rgb('green-400'),
|
|
403
431
|
});
|
|
404
432
|
|
|
405
433
|
// Health bar background
|
|
406
434
|
const healthBg = this.add.graphics();
|
|
407
|
-
healthBg.fillStyle(
|
|
435
|
+
healthBg.fillStyle(Color.hex('red-900'));
|
|
408
436
|
healthBg.fillRect(50, 100, 200, 20);
|
|
409
437
|
|
|
410
438
|
// Health bar fill
|
|
411
439
|
const healthFill = this.add.graphics();
|
|
412
|
-
healthFill.fillStyle(
|
|
440
|
+
healthFill.fillStyle(Color.hex('red-500'));
|
|
413
441
|
healthFill.fillRect(52, 102, 156, 16); // 80% health
|
|
414
442
|
|
|
415
443
|
// Game over screen
|
|
416
|
-
this.add.rectangle(400, 300, 600, 400,
|
|
444
|
+
this.add.rectangle(400, 300, 600, 400, Color.hex('slate-900'), 0.9);
|
|
417
445
|
|
|
418
446
|
this.add
|
|
419
447
|
.text(400, 250, 'GAME OVER', {
|
|
420
|
-
fontSize:
|
|
421
|
-
fill:
|
|
448
|
+
fontSize: FontSize.css('4xl'),
|
|
449
|
+
fill: Color.rgb('red-500'),
|
|
422
450
|
})
|
|
423
451
|
.setOrigin(0.5);
|
|
424
452
|
|
|
425
453
|
this.add
|
|
426
454
|
.text(400, 320, 'Final Score: 12,500', {
|
|
427
|
-
fontSize:
|
|
428
|
-
fill:
|
|
455
|
+
fontSize: FontSize.css('2xl'),
|
|
456
|
+
fill: Color.rgb('slate-300'),
|
|
429
457
|
})
|
|
430
458
|
.setOrigin(0.5);
|
|
431
459
|
}
|
|
@@ -445,19 +473,19 @@ class GameButton {
|
|
|
445
473
|
) {
|
|
446
474
|
const colors = {
|
|
447
475
|
primary: {
|
|
448
|
-
bg:
|
|
449
|
-
bgHover:
|
|
450
|
-
text:
|
|
476
|
+
bg: Color.hex('blue-600'),
|
|
477
|
+
bgHover: Color.hex('blue-700'),
|
|
478
|
+
text: Color.rgb('white'),
|
|
451
479
|
},
|
|
452
480
|
secondary: {
|
|
453
|
-
bg:
|
|
454
|
-
bgHover:
|
|
455
|
-
text:
|
|
481
|
+
bg: Color.hex('slate-600'),
|
|
482
|
+
bgHover: Color.hex('slate-700'),
|
|
483
|
+
text: Color.rgb('slate-100'),
|
|
456
484
|
},
|
|
457
485
|
danger: {
|
|
458
|
-
bg:
|
|
459
|
-
bgHover:
|
|
460
|
-
text:
|
|
486
|
+
bg: Color.hex('red-600'),
|
|
487
|
+
bgHover: Color.hex('red-700'),
|
|
488
|
+
text: Color.rgb('white'),
|
|
461
489
|
},
|
|
462
490
|
};
|
|
463
491
|
|
|
@@ -473,7 +501,7 @@ class GameButton {
|
|
|
473
501
|
// Text
|
|
474
502
|
this.text = scene.add
|
|
475
503
|
.text(x, y, text, {
|
|
476
|
-
fontSize:
|
|
504
|
+
fontSize: FontSize.css('lg'),
|
|
477
505
|
fill: style.text,
|
|
478
506
|
})
|
|
479
507
|
.setOrigin(0.5);
|
|
@@ -493,11 +521,11 @@ const quitButton = new GameButton(this, 400, 360, 'QUIT', 'danger');
|
|
|
493
521
|
this.add.particles(player.x, player.y, 'sparkle', {
|
|
494
522
|
speed: { min: 50, max: 100 },
|
|
495
523
|
tint: [
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
524
|
+
Color.hex('blue-400'),
|
|
525
|
+
Color.hex('blue-500'),
|
|
526
|
+
Color.hex('blue-600'),
|
|
527
|
+
Color.hex('cyan-400'),
|
|
528
|
+
Color.hex('cyan-500'),
|
|
501
529
|
],
|
|
502
530
|
lifespan: 1000,
|
|
503
531
|
});
|
|
@@ -505,12 +533,12 @@ this.add.particles(player.x, player.y, 'sparkle', {
|
|
|
505
533
|
|
|
506
534
|
---
|
|
507
535
|
|
|
508
|
-
## 🎮 Integration with Phaser
|
|
536
|
+
## 🎮 Integration with Phaser (no theme)
|
|
509
537
|
|
|
510
538
|
### Scene Setup
|
|
511
539
|
|
|
512
540
|
```typescript
|
|
513
|
-
import {
|
|
541
|
+
import { Color, FontSize } from 'phaser-wind';
|
|
514
542
|
|
|
515
543
|
export class MenuScene extends Phaser.Scene {
|
|
516
544
|
constructor() {
|
|
@@ -521,10 +549,10 @@ export class MenuScene extends Phaser.Scene {
|
|
|
521
549
|
// Background gradient effect
|
|
522
550
|
const bg = this.add.graphics();
|
|
523
551
|
bg.fillGradientStyle(
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
552
|
+
Color.hex('slate-900'), // top-left
|
|
553
|
+
Color.hex('slate-800'), // top-right
|
|
554
|
+
Color.hex('slate-800'), // bottom-left
|
|
555
|
+
Color.hex('slate-700') // bottom-right
|
|
528
556
|
);
|
|
529
557
|
bg.fillRect(0, 0, this.cameras.main.width, this.cameras.main.height);
|
|
530
558
|
|
|
@@ -536,9 +564,9 @@ export class MenuScene extends Phaser.Scene {
|
|
|
536
564
|
private createTitle() {
|
|
537
565
|
this.add
|
|
538
566
|
.text(this.cameras.main.centerX, 150, 'MY AWESOME GAME', {
|
|
539
|
-
fontSize:
|
|
540
|
-
fill:
|
|
541
|
-
stroke:
|
|
567
|
+
fontSize: FontSize.css('4xl'),
|
|
568
|
+
fill: Color.rgb('yellow-400'),
|
|
569
|
+
stroke: Color.rgb('yellow-700'),
|
|
542
570
|
strokeThickness: 3,
|
|
543
571
|
})
|
|
544
572
|
.setOrigin(0.5);
|
|
@@ -550,13 +578,13 @@ export class MenuScene extends Phaser.Scene {
|
|
|
550
578
|
menuItems.forEach((item, index) => {
|
|
551
579
|
this.add
|
|
552
580
|
.text(this.cameras.main.centerX, 250 + index * 60, item, {
|
|
553
|
-
fontSize:
|
|
554
|
-
fill:
|
|
581
|
+
fontSize: FontSize.css('xl'),
|
|
582
|
+
fill: Color.rgb('slate-300'),
|
|
555
583
|
})
|
|
556
584
|
.setOrigin(0.5)
|
|
557
585
|
.setInteractive()
|
|
558
586
|
.on('pointerover', function () {
|
|
559
|
-
this.setTint(
|
|
587
|
+
this.setTint(Color.hex('yellow-400'));
|
|
560
588
|
})
|
|
561
589
|
.on('pointerout', function () {
|
|
562
590
|
this.clearTint();
|
|
@@ -575,21 +603,21 @@ export class MenuScene extends Phaser.Scene {
|
|
|
575
603
|
```typescript
|
|
576
604
|
// Create consistent themes
|
|
577
605
|
const darkTheme = {
|
|
578
|
-
background:
|
|
579
|
-
surface:
|
|
580
|
-
primary:
|
|
581
|
-
secondary:
|
|
582
|
-
text:
|
|
583
|
-
textMuted:
|
|
606
|
+
background: Color.hex('slate-900'),
|
|
607
|
+
surface: Color.hex('slate-800'),
|
|
608
|
+
primary: Color.hex('blue-500'),
|
|
609
|
+
secondary: Color.hex('slate-600'),
|
|
610
|
+
text: Color.rgb('slate-100'),
|
|
611
|
+
textMuted: Color.rgb('slate-400'),
|
|
584
612
|
};
|
|
585
613
|
|
|
586
614
|
const lightTheme = {
|
|
587
|
-
background:
|
|
588
|
-
surface:
|
|
589
|
-
primary:
|
|
590
|
-
secondary:
|
|
591
|
-
text:
|
|
592
|
-
textMuted:
|
|
615
|
+
background: Color.hex('slate-50'),
|
|
616
|
+
surface: Color.hex('white'),
|
|
617
|
+
primary: Color.hex('blue-600'),
|
|
618
|
+
secondary: Color.hex('slate-200'),
|
|
619
|
+
text: Color.rgb('slate-900'),
|
|
620
|
+
textMuted: Color.rgb('slate-600'),
|
|
593
621
|
};
|
|
594
622
|
```
|
|
595
623
|
|
|
@@ -599,13 +627,13 @@ const lightTheme = {
|
|
|
599
627
|
// Scale text based on screen size
|
|
600
628
|
const getResponsiveTextSize = (baseSize: FontSizeKey): string => {
|
|
601
629
|
const scale = this.cameras.main.width / 1920; // Base on 1920px width
|
|
602
|
-
const basePixels =
|
|
630
|
+
const basePixels = FontSize.px(baseSize);
|
|
603
631
|
return `${Math.round(basePixels * scale)}px`;
|
|
604
632
|
};
|
|
605
633
|
|
|
606
634
|
this.add.text(x, y, 'Responsive Text', {
|
|
607
635
|
fontSize: getResponsiveTextSize('2xl'),
|
|
608
|
-
fill:
|
|
636
|
+
fill: Color.rgb('blue-500'),
|
|
609
637
|
});
|
|
610
638
|
```
|
|
611
639
|
|
|
@@ -625,16 +653,16 @@ Plus, `phaser-wind` is way easier to type than `phaser-tailwind-css-design-token
|
|
|
625
653
|
|
|
626
654
|
## 📚 Compared to Raw Phaser
|
|
627
655
|
|
|
628
|
-
| Without Phaser Wind | With Phaser Wind
|
|
629
|
-
| ------------------------ |
|
|
630
|
-
| `fill: '#3B82F6'` | `fill:
|
|
631
|
-
| `fontSize: '18px'` | `fontSize:
|
|
632
|
-
| `tint: 0x4ADE80` | `tint:
|
|
633
|
-
| `fontFamily: 'Arial'` | `fontFamily:
|
|
634
|
-
| Magic numbers everywhere | Semantic, consistent tokens
|
|
635
|
-
| Color picking hell | Harmonious color palettes
|
|
636
|
-
| Inconsistent sizing | Perfect typography scale
|
|
637
|
-
| No design system | Complete theme architecture
|
|
656
|
+
| Without Phaser Wind | With Phaser Wind |
|
|
657
|
+
| ------------------------ | ------------------------------- |
|
|
658
|
+
| `fill: '#3B82F6'` | `fill: Color.rgb('primary')` |
|
|
659
|
+
| `fontSize: '18px'` | `fontSize: FontSize.css('lg')` |
|
|
660
|
+
| `tint: 0x4ADE80` | `tint: Color.hex('success')` |
|
|
661
|
+
| `fontFamily: 'Arial'` | `fontFamily: Font.family('ui')` |
|
|
662
|
+
| Magic numbers everywhere | Semantic, consistent tokens |
|
|
663
|
+
| Color picking hell | Harmonious color palettes |
|
|
664
|
+
| Inconsistent sizing | Perfect typography scale |
|
|
665
|
+
| No design system | Complete theme architecture |
|
|
638
666
|
|
|
639
667
|
---
|
|
640
668
|
|