pixi-autoresize-text
v1.0.13
Published
An auto-resizing text component for PixiJS v8
Maintainers
Readme
pixi-autoresize-text
A lightweight, PixiJS 8 compatible text component that automatically reduces its font size to fit within a specified maximum width.
Instead of scaling the rendered texture (which can cause blurriness), pixi-autoresize-text dynamically updates the fontSize style property. This forces PixiJS to native render the text crisply at the exact size needed!
Why is this important?
When building multi-lingual games or UI systems, text length varies drastically between languages. A layout that looks perfect in English might completely overflow its boundaries or break your UI when translated.
For example, consider a standard error message:
- English: "Technical problem. Your account has not been charged, please try again later."
- Russian: "Техническая проблема. С вашего счёта не были списаны средства, пожалуйста, попробуйте позже."
If you have a strict, fixed-width dialogue box, standard global scaling can lead to pixelated or blurry text. pixi-autoresize-text solves this gracefully by recalculating and natively reducing the fontSize, ensuring that long translations always fit perfectly within their boundaries while maintaining crisp vector quality!
Installation
npm install pixi-autoresize-textBasic Usage
Use it exactly as you would use a standard PIXI.Text, but pass maxWidth in the options!
import { Application } from 'pixi.js';
import { AutoResizeText } from 'pixi-autoresize-text';
const app = new Application();
await app.init({ width: 800, height: 600 });
document.body.appendChild(app.canvas);
// Create the text component
const myText = new AutoResizeText({
text: "This is a super long player name that might break layout",
maxWidth: 250, // The boundary width limit
minFontSize: 16, // (Optional) Fallback to wordWrap if font scales below this
autoCenterVertically: true, // (Optional) Keeps text vertically centered when scaled
style: {
fontFamily: 'Arial',
fontSize: 36, // This is treated as the MAX/ORIGINAL font size
fill: 0xffffff
}
});
myText.x = 100;
myText.y = 100;
app.stage.addChild(myText);If the text is too long, the font size will seamlessly shrink from 36 downwards. If it hits the minFontSize of 16, it will stop shrinking and automatically enable wordWrap instead!
API & Examples
1. Updating Text Dynamically
If you change the text, it will automatically recalculate its bounds and resize the font instantly.
// Standard PixiJS setter
myText.text = "A short string";
// Convenience method
myText.setText("A short string"); 2. Updating Layout / Resizing the Game
When your game canvas resizes, you might need to adjust the UI boundaries.
window.addEventListener('resize', () => {
// Let's say your panel just shrunk to 150px
const newPanelWidth = 150;
// Updates the max width constraint and reapplies sizing immediately
myText.setMaxWidth(newPanelWidth);
// Or use the resize helper to also adjust position in one line!
const newX = 50;
const newY = 50;
myText.resize(newPanelWidth, newX, newY);
});3. Updating Styles Safely
Changing styles dynamically can sometimes accidentally mutate PixiJS global objects. AutoResizeText safely consumes your styles and properly re-evaluates the font size boundary.
myText.updateStyle({
fontSize: 48, // Upgrades the base font size limit to 48!
fill: 0xff0000,
fontWeight: 'bold'
});4. BitmapText Support
Need to use BitmapText for high-performance rendering (e.g. for scores or damage numbers)? We've got you covered! You can import AutoResizeBitmapText which behaves identically but extends the native BitmapText class.
import { AutoResizeBitmapText } from 'pixi-autoresize-text';
import { Assets } from 'pixi.js';
// Ensure your bitmap font is loaded first!
await Assets.load('path/to/my-font.fnt');
const myBitmapText = new AutoResizeBitmapText({
text: "1,452,999",
maxWidth: 100,
style: {
fontFamily: 'MyFontName', // The name of the font in the loaded asset
fontSize: 48,
}
});
app.stage.addChild(myBitmapText);5. Animations
The AutoResizeText and AutoResizeBitmapText components now feature a built-in, lightweight animation system powered by PixiJS's native Ticker.
// Start a typewriter effect
myText.animate('typewriter', { speed: 50, fullText: "Hello world!" });
// Start a continuous rainbow color cycle
myText.animate('rainbow', { speed: 0.1 });
// Stop a specific animation
myText.stopAnimation('rainbow');
// Stop all animations
myText.stopAnimation();Available Animations
| Category | Animation Name | Description | Options |
|---|---|---|---|
| Text Content | typewriter | Reveals characters one by one. | { speed: number, fullText: string } |
| | countUp | Animates numeric values. | { start: number, end: number, duration: number, prefix: string, suffix: string, decimals: number } |
| | scramble | Displays random characters before revealing final text. | { finalText: string, duration: number, chars: string } |
| Transform & Alpha | fadeIn | Animates alpha from 0 to 1. | { duration: number } |
| | fadeOut | Animates alpha from 1 to 0. | { duration: number } |
| | blink | Toggles alpha. | { interval: number } |
| | breath | Pulsates scale using a sine wave. | { speed: number, amount: number } |
| | shake | Randomly vibrates text. | { amount: number } |
| | marquee | Scrolls text horizontally. | { speed: number, boundX: number, resetX: number } |
| | achievement | A celebratory preset (scale bounce + fade in). | { duration: number } |
| Style & Visual | rainbow | Cycles through colors. | { speed: number } |
| | glow | Animates a glowing drop-shadow outline (Text only, not BitmapText). | { color: string, speed: number, minBlur: number, maxBlur: number } |
| | glitch | Adds flickering RGB split offset effects. | { frequency: number, offset: number } |
6. Grouping Texts for Visual Coherence
When you have multiple text elements on screen (like bullet points or a list of slot features), they shouldn't scale independently. If one shrinks heavily and another doesn't, it looks visually jarring.
You can use AutoResizeGroup to link them together. The group will evaluate all linked texts and force them all to snap to the smallest required font size, keeping everything visually coherent!
import { AutoResizeText, AutoResizeGroup } from 'pixi-autoresize-text';
const feature1 = new AutoResizeText({ text: "Wild Symbol Feature", maxWidth: 200, style: { fontSize: 36 }});
const feature2 = new AutoResizeText({ text: "Super Mega Extravaganza Bonus", maxWidth: 200, style: { fontSize: 36 }});
// Create a group and add the texts
const textGroup = new AutoResizeGroup();
textGroup.add(feature1, feature2);
// Now, because "feature2" is extremely long, it will shrink significantly.
// "feature1" will automatically shrink to match the exact same font size as "feature2"
// so they both look visually identical on the screen!7. Ticker Animations & Monospace Performance Optimization
When animating numbers rapidly (e.g. counting up a score frame-by-frame) with a monospaced font, recalculating the bounds every frame is a huge waste of CPU, because the width of "10" is exactly the same as "99".
Enable the optimizeMonospace flag to instantly solve this. When enabled, if the length of the string hasn't changed, it completely skips the bounds calculation logic and renders instantly!
const scoreText = new AutoResizeText({
text: "10",
maxWidth: 150,
optimizeMonospace: true, // Massive performance boost for counting animations!
style: { fontFamily: 'Courier', fontSize: 48 }
});
// Animate from 10 to 99 over 1 second.
// The resize logic will evaluate on "10", and then completely sleep for the rest of the animation
// since the string length remains exactly 2 characters long!
scoreText.animate('countUp', { start: 10, end: 99, duration: 1000 });Pixijs 8 Code snippet
import "./style.css";
import { Application } from "pixi.js";
import { AutoResizeText } from "pixi-autoresize-text";
const gameWidth = 1920;
const gameHeight = 1080;
(async () => {
const app = new Application();
//await window load
await new Promise((resolve) => {
window.addEventListener("load", resolve);
});
await app.init({ width: gameWidth, height: gameHeight });
document.body.appendChild(app.canvas);
// resizeCanvas();
// --- Create the auto-resize text component ---
const myText = new AutoResizeText({
text: "This is a super long player name that might break layout",
maxWidth: 250, // The boundary width
minFontSize: 16, //optional
style: {
fontFamily: 'Arial',
fontSize: 36, // This is treated as the MAX/ORIGINAL font size
fill: 0xffffff
}
});
myText.x = 400;
myText.y = 400;
app.stage.addChild(myText);
// --- 1. Updating Text Dynamically ---
// Change the text after 2 seconds to demonstrate automatic recalculation
setTimeout(() => {
// You can use myText.text = "..." or the convenience method myText.setText("...")
myText.setText("A short string");
}, 2000);
// --- 2. Updating Layout / Resizing the Game ---
// Change the max width and position after 4 seconds
setTimeout(() => {
const newPanelWidth = 150;
// You could update just the max width constraint:
// myText.setMaxWidth(newPanelWidth);
// Or use the resize helper to adjust maxWidth, x, and y in one line!
const newX = 400;
const newY = 400;
myText.resize(newPanelWidth, newX, newY);
}, 4000);
// --- 3. Updating Styles Safely ---
// Update the base styles after 6 seconds
setTimeout(() => {
myText.updateStyle({
fontSize: 48, // Upgrades the base font size limit to 48
fill: 0xff0000,
fontWeight: 'bold'
});
// Setting a long text again to see it shrink from the new base size of 48!
myText.setText("Now it is red, bold, and very long again to test shrinking!");
}, 6000);
})();Properties
| Property | Type | Description |
|---|---|---|
| maxWidth | number | The maximum allowable pixel width before font size reduction triggers. |
| minFontSize | number | (Optional) The absolute minimum font size. If it must scale below this, it wraps the text instead. |
| autoCenterVertically | boolean | (Optional) If true, automatically adjusts the y position so the text stays vertically centered within its original unscaled bounding box when it shrinks. |
| optimizeMonospace | boolean | (Optional) If true, completely bypasses bounds recalculation if the string length hasn't changed. Massive performance boost for ticker animations using monospaced fonts. |
Note: By default, AutoResizeText sets eventMode = "none" internally since UI text typically shouldn't block pointer interactions.
