Pixi.js NineSlicePlane Guide for Scalable UI
When building user interfaces in Pixi.js, scaling assets without
stretching their borders or corners is a common challenge. This article
explores the role of the NineSlicePlane class, explaining
how it enables developers to create scalable UI elements—such as
buttons, panels, and dialogue boxes—while preserving their visual
integrity. We will examine the mechanics of nine-slice scaling, how it
optimizes rendering performance, and how to implement it directly in
your Pixi.js projects.
Understanding Nine-Slice Scaling
Nine-slice scaling (also known as 9-slicing) is a 2D texture resizing technique that splits an image into a grid of nine regions: four corners, four edges, and one center.
When the UI element is resized: * The Corners (top-left, top-right, bottom-left, bottom-right) remain entirely unscaled, preserving their original proportions and sharpness. * The Horizontal Edges (top, bottom) scale only along the horizontal (X) axis. * The Vertical Edges (left, right) scale only along the vertical (Y) axis. * The Center scales in both directions to fill the remaining space.
This technique prevents rounded corners from becoming distorted or pixelated when a UI element is stretched to fit different screen sizes or dynamic content.
The Role of NineSlicePlane in Pixi.js
In Pixi.js, the NineSlicePlane class inherits from
SimplePlane and is specifically designed to handle this
9-way grid segmentation. Rather than requiring developers to manually
split an image into nine separate sprite objects—which complicates
positioning and increases draw calls—NineSlicePlane manages
this process internally as a single mesh.
1. Maintaining Visual Fidelity
Without nine-slice scaling, scaling a rounded rectangle button
horizontally causes the rounded corners to stretch oval-shaped and
blurry. NineSlicePlane ensures that corner radiuses,
borders, and bevels retain their exact dimensions, regardless of how
wide or tall the final UI component becomes.
2. Performance Optimization
By utilizing a single WebGL mesh, NineSlicePlane groups
the vertices of the nine sliced regions into one renderable object. This
minimizes CPU overhead and helps keep the GPU draw call count low, which
is crucial for maintaining a high framerate in graphics-intensive web
applications and games.
3. Reducing Asset Load Times
Instead of creating dozens of UI graphics of varying dimensions (e.g., separate assets for small, medium, and large panels), developers can load a single, tiny base texture. This base texture can be scaled dynamically to any dimension in real-time, significantly reducing the project’s overall bundle size and loading times.
How to Implement NineSlicePlane
To create a NineSlicePlane, you define the source
texture and the width/height of the padding margins for the corners.
import * as PIXI from 'pixi.js';
// Load the button texture
const texture = PIXI.Texture.from('button_template.png');
// Define the corner margins: left, top, right, bottom (in pixels)
const leftMargin = 15;
const topMargin = 15;
const rightMargin = 15;
const bottomMargin = 15;
// Create the NineSlicePlane instance
const scalableButton = new PIXI.NineSlicePlane(
texture,
leftMargin,
topMargin,
rightMargin,
bottomMargin
);
// Set the desired dimensions
scalableButton.width = 300;
scalableButton.height = 80;
// Add to the stage
app.stage.addChild(scalableButton);In this implementation, the 15-pixel border on all four sides of the
button_template.png texture will remain unscaled, while the
interior of the button stretches to fill the rest of the 300x80
area.
Key Properties for Dynamic UI Layouts
The NineSlicePlane class provides properties that make
responsive UI design straightforward:
widthandheight: Changing these properties dynamically resizes the element. The mesh recalculates the stretched areas instantly, allowing for fluid animations (such as expanding menus or hover states).leftWidth,topHeight,rightWidth, andbottomHeight: These properties allow you to adjust the slice margins at runtime if your UI texture requirements change dynamically.