| name | pixijs-math |
| description | Use this skill when working with coordinates, vectors, matrices, shapes, hit testing, or layout rectangles in PixiJS v8. Covers Point/ObservablePoint, Matrix (2D affine, decompose, apply, applyInverse), shapes (Rectangle, Circle, Ellipse, Polygon, RoundedRectangle, Triangle), Rectangle layout helpers (pad, fit, enlarge, ceil, scale, getBounds), strokeContains hit tests, Polygon isClockwise/containsPolygon, toGlobal/toLocal, PointData/PointLike/Size types, DEG_TO_RAD, and pixi.js/math-extras vector and intersection helpers. Triggers on: Point, ObservablePoint, Matrix, Rectangle, Circle, Polygon, Triangle, RoundedRectangle, toGlobal, toLocal, hitArea, strokeContains, pad, fit, enlarge, ceil, getBounds, containsRect, intersects, isClockwise, math-extras, lineIntersection, segmentIntersection, DEG_TO_RAD, PointData. |
| license | MIT |
| disable-model-invocation | true |
PixiJS exposes lightweight math primitives (Point, Matrix, shape classes) used throughout the library for transforms, hit testing, and coordinate conversion. Import pixi.js/math-extras to add vector operations (add, dot, magnitude, reflect) and Rectangle intersection/union helpers.
Quick Start
const parent = new Container();
parent.position.set(100, 100);
parent.scale.set(2);
app.stage.addChild(parent);
const child = new Container();
child.position.set(50, 50);
parent.addChild(child);
const globalPt = child.toGlobal(new Point(0, 0));
const m = new Matrix()
.translate(100, 50)
.rotate(Math.PI / 4)
.scale(2, 2);
const world = m.apply(new Point(10, 20));
const hitArea = new Rectangle(0, 0, 200, 100);
console.log(hitArea.contains(50, 50));
Related skills: pixijs-scene-container (transform properties), pixijs-events (hitArea usage), pixijs-scene-core-concepts (culling with Rectangle).
Core Patterns
Point and ObservablePoint
Point is a simple {x, y} value type. ObservablePoint fires a callback when x or y changes; it is used internally by Container's position, scale, pivot, origin, and skew.
import { Point } from "pixi.js";
const p = new Point(10, 20);
p.set(30, 40);
p.set(50);
const clone = p.clone();
console.log(p.equals(clone));
p.copyFrom({ x: 1, y: 2 });
const temp = Point.shared;
temp.set(100, 200);
Container properties like position, scale, pivot, origin, and skew are ObservablePoints. Setting .x or .y on them triggers transform recalculation automatically.
import { Container } from "pixi.js";
const obj = new Container();
obj.position.set(100, 200);
obj.position.x = 150;
Matrix (2D affine transform)
Matrix represents a 3x3 affine transform: | a c tx | b d ty | 0 0 1 |. It supports translate, scale, rotate, append, prepend, invert, and decompose.
import { Matrix, Point } from "pixi.js";
const m = new Matrix()
.translate(100, 50)
.rotate(Math.PI / 4)
.scale(2, 2);
const local = new Point(10, 20);
const world = m.apply(local);
const backToLocal = m.applyInverse(world);
const a = new Matrix().translate(50, 0);
const b = new Matrix().rotate(Math.PI / 2);
a.append(b);
const transform = {
position: new Point(),
scale: new Point(),
pivot: new Point(),
skew: new Point(),
rotation: 0,
};
m.decompose(transform);
console.log(transform.rotation);
const temp = Matrix.shared;
const isDefault = m.equals(Matrix.IDENTITY);
Coordinate transforms via Container
Containers provide toGlobal, toLocal, and getGlobalPosition for coordinate conversion.
import { Container, Point } from "pixi.js";
const parent = new Container();
parent.position.set(100, 100);
parent.scale.set(2);
const child = new Container();
child.position.set(50, 50);
parent.addChild(child);
const globalPt = child.toGlobal(new Point(0, 0));
const localPt = child.toLocal(new Point(200, 200));
const other = new Container();
other.position.set(300, 300);
const ptInOther = child.toLocal(new Point(10, 10), other);
Shapes and hit testing
Rectangle, Circle, Ellipse, Polygon, RoundedRectangle, and Triangle all implement contains(x, y) for point-in-shape tests, plus getBounds(out?) and strokeContains(x, y, width, alignment?). They can be used as hitArea on containers for custom interaction regions.
import { Rectangle, Circle, Polygon, Container } from "pixi.js";
const rect = new Rectangle(0, 0, 200, 100);
rect.contains(50, 50);
rect.contains(300, 50);
rect.left;
rect.right;
rect.top;
rect.bottom;
rect.isEmpty();
const other = new Rectangle(50, 50, 100, 100);
rect.containsRect(other);
rect.intersects(other);
rect.intersects(other, matrix);
rect.strokeContains(0, 50, 4);
const circle = new Circle(100, 100, 50);
circle.strokeContains(150, 100, 4, 1);
const bounds = circle.getBounds();
const reused = new Rectangle();
new Polygon([0, 0, 100, 0, 50, 100]).getBounds(reused);
const button = new Container();
button.hitArea = new Rectangle(0, 0, 200, 50);
button.eventMode = "static";
button.on("pointerdown", () => {
});
Do not confuse native Rectangle.intersects(other) (returns boolean) with math-extras intersection(other) (returns a Rectangle describing the overlap area).
Rectangle layout helpers
Rectangle ships with mutating helpers used heavily in UI/layout, bounds aggregation, and pixel snapping. All return this for chaining.
import { Rectangle } from "pixi.js";
const r = new Rectangle(10, 10, 100, 50);
r.pad(5);
r.pad(10, 4);
r.scale(2);
const viewport = new Rectangle(0, 0, 200, 200);
new Rectangle(150, 150, 200, 200).fit(viewport);
const total = new Rectangle();
items.forEach((item) =>
total.enlarge(new Rectangle().copyFromBounds(item.getBounds())),
);
new Rectangle(10.2, 10.6, 100.8, 100.4).ceil();
new Rectangle().copyFromBounds(container.getBounds());
Polygon
Polygon accepts four constructor formats: a flat number array, an array of point-like objects, or either passed as spread arguments.
import { Polygon, Point } from "pixi.js";
new Polygon([0, 0, 100, 0, 50, 100]);
new Polygon([new Point(0, 0), new Point(100, 0), new Point(50, 100)]);
new Polygon(0, 0, 100, 0, 50, 100);
new Polygon(new Point(0, 0), new Point(100, 0), new Point(50, 100));
const poly = new Polygon([0, 0, 100, 0, 100, 100, 0, 100]);
poly.points;
poly.closePath;
poly.startX;
poly.lastX;
poly.isClockwise();
const outer = new Polygon([0, 0, 100, 0, 100, 100, 0, 100]);
const hole = new Polygon([25, 25, 75, 25, 75, 75, 25, 75]);
outer.containsPolygon(hole);
Constants
import { DEG_TO_RAD, RAD_TO_DEG, PI_2 } from "pixi.js";
const angle = 45 * DEG_TO_RAD;
const degrees = angle * RAD_TO_DEG;
const fullCircle = PI_2;
Types
PointData - minimal {x, y} interface accepted by most APIs. Use it when typing parameters that only need to read coordinates.
PointLike - extends PointData with set(), copyFrom(), copyTo(), equals(). Implemented by both Point and ObservablePoint.
Size - { width, height } interface used by renderer/canvas APIs.
SHAPE_PRIMITIVE - string literal union: 'rectangle' | 'circle' | 'ellipse' | 'polygon' | 'roundedRectangle' | 'triangle'. Every shape exposes type so you can branch without instanceof.
import type { PointData } from "pixi.js";
function distance(a: PointData, b: PointData): number {
const dx = a.x - b.x;
const dy = a.y - b.y;
return Math.sqrt(dx * dx + dy * dy);
}
math-extras (side-effect import)
import 'pixi.js/math-extras' adds methods to Point, ObservablePoint, and Rectangle via prototype extension. Not included in the default bundle.
import "pixi.js/math-extras";
import { Point } from "pixi.js";
Point / ObservablePoint vector methods
All methods accept an optional out parameter to avoid allocations. Without out, a new Point is returned.
const a = new Point(3, 4);
const b = new Point(1, 2);
const sum = a.add(b);
const diff = a.subtract(b);
const prod = a.multiply(b);
const scaled = a.multiplyScalar(2);
const dot = a.dot(b);
const cross = a.cross(b);
const len = a.magnitude();
const lenSq = a.magnitudeSquared();
const unit = a.normalize();
const proj = a.project(b);
const refl = a.reflect(new Point(0, 1));
const rotated = a.rotate(Math.PI / 2);
const out = new Point();
a.add(b, out);
Rectangle extended methods
containsRect and intersects are native Rectangle methods (see above). math-extras adds equals, intersection (returns the overlap rect), and union:
import "pixi.js/math-extras";
import { Rectangle } from "pixi.js";
const r1 = new Rectangle(0, 0, 100, 100);
const r2 = new Rectangle(50, 50, 100, 100);
r1.equals(r2);
const overlap = r1.intersection(r2);
const envelope = r1.union(r2);
const out = new Rectangle();
r1.intersection(r2, out);
Geometry utility functions
These functions are exported from pixi.js/math-extras, not the main pixi.js entry.
import {
floatEqual,
lineIntersection,
segmentIntersection,
} from "pixi.js/math-extras";
import { Point } from "pixi.js";