Claude
Skills
Sign in
Back

pixijs-scene-graphics

Included with Lifetime
$97 forever

Use this skill when drawing vector shapes and paths in PixiJS v8. Covers the Graphics API: shape-then-fill methods (rect/circle/ellipse/poly/roundRect/star/regularPoly/roundPoly/roundShape/filletRect/chamferRect), path methods (moveTo/lineTo/bezierCurveTo/quadraticCurveTo/arc/arcTo/arcToSvg/closePath), fill/stroke/cut, holes, FillGradient (linear/radial), FillPattern, GraphicsContext sharing, svg import/export, containsPoint hit testing, cloning, clearing, bounds, fillStyle/strokeStyle, draw-time transforms (rotateTransform/scaleTransform/translateTransform/setTransform/save/restore), default styles, GraphicsPath reuse. Triggers on: Graphics, GraphicsContext, rect, circle, poly, roundRect, fill, stroke, cut, hole, beginHole, FillGradient, FillPattern, moveTo, bezierCurveTo, svg, graphicsContextToSvg, svg export, GraphicsOptions, containsPoint, clone, clear, bounds, rotateTransform, translateTransform, setFillStyle, setStrokeStyle, GraphicsPath.

Backend & APIs

What this skill does


`Graphics` is the vector-drawing leaf of the PixiJS v8 scene graph. The v8 API follows a shape-then-style pattern: draw a shape or path with `rect`, `circle`, `moveTo`, etc., then apply `fill` and/or `stroke`. Every method returns `this` for chaining, and the drawing instructions live on a `GraphicsContext` that can be shared between instances.

Assumes familiarity with `pixijs-scene-core-concepts`. `Graphics` is a leaf: do not nest children inside it. Wrap multiple `Graphics` objects in a `Container` to group them.

## Quick Start

```ts
const g = new Graphics();

g.rect(10, 10, 200, 100)
  .fill({ color: 0x3498db, alpha: 0.8 })
  .stroke({ width: 3, color: 0x2c3e50 });

g.circle(300, 60, 40).fill(0xe74c3c);

g.moveTo(50, 200)
  .lineTo(200, 200)
  .bezierCurveTo(250, 250, 100, 300, 50, 250)
  .closePath()
  .fill(0x6c5ce7);

app.stage.addChild(g);
```

**Related skills:** `pixijs-scene-core-concepts` (scene graph basics), `pixijs-scene-container` (group graphics with other objects), `pixijs-scene-core-concepts/references/masking.md` (Graphics as a stencil mask), `pixijs-filters` (effects), `pixijs-performance` (batching, `cacheAsTexture`).

## Constructor options

All `Container` options (`position`, `scale`, `tint`, `label`, `filters`, `zIndex`, etc.) are also valid here — see `skills/pixijs-scene-core-concepts/references/constructor-options.md`.

Leaf-specific options added by `GraphicsOptions`:

| Option        | Type              | Default                 | Description                                                                                                                                                                                          |
| ------------- | ----------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `context`     | `GraphicsContext` | new `GraphicsContext()` | Shared drawing context. Passing a context reuses its tessellated geometry across multiple `Graphics` nodes, avoiding duplicate GPU work. If omitted, each `Graphics` creates and owns a new context. |
| `roundPixels` | `boolean`         | `false`                 | Rounds the final on-screen `x`/`y` to the nearest pixel. Produces crisper lines for pixel-art styles at the cost of smooth sub-pixel movement.                                                       |

The constructor also accepts a `GraphicsContext` instance as its sole argument (`new Graphics(ctx)`), which is shorthand for `new Graphics({ context: ctx })`.

## Core Patterns

### Shape-then-fill workflow

```ts
const g = new Graphics();

g.rect(10, 10, 200, 100)
  .fill({ color: 0x3498db, alpha: 0.8 })
  .stroke({ width: 3, color: 0x2c3e50 });

g.circle(150, 200, 40).fill(0xe74c3c);
g.roundRect(300, 10, 150, 80, 12).fill(0x2ecc71);
g.poly([0, 0, 60, 0, 30, 50], true).fill(0x9b59b6);
g.star(400, 200, 5, 40, 20, 0).fill(0xf39c12);
g.ellipse(100, 350, 60, 30).fill(0x1abc9c);
```

`fill()` accepts a `FillInput`: a color number/string, `{ color, alpha, texture, matrix, textureSpace }`, a `FillGradient`, a `FillPattern`, or a `Texture`. When filling with a texture, `textureSpace` controls coordinate mapping:

- `'local'` (default): texture is scaled to fit each shape's bounding box (normalized 0-1 coordinates).
- `'global'`: texture position/scale are relative to the Graphics object's coordinate system, shared across all shapes.

`FillInput` also supports a nested `fill` subfield: a `FillStyle` options object can embed a `FillGradient` or `FillPattern` under its `fill` key, which applies the gradient or pattern alongside the `color`, `alpha`, `texture`, and `matrix` modifiers on the outer object.

