PixiJS Layout

repository·main·Indexed 41 days ago

https://github.com/pixijs/layout

A Yoga-powered layout engine for PixiJS that enables Flexbox-style layouting for 2D canvas interfaces. Version 3.2.1 provides responsive UI capabilities for PixiJS objects like Container, Sprite, and Text, featuring LayoutContainer for flexbox rules and LayoutView for layout-aware components. Supports advanced styling including objectFit, overflow, and physics-based scrolling via trackpad options.

Tokens
28.9K
Snippets
97
Records
121
Agent score
50%

What's inside PixiJS Layout

  1. Understand sizing and dimension values in PixiJS Layout

    main

    Sizing in PixiJS Layout is managed by the Yoga layout engine. Size-related properties (like width and height) accept several types of values to determine how much space a node occupies:

    • Pixel numbers: Absolute pixel values (e.g., width: 200).
    • Percentage strings: Relative to the parent container (e.g., width: '50%').
    • Auto sizing: Uses 'auto' to let the layout engine determine size.
    • Intrinsic sizing: Uses 'intrinsic' to size the node based on its own PixiJS bounds (content size).
  2. Treat a Container as a Leaf Node using isLeaf

    main

    If you want a Container to behave like a leaf node (for example, when using it as a single wrapper for multiple elements), you can set the isLeaf property to true in its layout configuration.

    When isLeaf is true:

    1. The container ignores its children for layout purposes.
    2. You can use objectFit and objectPosition properties on the container.
    3. If the container's bounds are negative, it is automatically pushed to the origin (0,0) to prevent content from leaving the layout box.
    const container = new Container();
    
    container.layout = {
        isLeaf: true,
        objectFit: 'contain',
        objectPosition: 'center',
    };
  3. How the PixiJS Layout model works

    main

    PixiJS Layout uses a declarative, responsive layout model powered by the Yoga Flexbox engine. It follows a box model where containers act as layout groups (similar to HTML <div>) and leaf nodes (like Sprite or Text) act as content-bearing elements (similar to <img>).

    Key Flexbox properties available include flexDirection, justifyContent, alignItems, gap, and flexWrap.

    const container = new Container({
        layout: {
            width: 500,
            height: 300,
            flexWrap: 'wrap',
            justifyContent: 'center',
            alignContent: 'center',
        },
    });
    
    const sprite = new Sprite({ texture });
    sprite.layout = {
        width: 100,
        height: 100,
        objectFit: 'contain',
        objectPosition: 'center',
    };
    
    container.addChild(sprite);
  4. Use transformOrigin for rotation and scaling

    main

    In PixiJS Layout, use the transformOrigin property to define the pivot point for rotation and scaling. Unlike traditional PixiJS where you use anchor or pivot, transformOrigin applies to the layout box rather than the PixiJS element itself. This behavior is conceptually similar to the CSS transform-origin property.

    Note: When using layout, the standard PixiJS anchor and pivot properties are ignored for layout box calculations. Use transformOrigin instead to avoid confusion.

    sprite.layout = {
        width: 300,
        height: 300,
        transformOrigin: 'center',
    };
    
    sprite.rotation = 0.2; // rotates around the center of the layout box
  5. Handle opposing insets (e.g., top/bottom or left/right)

    main

    When you define both opposing insets (such as left and right, or top and bottom), the following rules apply:

    1. Priority: The 'start' inset takes priority over the 'end' inset (left over right, and top over bottom).
    2. Fixed Dimensions: If the node has a fixed width or height, the opposing insets are used to determine the node's alignment relative to the container.
    3. Flexible Dimensions: If the node's width or height is flexible, the layout engine may stretch or shrink the node to satisfy the insets.
  6. Use DevTools features to inspect layout

    main

    The PixiJS DevTools extension provides several capabilities for debugging layouts:

    • Inspect Layout: View the layout properties of your PixiJS display objects in real-time.
    • Visual Helpers: A ⬥ symbol indicates a layout object. You can use the flash button to toggle the object on/off to locate it within the scene.
    • Reset Layout: Use the reset button to revert an object's layout properties to their default values.
  7. How to opt-in to layout for specific nodes

    main

    Layout is non-invasive and opt-in. A parent container only applies layout logic to children that have the layout property enabled.

    • To enable layout for a node, set node.layout = true or provide a layout configuration object.
    • Children without the layout property are unaffected and behave like standard PixiJS objects (positioned at their own x and y).
    const container = new Container({
        layout: {
            width: 500,
            height: 500,
            justifyContent: 'center',
        },
    });
    
    const managed = new Sprite({ texture, layout: true });
    const unmanaged = new Sprite(texture); // not in layout
    
    container.addChild(managed, unmanaged);
  8. Use intrinsic sizing for leaf nodes

    main

    Intrinsic sizing allows a node to automatically adjust its size based on its content or children.

    In PixiJS Layout, setting layout = true on a leaf node enables intrinsic sizing by default. This is equivalent to setting both width and height to 'intrinsic'.

    Performance Note: Intrinsic sizing has a performance impact because the system periodically checks the node's bounds (based on the LayoutSystem throttle value). For high-performance needs with many nodes, prefer using fixed pixel sizes instead.

    // Enables intrinsic sizing automatically
    sprite.layout = true;
    
    // Explicit equivalent
    sprite.layout = {
        width: 'intrinsic',
        height: 'intrinsic',
    };
    
    // Performance-optimized alternative using fixed sizes
    sprite.layout = {
        width: texture.width,
        height: texture.height,
    };
  9. Configure overflow behavior for LayoutContainer and LayoutView

    main

    Overflow settings determine how a node handles content that exceeds its layout bounds. Note that overflow and scrolling features are only available for LayoutContainer and LayoutView components.

    Available overflow values:

    • visible: Content outside bounds is shown (default).
    • hidden: Content is clipped to the bounds. No scrolling.
    • scroll: Content is clipped, and scrolling is enabled.
    const container = new LayoutContainer({
        layout: {
            overflow: 'scroll',
        },
    });
  10. Use Shorthand and Longhand properties for spacing

    main

    When configuring margin or padding, you can use shorthand properties (like margin) to apply a value to all sides, and then use longhand properties (like marginTop) to override specific sides. Longhand values always take precedence over shorthand values.

    // Apply 10px to all sides first, then override just the top side with 20px
    sprite.layout = {
        margin: 10,
        marginTop: 20,
    };
    // Result: 20px top margin, 10px everywhere else.
  11. Understand position and scale normalization

    main

    When layout is enabled on a node, the position and scale properties are normalized to the layout box. This differs from standard PixiJS behavior where position is relative to the parent and scale is relative to the content.

    • node.position.x and node.position.y default to 0, even if the node is positioned within a flexbox container.
    • node.scale.x and node.scale.y default to 1, even if properties like objectFit are scaling the content inside the layout box.

    This normalization is designed to simplify animations. To retrieve the actual position or scale of a node in the scene, refer to the realPositionScale documentation in the Layout API.

    const sprite = new Sprite({ texture });
    sprite.layout = {
        width: 300,
        height: 300,
        objectFit: 'cover',
        transformOrigin: 'center',
    };
    
    sprite.scale = 2; // scales as if the box was 600x600
    sprite.rotation = 0.2; // rotates around the center of the layout box
  12. How the Flexbox model works in PixiJS Layout

    main

    PixiJS Layout uses the Yoga layout engine, which implements a subset of the CSS Flexbox specification. If you are familiar with web development, the layout logic for properties like flexDirection, justifyContent, alignItems, gap, and flexWrap will behave as expected.

    Important Note on Naming: PixiJS Layout uses the same property names as CSS, but they are converted to camelCase. For example, justify-content becomes justifyContent and margin-left becomes marginLeft.