colorPicker3d
A colour as one row: tap the swatch, pick in a popup. The popup holds the color3d picker (saturation and value, hue, optional alpha) and a grid of presets, because most of the time the colour you want is one you have used before. After the swatches come two more squares: + saves the colour you are on, and the bin switches to taking swatches away (tap it, tap what should go, tap it again to stop). Saved swatches are shared by every picker on the page and kept in the browser. One row tall when closed, so a panel can carry a dozen colours without becoming a wall of pickers.
It is all SVG, like every control here, so it is the same thing on a flat panel and on one in a headset.
Demo
Three colours for a planet's bands and a translucent haze over them. Each row opens its own popup; the presets are the ones passed in, then a general set. The haze row keeps its alpha strip, the others turn it off.
import { panel3d, label3d, colorPicker3d } from 'tosijs-3d'
import { elements, tosi } from 'tosijs'
const { div } = elements
const { bandDemo } = tosi({ bandDemo: { zones: '#e9dcc1', belts: '#a9774c', accent: '#b4502f', haze: '#dfe9ff66' } })
const stripes = div({ class: 'stripes' })
const show = () => {
stripes.style.background = `linear-gradient(${[
bandDemo.zones.value, bandDemo.belts.value, bandDemo.zones.value,
bandDemo.accent.value, bandDemo.belts.value, bandDemo.zones.value,
].join(',')})`
}
// The haze has ALPHA: it is laid over the bands, and how much shows through
// is part of the colour.
const haze = div({ class: 'haze' })
stripes.append(haze)
const showHaze = () => { haze.style.background = bandDemo.haze.value }
for (const k of ['zones', 'belts', 'accent']) bandDemo[k].observe(show)
bandDemo.haze.observe(showHaze)
show()
showHaze()
const planetColours = ['#e9dcc1', '#a9774c', '#b4502f', '#e8d8ac', '#4a78dc', '#b4e6e8']
preview.append(
panel3d({ width: 300 },
label3d({ text: 'Bands' }),
colorPicker3d({ label: 'zones', value: bandDemo.zones, alpha: false, presets: planetColours }),
colorPicker3d({ label: 'belts', value: bandDemo.belts, alpha: false, presets: planetColours }),
colorPicker3d({ label: 'accent', value: bandDemo.accent, alpha: false, presets: planetColours }),
// alpha is on unless you turn it off: a second strip in the picker, and
// the value becomes #rrggbbaa.
colorPicker3d({ label: 'haze (with alpha)', value: bandDemo.haze }),
),
stripes,
)
.preview { display: flex; gap: 16px; padding: 12px; min-height: 500px; align-items: flex-start; }
.stripes { width: 120px; height: 180px; border-radius: 60px; flex: none; overflow: hidden; }
.haze { width: 100%; height: 100%; }
Options
| Option | Default | |
|---|---|---|
label |
'' |
The caption on the row |
value |
'#ffffff' |
A colour, or a reactive value holding one |
alpha |
true |
Offer the alpha strip. Off, the value is always #rrggbb |
presets |
Colours offered first in the popup: hex strings, or { name, value } |
|
defaultPresets |
'on' |
'off' leaves out the general set, showing only yours |
swatches |
shared | Where + saves to. Unset, one store for the page, kept in localStorage under tosijs-3d:color-swatches. Pass createSwatchStore(yourStorage) to keep them yourself, or null to keep nothing |
handleChange |
Live, including mid-drag. Canonical hex | |
handleCommit |
Once per gesture or preset, with the settled value: one undo step |