Layout
Dill pixel provides two main ways to handle layouts in your game: FlexContainer
and UICanvas
. These classes offer different approaches to positioning and organizing UI elements, both powered by the robust @pixi/layout system.
FlexContainer
Section titled “FlexContainer”The FlexContainer provides a flexible box layout model similar to CSS Flexbox, built on top of @pixi/layout. It’s ideal for creating dynamic layouts that need to adapt to different screen sizes or content.
Basic Usage
Section titled “Basic Usage”// Create a flex containerconst flexContainer = this.add.flexContainer({ layout: { gap: 10, flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start', },});// Add items to the containerflexContainer.add.text({ text: 'Item 1', style: textStyle });flexContainer.add.text({ text: 'Item 2', style: textStyle });flexContainer.add.text({ text: 'Item 3', style: textStyle });
Configuration Options
Section titled “Configuration Options”The FlexContainer supports several configuration options:
const container = this.add.flexContainer({ // Layout properties (passed to @pixi/layout) layout: { width: 800, height: 200, gap: 20, flexDirection: 'row', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'space-between', }, // Auto-layout children (default: true) autoLayoutChildren: true, // Bind to app size for responsive layouts bindToAppSize: false, // Bind to another container's size bindTo: someContainer,});
Layout Properties
Section titled “Layout Properties”The layout
property accepts any valid @pixi/layout options:
flexDirection
: Controls the direction of items (‘row’ | ‘column’ | ‘row-reverse’ | ‘column-reverse’)flexWrap
: Determines if items should wrap (‘wrap’ | ‘nowrap’ | ‘wrap-reverse’)alignItems
: Aligns items on the cross axis (‘center’ | ‘flex-start’ | ‘flex-end’ | ‘stretch’ | ‘baseline’)justifyContent
: Aligns items on the main axis (‘center’ | ‘flex-start’ | ‘flex-end’ | ‘space-between’ | ‘space-around’ | ‘space-evenly’)gap
: Space between items (number)width
/height
: Container dimensions (number | ‘auto’ | ‘intrinsic’ | percentage string)padding
: Inner spacing (number | object with top/left/bottom/right)margin
: Outer spacing (number | object with top/left/bottom/right)
Convenience Properties
Section titled “Convenience Properties”FlexContainer provides convenient getters and setters for common layout properties:
// Direct property access (updates layout automatically)container.gap = 15;container.flexDirection = 'column';container.alignItems = 'center';container.justifyContent = 'space-between';
// Size controlcontainer.size = { width: 400, height: 300 };container.size = [400, 300]; // Array formatcontainer.size = 400; // Square format
// Individual dimensionscontainer.layoutWidth = 'auto';container.layoutHeight = 200;
Auto-Layout Children
Section titled “Auto-Layout Children”When autoLayoutChildren
is true (default), child elements are automatically configured for layout:
const container = this.add.flexContainer({ autoLayoutChildren: true, // default layout: { flexDirection: 'row', gap: 10 },});
// Children are automatically given layout propertiesconst child = container.add.text({ text: 'Auto-layout text' });// child.layout is automatically set to { isLeaf: true }
Responsive Layouts
Section titled “Responsive Layouts”Bind containers to app size or other containers for responsive behavior:
// Bind to application sizeconst responsiveContainer = this.add.flexContainer({ bindToAppSize: true, layout: { flexDirection: 'column', justifyContent: 'center', alignItems: 'center', },});
// Bind to another containerconst childContainer = this.add.flexContainer({ bindTo: parentContainer, layout: { width: '100%', height: 'auto' },});
Nested Containers
Section titled “Nested Containers”FlexContainers can be nested to create complex layouts:
const mainContainer = this.add.flexContainer({ layout: { flexDirection: 'column', gap: 20, width: '100%', height: '100%', },});
const topRow = mainContainer.add.flexContainer({ layout: { flexDirection: 'row', gap: 10, alignItems: 'center', width: '100%', height: 'auto', },});
topRow.add.text({ text: 'Row 1 Item 1' });topRow.add.text({ text: 'Row 1 Item 2' });
const bottomRow = mainContainer.add.flexContainer({ layout: { flexDirection: 'row', gap: 10, alignItems: 'center', width: '100%', height: 'auto', },});
bottomRow.add.text({ text: 'Row 2 Item 1' });bottomRow.add.text({ text: 'Row 2 Item 2' });
Layout Events
Section titled “Layout Events”FlexContainer emits layout events you can listen to:
const container = this.add.flexContainer({ layout: { flexDirection: 'row', gap: 10 },});
container.onLayoutComplete.connect(() => { console.log('Layout calculation complete');});
UICanvas
Section titled “UICanvas”The UICanvas provides edge-based alignment for UI elements using a sophisticated 9-grid system, making it perfect for HUD elements, menus, and other screen-anchored UI components. It’s built on top of FlexContainer internally.
Basic Usage
Section titled “Basic Usage”// Create a UI canvasconst ui = this.add.uiCanvas({ useAppSize: true, // Bind to application size debug: true, // Show alignment guides autoLayoutChildren: true, // Auto-configure child layouts});
// Add elements with alignmentui.addElement(this.make.text({ text: 'Top Left' }), { align: 'top left' });ui.addElement(this.make.text({ text: 'Bottom Right' }), { align: 'bottom right' });
Configuration Options
Section titled “Configuration Options”const ui = this.add.uiCanvas({ // Visual debugging debug: false, // Canvas padding padding: { top: 20, left: 20, bottom: 20, right: 20 }, // Manual size (ignored if useAppSize is true) size: { width: 800, height: 600 }, // Bind to application size useAppSize: true, // Layout configuration for the main container layout: { flexDirection: 'column', justifyContent: 'space-between', }, // Auto-configure child layouts autoLayoutChildren: true,});
Internal Structure
Section titled “Internal Structure”UICanvas creates a sophisticated 9-grid layout system using FlexContainers:
// UICanvas internally creates:// - topRow: FlexContainer (top alignment)// - middleRow: FlexContainer (middle alignment)// - bottomRow: FlexContainer (bottom alignment)
// Each row contains position containers for left/center/right alignment// This creates 9 total positioning zones
Alignment Options
Section titled “Alignment Options”UICanvas supports various edge alignments mapped to the 9-grid system:
- Corners: ‘top left’, ‘top right’, ‘bottom left’, ‘bottom right’
- Edges: ‘top’, ‘bottom’, ‘left’, ‘right’
- Centers: ‘top center’, ‘bottom center’, ‘left center’, ‘right center’
- Absolute center: ‘center’
// All these alignments work:ui.addElement(element1, { align: 'top left' });ui.addElement(element2, { align: 'left top' }); // Same as aboveui.addElement(element3, { align: 'center' });ui.addElement(element4, { align: 'bottom right' });
Adding Padding
Section titled “Adding Padding”Elements can be positioned with padding from their aligned edges:
ui.addElement(this.make.text({ text: 'Padded Corner' }), { align: 'top right', padding: { top: 20, right: 20 },});
// Padding can also be specified as a point-like objectui.addElement(someElement, { align: 'bottom left', padding: { x: 10, y: 10 }, // Applies to left/right and top/bottom});
Combining with FlexContainer
Section titled “Combining with FlexContainer”UICanvas and FlexContainer work seamlessly together:
const ui = this.add.uiCanvas({ useAppSize: true });
// Create a flex container for a bottom toolbarconst toolbar = this.make.flexContainer({ layout: { gap: 20, alignItems: 'center', height: 48, width: 'auto', flexDirection: 'row', },});
toolbar.add.text({ text: 'Button 1' });toolbar.add.text({ text: 'Button 2' });toolbar.add.text({ text: 'Button 3' });
// Add the flex container to the UI canvasui.addElement(toolbar, { align: 'bottom center' });
Layout Updates and Performance
Section titled “Layout Updates and Performance”UICanvas automatically handles layout updates through the @pixi/layout system:
const ui = this.add.uiCanvas({ useAppSize: true });
// Layout updates happen automatically when:// - Elements are added or removed// - App is resized (if useAppSize is true)// - Child elements change their layout properties// - Manual updateLayout() is called
ui.updateLayout(); // Force layout update if needed
Advanced Layout Features
Section titled “Advanced Layout Features”Auto-Layout Children
Section titled “Auto-Layout Children”Both FlexContainer and UICanvas support automatic layout configuration for children:
const container = this.add.flexContainer({ autoLayoutChildren: true, // default layout: { flexDirection: 'row' },});
// When autoLayoutChildren is true:// - Children automatically get layout properties// - Width and height are set to 'auto' if not specified// - Children are marked as layout leaves for optimization
Layout Property Types
Section titled “Layout Property Types”The layout system supports various value types for dimensions:
const container = this.add.flexContainer({ layout: { width: 400, // Fixed pixel width height: 'auto', // Auto-size to content maxWidth: '80%', // Percentage of parent minHeight: 100, // Minimum size constraint flexGrow: 1, // Flex grow factor flexShrink: 0, // Flex shrink factor },});
Performance Optimization
Section titled “Performance Optimization”The @pixi/layout integration provides several performance benefits:
- Efficient Updates: Only recalculates when properties change
- Batched Calculations: Layout updates are batched for performance
- Optimized Rendering: Reduces unnecessary draw calls
- Memory Efficient: Reuses layout calculations where possible
// Layout updates are automatically optimizedconst container = this.add.flexContainer({ layout: { flexDirection: 'row', gap: 10 },});
// Multiple property changes are batchedcontainer.gap = 20;container.flexDirection = 'column';// Layout recalculation happens once, not twice
Best Practices
Section titled “Best Practices”-
Choose the Right Tool:
- Use FlexContainer for dynamic content that needs to flow and adapt
- Use UICanvas for screen-anchored UI elements like HUDs and menus
-
Performance:
- Keep
autoLayoutChildren: true
unless you need manual control - Use appropriate size constraints (
width: 'auto'
vs fixed values) - Minimize deep nesting of layout containers
- Keep
-
Responsive Design:
- Use
useAppSize: true
with UICanvas for responsive layouts - Leverage percentage values and ‘auto’ sizing for adaptive layouts
- Use
bindToAppSize
orbindTo
for reactive container sizing
- Use
-
Layout Properties:
- Prefer the
layout
object over individual property setters for multiple changes - Use percentage strings (‘50%’) for responsive sizing
- Leverage ‘auto’ and ‘intrinsic’ sizing for content-driven layouts
- Prefer the
-
Debugging:
- Use
debug: true
to visualize layout boundaries on UI Canvas - Monitor layout events for performance debugging
- Use the browser’s performance tools to profile layout calculations
- Use