palette
This commit is contained in:
parent
d0099fbf19
commit
815ef5c23f
10 changed files with 256 additions and 131 deletions
|
@ -38,7 +38,6 @@ type Rgbs = Record<Color.Layer, Rgb>;
|
|||
let rgbBuf = new OffscreenCanvas(1, 1).getContext('2d')!;
|
||||
|
||||
function toRgb(col: Color.Oklch): Rgb {
|
||||
// :)
|
||||
rgbBuf.fillStyle = col.css();
|
||||
rgbBuf.fillRect(0, 0, 1, 1);
|
||||
const rgb = rgbBuf.getImageData(0, 0, 1, 1).data;
|
||||
|
@ -49,6 +48,14 @@ function toRgbs(col: Color.Colors): Rgbs {
|
|||
return Color.makeColorInfo(l => toRgb(col[l]));
|
||||
}
|
||||
|
||||
function toHex([r, g, b]: Rgb): string {
|
||||
function chan(n: number) {
|
||||
let a = Math.floor(n).toString(16);
|
||||
return a.length == 1 ? `0${a}` : a;
|
||||
}
|
||||
return `#${chan(r)}${chan(g)}${chan(b)}`;
|
||||
}
|
||||
|
||||
|
||||
function setImageDataRgb({ data }: ImageData, [r, g, b]: Rgb, a: number = -1) {
|
||||
for (let i = 0; i < data.length; i += 4) {
|
||||
|
@ -84,7 +91,6 @@ async function loadSide(buf: OffscreenCanvasRenderingContext2D,
|
|||
await Promise.all(
|
||||
allLayers.map(l => load(buf, side, l).then(res => [l, res])))
|
||||
) as Record<Layer, ImageData>;
|
||||
console.log(images);
|
||||
for (const l of allLayers) {
|
||||
layers[l] = { data: images[l], pos: pos[l] };
|
||||
}
|
||||
|
@ -131,7 +137,7 @@ function message(msg: string, ctx: CanvasRenderingContext2D) {
|
|||
ctx.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
ctx.font = 'bold 100px Muller, sans-serif';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText(msg, WIDTH/2, HEIGHT/2);
|
||||
ctx.fillText(msg, WIDTH/2, HEIGHT/2, WIDTH-10);
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
|
@ -167,13 +173,14 @@ class Side {
|
|||
layers() { return this.cur == 'front' ? this.fronts : this.backs; }
|
||||
|
||||
async recolorOn(ctx: CanvasRenderingContext2D,
|
||||
buf: OffscreenCanvasRenderingContext2D) {
|
||||
buf: OffscreenCanvasRenderingContext2D):
|
||||
Promise<[Color.Colors, Rgbs]> {
|
||||
const cols = Color.colors();
|
||||
const rgbs = toRgbs(cols);
|
||||
setColors(rgbs, this.fronts);
|
||||
setColors(rgbs, this.backs);
|
||||
await redraw(ctx, buf, this.layers());
|
||||
return cols.outer.h;
|
||||
return [cols, rgbs];
|
||||
}
|
||||
|
||||
async ensureComposed(buf: OffscreenCanvasRenderingContext2D) {
|
||||
|
@ -187,15 +194,53 @@ function setBg(hue: number) {
|
|||
}
|
||||
|
||||
|
||||
function getPalette(): XMLDocument | null {
|
||||
const palette = document.getElementById('palette') as HTMLObjectElement;
|
||||
return palette.contentDocument;
|
||||
}
|
||||
|
||||
function setPalette(oklch: Color.Colors, rgb: Rgbs) {
|
||||
const palette = getPalette();
|
||||
|
||||
if (!palette) {
|
||||
setTimeout(() => setPalette(oklch, rgb), 500);
|
||||
return;
|
||||
}
|
||||
|
||||
palette.documentElement.style.setProperty('--hue', `${oklch.outer.h}`);
|
||||
console.log(palette);
|
||||
|
||||
for (const l of Color.allLayers) {
|
||||
let col = toHex(rgb[l]);
|
||||
|
||||
const swatch = palette.getElementById(`s-${l}`);
|
||||
if (swatch) swatch.style.fill = col;
|
||||
|
||||
const text = palette.getElementById(`c-${l}`);
|
||||
if (text) text.innerHTML = col;
|
||||
|
||||
const bg = palette.getElementById(`p-${l}`);
|
||||
if (bg) bg.style.fill = col;
|
||||
|
||||
const item = palette.getElementById(`i-${l}`);
|
||||
if (item) {
|
||||
const textCol = oklch[l].l < 0.6 ? 'white' : 'black';
|
||||
item.style.setProperty('--text', textCol);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function animateReroll(ctx1: CanvasRenderingContext2D,
|
||||
ctx2: CanvasRenderingContext2D,
|
||||
buf: OffscreenCanvasRenderingContext2D,
|
||||
side: Side,
|
||||
done: () => void) {
|
||||
side: Side, done: () => void) {
|
||||
const duration = 200;
|
||||
const hue = await side.recolorOn(ctx2, buf);
|
||||
const [oklch, rgb] = await side.recolorOn(ctx2, buf);
|
||||
ctx2.canvas.style.animation = `${duration}ms ease fade-in`;
|
||||
setBg(hue);
|
||||
setBg(oklch.outer.h);
|
||||
setPalette(oklch, rgb);
|
||||
setTimeout(finish, duration);
|
||||
|
||||
async function finish() {
|
||||
|
@ -255,8 +300,9 @@ document.addEventListener('DOMContentLoaded', async function() {
|
|||
throw err;
|
||||
});
|
||||
|
||||
let hue = await side.recolorOn(picCtx, buf);
|
||||
setBg(hue);
|
||||
let [oklch, rgb] = await side.recolorOn(picCtx, buf);
|
||||
setBg(oklch.outer.h);
|
||||
setPalette(oklch, rgb);
|
||||
await redraw(picCtx, buf, side.layers());
|
||||
|
||||
const reroll = document.getElementById('reroll')!;
|
||||
|
@ -264,6 +310,19 @@ document.addEventListener('DOMContentLoaded', async function() {
|
|||
|
||||
addListeners();
|
||||
|
||||
type Done = (finish: () => void) => void;
|
||||
|
||||
function handleReroll(e: Event) {
|
||||
wrap(reroll,
|
||||
done => animateReroll(picCtx, pic2Ctx, buf, side, done),
|
||||
'reroll', e);
|
||||
}
|
||||
|
||||
function handleSwap(e: Event) {
|
||||
wrap(swap, done => animateSwap(picCtx, pic2Ctx, side, buf, done),
|
||||
'swap', e);
|
||||
}
|
||||
|
||||
function addListeners() {
|
||||
reroll.addEventListener('click', handleReroll);
|
||||
swap.addEventListener('click', handleSwap);
|
||||
|
@ -274,19 +333,7 @@ document.addEventListener('DOMContentLoaded', async function() {
|
|||
swap.removeEventListener('click', handleSwap);
|
||||
}
|
||||
|
||||
function handleReroll(e: Event) {
|
||||
wrap(reroll, done => animateReroll(picCtx, pic2Ctx, buf, side, done),
|
||||
'reroll', e);
|
||||
}
|
||||
|
||||
function handleSwap(e: Event) {
|
||||
wrap(swap, done => animateSwap(picCtx, pic2Ctx, side, buf, done),
|
||||
'swap', e);
|
||||
}
|
||||
|
||||
type Handler = (finish: () => void) => void;
|
||||
|
||||
function wrap(elem: Element, f: Handler, name: string, e: Event) {
|
||||
function wrap(elem: Element, f: Done, name: string, e: Event) {
|
||||
if (elem != e.target) return;
|
||||
e.stopPropagation();
|
||||
if (isRunning()) return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue