Skip to content
GitHub repository
Getting started

Quick start

Create a DPR-exact PixiJS app with createSilkApp, then draw a squircle card, a gradient gauge and an area chart with SilkGraphics.

Updated pixi-silk 0.1.0

Build the card below: a squircle background, a gauge whose conic gradient follows the arc, and a smoothed area chart with a fading fill.

Source src/demos/quick-start.demo.ts
import { conic, SilkGraphics, vertical } from 'pixi-silk';
import { defineDemo } from './runtime';

const GAUGE = conic([0x30d158, 0xffd60a, 0xff453a]);
const FILL = vertical(
    [
        [0, 0xff9f0a, 0.8],
        [1, 0xff9f0a, 0],
    ],
    { easing: 'smooth' },
);

export default defineDemo({
    size: [360, 160],
    controls: {
        progress: { type: 'range', label: 'progress', min: 0, max: 1, step: 0.01, value: 0.72 },
    },
    setup({ stage, params, tick }) {
        const g = new SilkGraphics();

        stage.addChild(g);
        tick((t) => {
            const wave = [120, 100, 170, 80, 220, 92, 270, 60, 320, 70].map((v, i) =>
                i % 2 ? v + Math.sin(t + i) * 6 : v,
            );

            g.clear();
            g.roundRect(10, 10, 340, 140, 22, 0.6).fill(0x1c1c1e); // squircle card
            g.arcSweep(80, 80, 44, -Math.PI / 2, Math.PI * 2).stroke({ width: 12, color: 0x2c2c2e });
            g.arcSweep(80, 80, 44, -Math.PI / 2, Math.PI * 2 * params.progress).stroke({
                width: 12,
                cap: 'round',
                gradient: GAUGE,
            }); // gauge follows the arc
            g.area(wave, 130, { smooth: 'monotone' })
                .fill(FILL) // chart fill ...
                .stroke({ width: 2, color: 0xff9f0a, cap: 'round' }); // ... and its top line
        });
    },
});

1. Create the application#

createSilkApp is a thin wrapper around new Application() and app.init(). It sizes the canvas in device pixels and turns MSAA off, because Silk’s anti-aliasing is analytic.

import { createSilkApp } from 'pixi-silk';

const { app } = await createSilkApp({
    parent: document.getElementById('stage')!, // the canvas fills this element
    background: 0x000000,
});

You can also keep your own Application. See Resolution & DPR for the settings that matter.

2. Draw#

SilkGraphics works like Pixi’s Graphics. Add shapes to the active path, then fill() or stroke() them. Calls chain.

import { SilkGraphics, conic, vertical } from 'pixi-silk';

const GAUGE = conic([0x30d158, 0xffd60a, 0xff453a]); // spans whatever arc it is drawn on
const g = new SilkGraphics();

g.roundRect(10, 10, 340, 140, 22, 0.6).fill(0x1c1c1e); // radius 22, squircle smoothing 0.6
g.arcSweep(80, 80, 44, -Math.PI / 2, Math.PI * 1.5).stroke({ width: 12, cap: 'round', gradient: GAUGE });
g.area([120, 100, 170, 80, 220, 92, 270, 60, 320, 70], 130, { smooth: 'monotone' })
    .fill(vertical([[0, 0xff9f0a, 0.8], [1, 0xff9f0a, 0]]))
    .stroke({ width: 2, color: 0xff9f0a, cap: 'round' });   // stroke right after fill draws the top line

app.stage.addChild(g);

3. Animate#

Redrawing every frame is cheap. clear() keeps the GPU buffers, and all primitives go out in one instanced draw call.

app.ticker.add((ticker) => {
    const t = ticker.lastTime / 1000;

    g.clear();
    g.arcSweep(80, 80, 44, -Math.PI / 2, Math.PI * 2 * (0.5 + 0.4 * Math.sin(t)))
        .stroke({ width: 12, cap: 'round', gradient: GAUGE });
});

Next steps#

API reference: createSilkApp, SilkGraphics, conic, vertical