pixi-scroll-layout
v1.1.1
Published
A lightweight, customizable scroll container for PixiJS with vertical/horizontal scrolling, draggable scrollbars, sticky headers, and overflow control.
Maintainers
Readme
pixi-scroll-layout
A lightweight, fully-typed scroll container for PixiJS (v7/v8). Supports vertical and horizontal scrolling, draggable scrollbars, optional sticky/scrollable headers, configurable overflow modes, and automatic content size detection — with zero external dependencies beyond PixiJS itself.
Features
- Vertical & horizontal scrolling via mouse wheel
- Draggable scrollbars with configurable style (color, thickness, radius, min size)
- Sticky or scrollable header with configurable bottom margin
- 4 overflow modes —
auto,scroll,hidden, andsilentfor each axis independently - Auto content size detection — scrollbars update automatically when content changes
- Fully typed with TypeScript
- Lightweight — ships as ES module and UMD bundle
Installation
npm install pixi-scroll-layoutPeer dependency: Requires
pixi.jsv7 or v8.
Quick Start
import * as PIXI from 'pixi.js';
import { ScrollContainer } from 'pixi-scroll-layout';
const app = new PIXI.Application();
await app.init({ width: 800, height: 600, backgroundColor: 0x1e1e1e });
document.body.appendChild(app.canvas);
const scroll = new ScrollContainer({
width: 400,
height: 300,
overflowX: 'auto',
overflowY: 'auto',
});
app.stage.addChild(scroll);
// Add content
for (let i = 0; i < 20; i++) {
const box = new PIXI.Graphics();
box.beginFill(0x4a90d9);
box.drawRect(0, 0, 100, 50);
box.endFill();
box.y = i * 60;
scroll.addChildToContent(box);
}API
new ScrollContainer(options?)
Creates a new scroll container and adds it to your PixiJS scene like any other Container.
Options (IScrollContainerOptions)
| Option | Type | Default | Description |
|---|---|---|---|
| width | number | 300 | Width of the visible viewport |
| height | number | 200 | Height of the visible viewport |
| overflowX | 'auto' \| 'scroll' \| 'hidden' \| 'silent' | 'auto' | Horizontal scroll & scrollbar behaviour |
| overflowY | 'auto' \| 'scroll' \| 'hidden' \| 'silent' | 'auto' | Vertical scroll & scrollbar behaviour |
| scrollHeader | boolean | false | If true, the header scrolls with the content. If false, the header is sticky |
| headerBottomMargin | number | 0 | Gap in pixels between the header and the scrollable content area |
| scrollbar.color | number | 0x888888 | Scrollbar color (hex) |
| scrollbar.thickness | number | 6 | Scrollbar thickness in pixels |
| scrollbar.minSize | number | 20 | Minimum scrollbar thumb size in pixels |
| scrollbar.radius | number | 3 | Corner radius of the scrollbar thumb |
Overflow Modes
| Value | Scrollable | Scrollbar visible |
|---|---|---|
| 'auto' | ✅ Yes | Only when content overflows |
| 'scroll' | ✅ Yes | Always |
| 'silent' | ✅ Yes | Never (invisible scrollbar) |
| 'hidden' | ❌ No | Never |
Use
'silent'when you want smooth touch/wheel scrolling without any visible scrollbar — ideal for clean UIs, mobile-style layouts, or when you handle scroll indicators yourself.
Properties
| Property | Type | Description |
|---|---|---|
| content | PIXI.Container | The scrollable content container. Add children here directly or via addChildToContent() |
| header | PIXI.Container | The header container. Set its contents via setHeaderContent() |
| viewport | PIXI.Container | The masked viewport container |
Methods
update()
Manually recalculates content bounds, clamps scroll position, and redraws scrollbars. Called automatically on the ticker; you rarely need this directly.
resize(width: number, height: number)
Resizes the viewport and refreshes the layout.
scroll.resize(600, 400);addChildToContent(child: DisplayObject)
Adds a display object to the scrollable content area and triggers an update.
const sprite = new PIXI.Sprite(texture);
scroll.addChildToContent(sprite);setHeaderContent(child: DisplayObject)
Replaces the current header content. The header sits above the scrollable area and can be sticky or scrolling depending on the scrollHeader option.
const headerGraphic = new PIXI.Graphics();
scroll.setHeaderContent(headerGraphic);setScrollbarStyle(style: Partial<ScrollbarStyle>)
Updates scrollbar appearance at runtime.
scroll.setScrollbarStyle({ color: 0xff0000, thickness: 10 });Examples
Silent scroll (scrollable, no visible scrollbar)
const scroll = new ScrollContainer({
width: 400,
height: 300,
overflowY: 'silent', // scrolls freely, no scrollbar shown
overflowX: 'hidden',
});Sticky header with 2D scrolling
const scroll = new ScrollContainer({
width: 400,
height: 300,
overflowX: 'scroll',
overflowY: 'scroll',
scrollHeader: false, // header stays fixed
headerBottomMargin: 10,
scrollbar: {
color: 0xaaaaaa,
thickness: 8,
radius: 4,
}
});
// Build header
const headerBg = new PIXI.Graphics();
headerBg.beginFill(0x333333);
headerBg.drawRect(0, 0, 400, 60);
headerBg.endFill();
const headerText = new PIXI.Text({ text: 'My Header', style: { fill: '#fff', fontSize: 20 } });
headerText.x = 10;
headerText.y = 15;
const header = new PIXI.Container();
header.addChild(headerBg, headerText);
scroll.setHeaderContent(header);
// Fill content grid
for (let row = 0; row < 20; row++) {
for (let col = 0; col < 20; col++) {
const box = new PIXI.Graphics();
box.beginFill(Math.random() * 0xffffff);
box.drawRect(0, 0, 80, 50);
box.endFill();
box.x = col * 90;
box.y = row * 60;
scroll.addChildToContent(box);
}
}
app.stage.addChild(scroll);Development
# Install dependencies
npm install
# Start demo dev server
cd demo && npm install && npm run dev
# Build the library
npm run buildThe library builds to dist/ as both an ES module (pixi-scroll-layout-es.js) and a UMD bundle (pixi-scroll-layout.umd.js), with TypeScript declarations (index.d.ts).
License
ISC
