0
# Display Objects & Scene Graph
1
2
Core display object system providing the foundation for all renderable objects in PixiJS. The scene graph is built from DisplayObjects arranged in a parent-child hierarchy using Containers.
3
4
## Capabilities
5
6
### DisplayObject Base Class
7
8
The base class for all objects that can be rendered and placed in the scene graph.
9
10
```typescript { .api }
11
/**
12
* The base class for all objects that can be rendered in PixiJS
13
*/
14
abstract class DisplayObject extends EventEmitter {
15
/** Position of the object */
16
position: ObservablePoint;
17
/** Scale of the object */
18
scale: ObservablePoint;
19
/** Pivot point for rotation and scaling */
20
pivot: ObservablePoint;
21
/** Rotation in radians */
22
rotation: number;
23
/** Skew values */
24
skew: ObservablePoint;
25
/** Alpha transparency (0-1) */
26
alpha: number;
27
/** Whether the object is visible */
28
visible: boolean;
29
/** Whether the object should be rendered */
30
renderable: boolean;
31
/** Parent container */
32
parent: Container;
33
/** World transform matrix */
34
worldTransform: Matrix;
35
/** Local transform matrix */
36
localTransform: Matrix;
37
/** Color tint as hex number */
38
tint: number;
39
/** Blend mode for rendering */
40
blendMode: BLEND_MODES;
41
/** Shader to use for rendering */
42
shader: Shader | Filter;
43
/** Enable/disable interaction */
44
interactive: boolean;
45
/** Whether children can be interactive */
46
interactiveChildren: boolean;
47
/** Custom hit area for interaction */
48
hitArea: Rectangle | Circle | Ellipse | Polygon | RoundedRectangle;
49
/** Button mode for cursor changes */
50
buttonMode: boolean;
51
/** CSS cursor when hovering */
52
cursor: string;
53
/** Z-index for depth sorting */
54
zIndex: number;
55
/** Mask for clipping */
56
mask: Container | MaskData;
57
/** Filters to apply */
58
filters: Filter[];
59
/** Render order ID */
60
_zOrder: number;
61
62
constructor();
63
64
/**
65
* Get the bounds of this object
66
* @param skipUpdate - Skip transform update
67
* @param rect - Rectangle to store bounds in
68
*/
69
getBounds(skipUpdate?: boolean, rect?: Rectangle): Rectangle;
70
71
/**
72
* Get the local bounds of this object
73
* @param rect - Rectangle to store bounds in
74
*/
75
getLocalBounds(rect?: Rectangle): Rectangle;
76
77
/**
78
* Convert a local point to global coordinates
79
* @param position - Local point
80
* @param point - Point to store result in
81
* @param skipUpdate - Skip transform update
82
*/
83
toGlobal(position: IPointData, point?: Point, skipUpdate?: boolean): Point;
84
85
/**
86
* Convert a global point to local coordinates
87
* @param position - Global point
88
* @param from - Object to convert from (default: stage)
89
* @param point - Point to store result in
90
* @param skipUpdate - Skip transform update
91
*/
92
toLocal(position: IPointData, from?: DisplayObject, point?: Point, skipUpdate?: boolean): Point;
93
94
/**
95
* Set the position of the object
96
* @param x - X coordinate
97
* @param y - Y coordinate
98
*/
99
setPosition(x: number, y: number): this;
100
101
/**
102
* Set the parent of this object
103
* @param container - New parent container
104
*/
105
setParent(container: Container): Container;
106
107
/**
108
* Enable interaction for this object
109
*/
110
enableInteraction(): this;
111
112
/**
113
* Disable interaction for this object
114
*/
115
disableInteraction(): this;
116
117
/** Update the transform */
118
updateTransform(): void;
119
120
/** Calculate bounds */
121
calculateBounds(): void;
122
123
/** Destroy the object and clean up resources */
124
destroy(): void;
125
126
/** Remove from parent */
127
removeFromParent(): void;
128
129
/** Render the object */
130
render(renderer: Renderer): void;
131
}
132
```
133
134
### Container Class
135
136
A DisplayObject that can contain and manage child objects.
137
138
```typescript { .api }
139
/**
140
* Container is a general-purpose display object that holds children
141
*/
142
class Container extends DisplayObject {
143
/** Array of child objects */
144
children: DisplayObject[];
145
/** Whether children should be sorted by zIndex */
146
sortableChildren: boolean;
147
/** Whether children can receive interaction events */
148
interactiveChildren: boolean;
149
/** Number of children */
150
readonly length: number;
151
152
constructor();
153
154
/**
155
* Add one or more children to the container
156
* @param children - Objects to add as children
157
*/
158
addChild<T extends DisplayObject[]>(...children: T): T[0];
159
160
/**
161
* Add child at specific index
162
* @param child - Object to add
163
* @param index - Index to add at
164
*/
165
addChildAt<T extends DisplayObject>(child: T, index: number): T;
166
167
/**
168
* Remove one or more children from the container
169
* @param children - Objects to remove
170
*/
171
removeChild<T extends DisplayObject[]>(...children: T): T[0];
172
173
/**
174
* Remove child at specific index
175
* @param index - Index to remove from
176
*/
177
removeChildAt(index: number): DisplayObject;
178
179
/**
180
* Remove children in index range
181
* @param beginIndex - Start index (inclusive)
182
* @param endIndex - End index (exclusive)
183
*/
184
removeChildren(beginIndex?: number, endIndex?: number): DisplayObject[];
185
186
/**
187
* Get child at specific index
188
* @param index - Index of child
189
*/
190
getChildAt(index: number): DisplayObject;
191
192
/**
193
* Get index of child object
194
* @param child - Child to find index of
195
*/
196
getChildIndex(child: DisplayObject): number;
197
198
/**
199
* Set index of child object
200
* @param child - Child to move
201
* @param index - New index
202
*/
203
setChildIndex(child: DisplayObject, index: number): void;
204
205
/**
206
* Swap positions of two children
207
* @param child1 - First child
208
* @param child2 - Second child
209
*/
210
swapChildren(child1: DisplayObject, child2: DisplayObject): void;
211
212
/**
213
* Get child by name
214
* @param name - Name to search for
215
* @param deep - Search recursively
216
*/
217
getChildByName(name: string, deep?: boolean): DisplayObject;
218
219
/** Sort children by zIndex */
220
sortChildren(): void;
221
222
/** Update transforms of all children */
223
updateTransform(): void;
224
225
/** Calculate bounds including all children */
226
calculateBounds(): void;
227
228
/** Render container and all children */
229
render(renderer: Renderer): void;
230
231
/** Destroy container and all children */
232
destroy(options?: boolean | IDestroyOptions): void;
233
}
234
235
interface IDestroyOptions {
236
children?: boolean;
237
texture?: boolean;
238
baseTexture?: boolean;
239
}
240
```
241
242
**Usage Examples:**
243
244
```typescript
245
import { Container, Sprite, Graphics } from "pixi.js";
246
247
// Create container hierarchy
248
const gameContainer = new Container();
249
const uiContainer = new Container();
250
const backgroundContainer = new Container();
251
252
// Add to main stage
253
app.stage.addChild(backgroundContainer);
254
app.stage.addChild(gameContainer);
255
app.stage.addChild(uiContainer);
256
257
// Add objects to containers
258
const background = Sprite.from('background.jpg');
259
backgroundContainer.addChild(background);
260
261
const player = Sprite.from('player.png');
262
const enemy = Sprite.from('enemy.png');
263
gameContainer.addChild(player, enemy);
264
265
// Container transforms affect all children
266
gameContainer.position.set(100, 100);
267
gameContainer.scale.set(2, 2); // Double size
268
gameContainer.rotation = Math.PI / 4; // 45 degrees
269
270
// Z-ordering
271
player.zIndex = 10;
272
enemy.zIndex = 5;
273
gameContainer.sortableChildren = true; // Enable z-sorting
274
275
// Find children
276
const foundPlayer = gameContainer.getChildByName('player', false);
277
```
278
279
### Transform System
280
281
Objects that manage transformation data.
282
283
```typescript { .api }
284
/**
285
* Observable point that emits change events
286
*/
287
class ObservablePoint implements IPointData {
288
x: number;
289
y: number;
290
291
constructor(x?: number, y?: number, observer?: () => void);
292
293
/** Set both coordinates */
294
set(x?: number, y?: number): this;
295
296
/** Copy from another point */
297
copyFrom(p: IPointData): this;
298
299
/** Copy to another point */
300
copyTo<T extends IPoint>(p: T): T;
301
302
/** Check equality with another point */
303
equals(p: IPointData): boolean;
304
305
/** Clone this point */
306
clone(): ObservablePoint;
307
}
308
309
/**
310
* Transform manages the transformation state of a DisplayObject
311
*/
312
class Transform {
313
/** Position of the object */
314
position: ObservablePoint;
315
/** Scale of the object */
316
scale: ObservablePoint;
317
/** Pivot point */
318
pivot: ObservablePoint;
319
/** Skew values */
320
skew: ObservablePoint;
321
/** Rotation in radians */
322
rotation: number;
323
/** Local transform matrix */
324
localTransform: Matrix;
325
/** World transform matrix */
326
worldTransform: Matrix;
327
328
constructor();
329
330
/** Update the local transform */
331
updateLocalTransform(): void;
332
333
/** Update the world transform */
334
updateTransform(parentTransform: Transform): void;
335
336
/** Set position */
337
setPosition(x: number, y: number): void;
338
339
/** Set scale */
340
setScale(x: number, y: number): void;
341
342
/** Set pivot */
343
setPivot(x: number, y: number): void;
344
345
/** Set rotation */
346
setRotation(rotation: number): void;
347
348
/** Set skew */
349
setSkew(x: number, y: number): void;
350
351
/** Destroy and clean up */
352
destroy(): void;
353
}
354
```
355
356
### Bounds Calculation
357
358
System for calculating object bounds.
359
360
```typescript { .api }
361
/**
362
* Bounds represents a bounding box for display objects
363
*/
364
class Bounds {
365
/** Minimum X coordinate */
366
minX: number;
367
/** Minimum Y coordinate */
368
minY: number;
369
/** Maximum X coordinate */
370
maxX: number;
371
/** Maximum Y coordinate */
372
maxY: number;
373
/** Rectangle representation */
374
rect: Rectangle;
375
376
constructor();
377
378
/** Clear the bounds */
379
clear(): void;
380
381
/** Check if bounds are empty */
382
isEmpty(): boolean;
383
384
/** Get bounds as rectangle */
385
getRectangle(rect?: Rectangle): Rectangle;
386
387
/**
388
* Add point to bounds
389
* @param point - Point to add
390
*/
391
addPoint(point: IPointData): void;
392
393
/**
394
* Add quad to bounds
395
* @param vertices - Quad vertices
396
*/
397
addQuad(vertices: Float32Array): void;
398
399
/**
400
* Add frame to bounds
401
* @param transform - Transform matrix
402
* @param x0 - Left edge
403
* @param y0 - Top edge
404
* @param x1 - Right edge
405
* @param y1 - Bottom edge
406
*/
407
addFrame(transform: Matrix, x0: number, y0: number, x1: number, y1: number): void;
408
409
/**
410
* Add vertices to bounds
411
* @param transform - Transform matrix
412
* @param vertices - Vertex data
413
* @param beginOffset - Start offset
414
* @param endOffset - End offset
415
*/
416
addVertices(transform: Matrix, vertices: Float32Array, beginOffset: number, endOffset: number): void;
417
418
/**
419
* Add bounds to these bounds
420
* @param bounds - Other bounds
421
*/
422
addBounds(bounds: Bounds): void;
423
424
/**
425
* Add bounds with matrix transform
426
* @param bounds - Other bounds
427
* @param matrix - Transform matrix
428
*/
429
addBoundsMatrix(bounds: Bounds, matrix: Matrix): void;
430
431
/**
432
* Add bounds area
433
* @param bounds - Other bounds
434
* @param area - Area rectangle
435
*/
436
addBoundsArea(bounds: Bounds, area: Rectangle): void;
437
438
/** Pad bounds by amount */
439
pad(paddingX: number, paddingY?: number): void;
440
441
/** Add padding uniformly */
442
addFramePad(paddingX: number, paddingY: number, paddingZ: number, paddingW: number): void;
443
}
444
```
445
446
**Usage Examples:**
447
448
```typescript
449
import { DisplayObject, Container } from "pixi.js";
450
451
// Working with transforms
452
const sprite = new Sprite();
453
sprite.position.set(100, 200);
454
sprite.scale.set(2, 1.5);
455
sprite.rotation = Math.PI / 6; // 30 degrees
456
sprite.pivot.set(sprite.width / 2, sprite.height / 2); // Center pivot
457
458
// Transform listeners
459
sprite.position.onChange = () => {
460
console.log('Position changed');
461
};
462
463
// Bounds calculation
464
const bounds = sprite.getBounds();
465
console.log(`Width: ${bounds.width}, Height: ${bounds.height}`);
466
467
// Coordinate conversion
468
const globalPoint = sprite.toGlobal(new Point(0, 0));
469
const localPoint = sprite.toLocal(globalPoint);
470
471
// Container management
472
const container = new Container();
473
container.sortableChildren = true;
474
475
// Add children with z-ordering
476
const bg = Sprite.from('background.png');
477
bg.zIndex = 0;
478
container.addChild(bg);
479
480
const character = Sprite.from('character.png');
481
character.zIndex = 10;
482
container.addChild(character);
483
484
// Interaction setup
485
character.interactive = true;
486
character.buttonMode = true;
487
character.on('pointerdown', () => {
488
console.log('Character clicked!');
489
});
490
491
// Masking
492
const mask = new Graphics();
493
mask.beginFill(0xffffff);
494
mask.drawRect(0, 0, 200, 200);
495
mask.endFill();
496
container.mask = mask;
497
```
498
499
## Transform Hierarchy
500
501
Understanding the transform hierarchy is crucial for proper positioning:
502
503
```typescript
504
// Parent transforms affect children
505
const parent = new Container();
506
parent.position.set(100, 100);
507
parent.scale.set(2, 2);
508
509
const child = new Sprite();
510
child.position.set(50, 50); // Relative to parent
511
512
parent.addChild(child);
513
// Child's world position is now (200, 200) due to parent transforms
514
515
// Global vs local coordinates
516
const globalPos = child.toGlobal(new Point(0, 0)); // Gets world position
517
const localPos = child.toLocal(globalPos); // Converts back to local
518
```
519
520
## Performance Considerations
521
522
```typescript
523
// Efficient container management
524
const container = new Container();
525
526
// Batch operations
527
const sprites = [];
528
for (let i = 0; i < 100; i++) {
529
sprites.push(new Sprite(texture));
530
}
531
container.addChild(...sprites); // Add all at once
532
533
// Use object pooling for frequently created/destroyed objects
534
class SpritePool {
535
private pool: Sprite[] = [];
536
537
get(): Sprite {
538
return this.pool.pop() || new Sprite();
539
}
540
541
release(sprite: Sprite): void {
542
sprite.visible = false;
543
sprite.parent?.removeChild(sprite);
544
this.pool.push(sprite);
545
}
546
}
547
548
// Disable interaction when not needed
549
container.interactiveChildren = false; // Better performance
550
```