Colour pickers
Hue rings, a colour wheel, an OKLCH plane, channel sliders, swatches, a radial swatch popup and an eyedropper for PixiJS, all editing one colour model.
Updated pixi-silk 1.0.1View as Markdown
Every picker in pixi-silk/ui/color edits a ColorModel. Pickers that share a model stay in sync.
Share one colour between pickers#
import { ColorModel, ColorWheel, HueTrianglePicker, SwatchPalette } from 'pixi-silk/ui/color';
declare const brush: { tint: number };
declare function save(color: number): void;
const model = new ColorModel({ color: 0x30d158 });
const triangle = new HueTrianglePicker({ model, size: 220 });
const wheel = new ColorWheel({ model, size: 196 });
const recent = new SwatchPalette({ model });
model.value.subscribe(() => (brush.tint = model.hex));
model.committed.subscribe(() => save(model.hex));
model.value changes on every move of a drag, so the brush follows live. When a drag ends, the
picker calls commit(). That adds the colour to model.history and bumps committed, so save
runs once per release. A SwatchPalette with no colors shows that history.
The model stores hue, saturation, value and alpha. The hue therefore survives greys and black,
where RGB would lose it. hex, rgb and oklch read the colour, and setHex(), setRgb(),
setHsv() and setOklch() write it.
| Option | Default | What it does |
|---|---|---|
color | 0x0a84ff | Starting colour. |
alpha | 1 | Starting alpha. |
historySize | 16 | How many committed colours history keeps. |
Pick a picker#
| Class | What it shows |
|---|---|
HueTrianglePicker | A hue ring around a triangle with the pure hue, white and black at its corners. The triangle turns to face its hue. |
HueSquarePicker | A hue ring around a saturation and value square. |
ColorWheel | Hue around a disc, saturation from the centre out, value on a strip beside it. |
OklchPicker | Lightness against chroma for one OKLCH hue, plus a hue strip. |
ColorSlider, ChannelSliders | Gradient tracks for HSV, RGB, OKLCH and alpha. Each track shows what its positions would give with the rest of the colour unchanged. |
SwatchPalette | Fixed colours or the recent ones, as a grid or a ring. |
SwatchPopup | A ring of swatches that opens around the pointer. |
Eyedropper | Samples the scene through a function you supply. |
A drag belongs to the part it started on. A drag that starts on the ring only turns the hue, even when it crosses the square.
Pick in OKLCH#
import { ChannelSliders, ColorModel, OklchPicker } from 'pixi-silk/ui/color';
const model = new ColorModel();
const plane = new OklchPicker({ model, width: 260, height: 180 });
const sliders = new ChannelSliders({ model, mode: 'oklch' });
OKLCH is lightness, chroma and hue in a space built to match how colours look. Moving lightness
does not shift the hue, and equal steps look equal. Not every OKLCH colour fits on a screen. The
picker greys out the part outside sRGB and draws its edge, and a drag into the grey part slides
along that edge. ChannelSliders also takes mode: 'hsv' or 'rgb', with an alpha track by
default.
Pick from swatches or the scene#
import type { Container } from 'pixi.js';
import { ColorModel, Eyedropper, SwatchPopup } from 'pixi-silk/ui/color';
declare const artwork: Container, pipette: Container;
declare function colorAt(x: number, y: number): number | null;
const model = new ColorModel();
const popup = new SwatchPopup({ model, colors: [0xff453a, 0xffd60a, 0x30d158, 0x0a84ff] });
const dropper = new Eyedropper({ model, sample: (x, y) => colorAt(x, y) });
artwork.on('pointerdown', (e) => popup.openAt(e.global.x, e.global.y, e));
pipette.on('pointertap', () => dropper.start());
The swatch popup works like the radial menu: press, drag towards a colour and let go, or tap to keep it open.
The eyedropper does not read pixels itself, because your app knows its scene better. The sampler
can be a texture lookup, renderer.extract on a render target or plain maths. A click picks,
and Escape or a right click cancels.
How the colours are drawn#
The pickers draw with pixi-silk gradients. Hue rings are conic gradients interpolated in sRGB, so every angle is an exact HSV hue. The square and the wheel layer white and black ramps. The OKLCH plane is drawn row by row, and chroma along a row is a straight line in OKLab, so each row is exact.
API reference: ColorModel, HueTrianglePicker, HueSquarePicker, ColorWheel, OklchPicker, ChannelSliders, SwatchPalette, SwatchPopup, Eyedropper