`stroke()` accepts a color, a `FillGradient`, a `FillPattern`, or a `StrokeStyle` object that combines all `FillStyle` keys (`color`, `alpha`, `texture`, `matrix`, `fill`, `textureSpace`) with stroke attributes:

| Attribute    | Default   | Notes                                                                   |
| ------------ | --------- | ----------------------------------------------------------------------- |
| `width`      | `1`       | Pixel width of the stroke.                                              |
| `cap`        | `'butt'`  | One of `'butt'`, `'round'`, `'square'`. End style for open paths.       |
| `join`       | `'miter'` | One of `'miter'`, `'round'`, `'bevel'`. Corner style.                   |
| `miterLimit` | `10`      | Caps how far miter joins extend before falling back to bevel.           |
| `alignment`  | `0.5`     | `1` = inside the shape, `0.5` = centered, `0` = outside.                |
| `pixelLine`  | `false`   | Aligns 1-pixel lines to the pixel grid for crisp output. Graphics-only. |

Strokes can use the same gradients and patterns as fills via `fill: gradient` or `texture: tex`:

```ts
const grad = new FillGradient({
  end: { x: 1, y: 0 },
  colorStops: [
    { offset: 0, color: 0xff0000 },
    { offset: 1, color: 0x0000ff },
  ],
});
g.rect(0, 0, 200, 100).stroke({
  width: 8,
  fill: grad,
  join: "round",
  cap: "round",
});
```

Both `fill()` and `stroke()` can be called after the same shape; calling `stroke()` immediately after `fill()` reuses the same path.

### Advanced shape primitives

```ts
g.regularPoly(100, 100, 50, 6, 0).fill(0x3498db);
g.roundPoly(250, 100, 50, 5, 10).fill(0xe74c3c);
g.chamferRect(350, 50, 100, 80, 15).fill(0x2ecc71);
g.filletRect(500, 50, 100, 80, 15).fill(0x9b59b6);
g.roundShape(
  [
    { x: 50, y: 250, radius: 20 },
    { x: 150, y: 250, radius: 5 },
    { x: 150, y: 350, radius: 10 },
    { x: 50, y: 350, radius: 15 },
  ],
  10,
).fill(0xf39c12);
```

### Holes with cut()

```ts
g.rect(0, 0, 200, 200).fill(0x00ff00).circle(100, 100, 50).cut();
```

`cut()` subtracts the current active path from the previously drawn fill or stroke. Rules:

- The hole must be **completely inside** the target shape. Holes that overlap edges or sit outside the shape will not render correctly because the renderer triangulates with the hole as an interior boundary.
- `cut()` looks back at up to the **last two** instructions. When you `fill()` and then `stroke()` the same path, a single `cut()` adds the hole to the stroke first; a second `cut()` adds it to the fill underneath.
- After `cut()`, the active path resets so you can start the next shape with `moveTo`, `rect`, etc.
- `cut()` applies to strokes too — `g.rect(...).stroke(...).circle(...).cut()` cuts a hole through the stroke outline.

Punch multiple holes with a single `cut()` by drawing several shapes into the active path before calling it. Each shape accumulates into the same hole path:

```ts
const g = new Graphics();

g.rect(350, 350, 150, 150).fill(0x00ff00);

// Draw three circles into the active path, then cut them all in one call
g.circle(375, 375, 25);
g.circle(425, 425, 25);
g.circle(475, 475, 25);
g.cut();
```

If you need holes on **separate** filled shapes, give each shape its own `fill()` and matching `cut()`:

```ts
g.rect(0, 0, 100, 100).fill(0x3498db);
g.circle(50, 50, 20).cut(); // hole in the rect

g.rect(120, 0, 100, 100).fill(0xe74c3c);
g.circle(170, 50, 20).cut(); // hole in the second rect
```

Calling `cut()` on a shape that already has a hole **adds** to the existing hole path rather than replacing it. Use this to layer holes additively.

### Paths and complex shapes

```ts
g.moveTo(50, 50)
  .lineTo(200, 50)
  .bezierCurveTo(250, 100, 250, 150, 200, 200)
  .quadraticCurveTo(100, 250, 50, 200)
  .closePath()
  .fill({ color: 0x6c5ce7, alpha: 0.7 })
  .stroke({ width: 2, color: 0xdfe6e9 });
```

Path methods: `moveTo`, `lineTo`, `bezierCurveTo`, `quadraticCurveTo`, `arc`, `arcTo`, `arcToSvg`, `closePath`. Call `beginPath()` to discard the current path and start a new one.

```ts
// arc(cx, cy, radius, startAngle, endAngle, counterclockwise?)
g.moveTo(80, 50)
  .arc(50, 50, 30, 0, Math.PI)
  .stro

Related in Backend & APIs