0
# JSX Elements
1
2
@pixi/react provides type-safe JSX elements for all PixiJS components through a sophisticated type system. Components must be registered with `extend()` before use, supporting both prefixed and unprefixed usage patterns.
3
4
## Capabilities
5
6
### PixiJS Component Elements
7
8
All extended PixiJS components are available as JSX elements with automatic type safety and event handling.
9
10
```typescript { .api }
11
/**
12
* Type-safe JSX elements for PixiJS components
13
* Components must be registered via extend() before use
14
*/
15
interface PixiElements extends PrefixedPixiElements {}
16
17
type PrefixedPixiElements = {
18
[K in keyof UnprefixedPixiElements as `pixi${Capitalize<string & K>}`]: UnprefixedPixiElements[K];
19
};
20
21
type UnprefixedPixiElements = {
22
[K in PixiComponents as K extends keyof NameOverrides ? NameOverrides[K] : Uncapitalize<K>]:
23
PixiReactElementProps<typeof PIXI[K]>;
24
};
25
26
type PixiReactElementProps<T extends new (...args: any) => any> =
27
BaseNodeProps<InstanceType<T>>
28
& GraphicsProps<InstanceType<T>>
29
& EventHandlers
30
& ConstructorOptions<T>;
31
```
32
33
**Usage Examples:**
34
35
```typescript
36
import { extend } from "@pixi/react";
37
import { Container, Graphics, Text, Sprite } from "pixi.js";
38
39
extend({ Container, Graphics, Text, Sprite });
40
41
// Basic element usage
42
const BasicElements = () => (
43
<pixiContainer x={100} y={100} alpha={0.8}>
44
<pixiText
45
text="Hello World!"
46
x={50}
47
y={50}
48
style={{ fontSize: 24, fill: "white" }}
49
/>
50
<pixiSprite
51
texture={myTexture}
52
anchor={0.5}
53
interactive
54
onPointerDown={(event) => console.log("Clicked!", event)}
55
/>
56
</pixiContainer>
57
);
58
59
// All PixiJS properties are supported
60
const AdvancedElements = () => (
61
<pixiContainer
62
x={200}
63
y={150}
64
rotation={Math.PI / 4}
65
scale={{ x: 1.5, y: 1.5 }}
66
pivot={{ x: 50, y: 50 }}
67
alpha={0.9}
68
visible={true}
69
interactive={true}
70
interactiveChildren={true}
71
hitArea={new Rectangle(0, 0, 100, 100)}
72
mask={maskGraphics}
73
filters={[blurFilter]}
74
zIndex={10}
75
>
76
<pixiGraphics
77
draw={(graphics) => {
78
graphics.clear();
79
graphics.setFillStyle({ color: "red" });
80
graphics.rect(0, 0, 100, 100);
81
graphics.fill();
82
}}
83
interactive
84
onPointerMove={(event) => {
85
console.log("Mouse position:", event.global.x, event.global.y);
86
}}
87
/>
88
</pixiContainer>
89
);
90
```
91
92
### Graphics Elements
93
94
Graphics components have special support for the `draw` callback function.
95
96
```typescript { .api }
97
/**
98
* Graphics elements support special draw callback for rendering
99
*/
100
type GraphicsProps<T> = T extends Graphics ? { draw: DrawCallback } : unknown;
101
102
type DrawCallback = (graphics: Graphics) => void;
103
```
104
105
**Usage Examples:**
106
107
```typescript
108
import { extend } from "@pixi/react";
109
import { Graphics } from "pixi.js";
110
import { useCallback, useState } from "react";
111
112
extend({ Graphics });
113
114
// Simple graphics drawing
115
const SimpleGraphics = () => {
116
const drawRect = useCallback((graphics: Graphics) => {
117
graphics.clear();
118
graphics.setFillStyle({ color: "blue" });
119
graphics.rect(0, 0, 100, 100);
120
graphics.fill();
121
}, []);
122
123
return <pixiGraphics draw={drawRect} x={100} y={100} />;
124
};
125
126
// Dynamic graphics with state
127
const DynamicGraphics = () => {
128
const [color, setColor] = useState("red");
129
130
const drawCircle = useCallback((graphics: Graphics) => {
131
graphics.clear();
132
graphics.setFillStyle({ color });
133
graphics.circle(0, 0, 50);
134
graphics.fill();
135
graphics.setStrokeStyle({ color: "white", width: 2 });
136
graphics.stroke();
137
}, [color]);
138
139
return (
140
<pixiContainer>
141
<pixiGraphics
142
draw={drawCircle}
143
x={200}
144
y={200}
145
interactive
146
onPointerTap={() => {
147
const colors = ["red", "green", "blue", "yellow"];
148
const nextColor = colors[Math.floor(Math.random() * colors.length)];
149
setColor(nextColor);
150
}}
151
/>
152
</pixiContainer>
153
);
154
};
155
156
// Complex graphics shapes
157
const ComplexGraphics = () => {
158
const drawShape = useCallback((graphics: Graphics) => {
159
graphics.clear();
160
161
// Draw a star shape
162
graphics.setFillStyle({
163
color: "gold",
164
alpha: 0.8
165
});
166
167
const outerRadius = 60;
168
const innerRadius = 30;
169
const points = 5;
170
171
graphics.moveTo(outerRadius, 0);
172
173
for (let i = 1; i <= points * 2; i++) {
174
const radius = i % 2 === 0 ? outerRadius : innerRadius;
175
const angle = (i * Math.PI) / points;
176
graphics.lineTo(
177
Math.cos(angle) * radius,
178
Math.sin(angle) * radius
179
);
180
}
181
182
graphics.closePath();
183
graphics.fill();
184
185
// Add stroke
186
graphics.setStrokeStyle({ color: "orange", width: 3 });
187
graphics.stroke();
188
}, []);
189
190
return <pixiGraphics draw={drawShape} x={300} y={300} />;
191
};
192
```
193
194
### Event Handling
195
196
All PixiJS events are supported with automatic type conversion from React event props.
197
198
```typescript { .api }
199
/**
200
* Event handlers for PixiJS interaction events
201
* React event prop names are automatically converted to PixiJS event names
202
*/
203
interface EventHandlers {
204
// Pointer events
205
onPointerDown?: (event: FederatedPointerEvent) => void;
206
onPointerUp?: (event: FederatedPointerEvent) => void;
207
onPointerMove?: (event: FederatedPointerEvent) => void;
208
onPointerTap?: (event: FederatedPointerEvent) => void;
209
onPointerOver?: (event: FederatedPointerEvent) => void;
210
onPointerOut?: (event: FederatedPointerEvent) => void;
211
onPointerEnter?: (event: FederatedPointerEvent) => void;
212
onPointerLeave?: (event: FederatedPointerEvent) => void;
213
214
// Mouse events
215
onMouseDown?: (event: FederatedMouseEvent) => void;
216
onMouseUp?: (event: FederatedMouseEvent) => void;
217
onMouseMove?: (event: FederatedMouseEvent) => void;
218
onMouseOver?: (event: FederatedMouseEvent) => void;
219
onMouseOut?: (event: FederatedMouseEvent) => void;
220
221
// Touch events
222
onTouchStart?: (event: FederatedTouchEvent) => void;
223
onTouchEnd?: (event: FederatedTouchEvent) => void;
224
onTouchMove?: (event: FederatedTouchEvent) => void;
225
226
// Wheel events
227
onWheel?: (event: FederatedWheelEvent) => void;
228
}
229
```
230
231
**Usage Examples:**
232
233
```typescript
234
// Interactive sprite with multiple event handlers
235
const InteractiveSprite = ({ texture }) => {
236
const [isHovered, setIsHovered] = useState(false);
237
const [isPressed, setIsPressed] = useState(false);
238
239
return (
240
<pixiSprite
241
texture={texture}
242
interactive
243
alpha={isHovered ? 0.8 : 1}
244
scale={isPressed ? 0.9 : 1}
245
onPointerEnter={() => setIsHovered(true)}
246
onPointerLeave={() => setIsHovered(false)}
247
onPointerDown={() => setIsPressed(true)}
248
onPointerUp={() => setIsPressed(false)}
249
onPointerTap={(event) => {
250
console.log("Tapped at:", event.global.x, event.global.y);
251
}}
252
onRightClick={(event) => {
253
event.preventDefault();
254
console.log("Right clicked!");
255
}}
256
/>
257
);
258
};
259
260
// Draggable container
261
const DraggableContainer = ({ children }) => {
262
const [isDragging, setIsDragging] = useState(false);
263
const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
264
const [position, setPosition] = useState({ x: 0, y: 0 });
265
266
return (
267
<pixiContainer
268
x={position.x}
269
y={position.y}
270
interactive
271
onPointerDown={(event) => {
272
setIsDragging(true);
273
setDragStart({
274
x: event.global.x - position.x,
275
y: event.global.y - position.y,
276
});
277
}}
278
onPointerMove={(event) => {
279
if (isDragging) {
280
setPosition({
281
x: event.global.x - dragStart.x,
282
y: event.global.y - dragStart.y,
283
});
284
}
285
}}
286
onPointerUp={() => setIsDragging(false)}
287
onPointerUpOutside={() => setIsDragging(false)}
288
>
289
{children}
290
</pixiContainer>
291
);
292
};
293
```
294
295
### Component Properties
296
297
All PixiJS component properties are supported with full type safety.
298
299
```typescript { .api }
300
/**
301
* Base properties available on all PixiJS components
302
*/
303
interface BaseNodeProps<T> {
304
/** Child components (Container types only) */
305
children?: T extends Container ? PixiReactChildNode : never;
306
/** React key for list rendering */
307
key?: Key;
308
/** React ref for imperative access */
309
ref?: Ref<T>;
310
}
311
312
/**
313
* Constructor options and properties from PixiJS components
314
* Automatically inferred from the component class
315
*/
316
type ConstructorOptions<T> = ExcludeFunctionProps<T>;
317
```
318
319
**Usage Examples:**
320
321
```typescript
322
// Container with all supported properties
323
const FullContainer = () => (
324
<pixiContainer
325
// Transform properties
326
x={100}
327
y={150}
328
rotation={Math.PI / 6}
329
scale={{ x: 1.2, y: 1.2 }}
330
skew={{ x: 0.1, y: 0 }}
331
pivot={{ x: 50, y: 50 }}
332
anchor={0.5} // If supported by component
333
334
// Display properties
335
alpha={0.8}
336
visible={true}
337
renderable={true}
338
339
// Interaction properties
340
interactive={true}
341
interactiveChildren={true}
342
buttonMode={true}
343
cursor="pointer"
344
345
// Rendering properties
346
mask={maskObject}
347
filters={[blurFilter, colorFilter]}
348
cacheAsBitmap={false}
349
350
// Layout properties
351
zIndex={5}
352
sortableChildren={true}
353
354
// Event properties
355
onPointerDown={(event) => console.log("Clicked")}
356
>
357
{/* Children go here */}
358
</pixiContainer>
359
);
360
361
// Text with typography properties
362
const StyledText = () => (
363
<pixiText
364
text="Styled Text"
365
style={{
366
fontFamily: "Arial",
367
fontSize: 24,
368
fill: "white",
369
stroke: "black",
370
strokeThickness: 2,
371
fontWeight: "bold",
372
textAlign: "center",
373
}}
374
anchor={0.5}
375
x={400}
376
y={300}
377
/>
378
);
379
380
// Sprite with texture properties
381
const ConfiguredSprite = ({ texture }) => (
382
<pixiSprite
383
texture={texture}
384
anchor={{ x: 0.5, y: 1 }}
385
tint="0xff0000"
386
blendMode="multiply"
387
pluginName="batch"
388
roundPixels={true}
389
/>
390
);
391
```
392
393
## Type Safety Features
394
395
The JSX element system provides comprehensive type safety:
396
397
- **Property Validation**: All component properties are type-checked
398
- **Event Type Safety**: Event handlers receive properly typed event objects
399
- **Generic Support**: Components maintain generic type parameters where applicable
400
- **Conditional Properties**: Graphics `draw` prop only available on Graphics components
401
- **Ref Types**: Refs are properly typed to the underlying PixiJS component
402
403
## Component Registration
404
405
Components must be registered before use:
406
407
```typescript
408
import { extend } from "@pixi/react";
409
import { Container, Graphics, Text, Sprite, AnimatedSprite } from "pixi.js";
410
411
// Register before using in JSX
412
extend({
413
Container, // Available as <pixiContainer>
414
Graphics, // Available as <pixiGraphics>
415
Text, // Available as <pixiText>
416
Sprite, // Available as <pixiSprite>
417
AnimatedSprite, // Available as <pixiAnimatedSprite>
418
});
419
```
420
421
Attempting to use unregistered components will result in TypeScript errors and runtime warnings.