Add WIP palette support

main
kts of kettek 2024-02-22 01:22:36 -08:00
parent 2afd2ff119
commit d2b90298cd
3 changed files with 70 additions and 27 deletions

View File

@ -9,7 +9,7 @@
import { LoadedFile, PixelsPlaceUndoable, SelectionClearUndoable, SelectionSetUndoable } from './types/file'
import "carbon-components-svelte/css/all.css"
import { Tabs, Tab, TabContent, Theme, Button, Modal, Truncate, ButtonSet, NumberInput } from "carbon-components-svelte"
import { Tabs, Tab, TabContent, Theme, Button, Modal, Truncate, ButtonSet, NumberInput, Dropdown } from "carbon-components-svelte"
import { ComposedModal } from "carbon-components-svelte"
import { OverflowMenu, OverflowMenuItem } from "carbon-components-svelte"
@ -44,6 +44,23 @@
let alpha: number = 0
let refreshPalette = {}
let fakePalette: Uint32Array | undefined = undefined
let selectedPaletteID: number = 0
$: {
if (selectedPaletteID === 0) {
fakePalette = undefined
} else if (selectedPaletteID === 1) {
fakePalette = new Uint32Array([
0xFFE0F8D0, 0xFF88C070, 0xFF346856, 0xFF081820,
0xFFF8F8F8, 0xFFC0C0C0, 0xFF606060, 0xFF202020,
0xFFF8D8F8, 0xFFA800A8, 0xFF503050, 0xFF200020,
0xFFF8B8F8, 0xFFA800A8, 0xFF503050, 0xFF200020,
])
}
focusedFile?.canvas.setFakePalette(fakePalette)
focusedFile?.canvas.refreshImageData()
focusedFile?.canvas.refreshCanvas()
}
// Oh no, what are you doing, step palette~
function stepPalette(step: number, primary: boolean) {
@ -189,7 +206,15 @@
</menu>
<section class='content'>
<section class='left'>
<PaletteSection refresh={refreshPalette} bind:primaryColorIndex bind:secondaryColorIndex file={focusedFile} on:select={handlePaletteSelect} />
<Dropdown
size="sm"
bind:selectedId={selectedPaletteID}
items={[
{ id: 0, text: "<image>"},
{ id: 1, text: "test palette"},
]}
/>
<PaletteSection refresh={refreshPalette} bind:primaryColorIndex bind:secondaryColorIndex file={focusedFile} fakePalette={fakePalette} on:select={handlePaletteSelect} />
<article>
<ColorSelector bind:red bind:green bind:blue bind:alpha />
<ColorIndex bind:red bind:green bind:blue bind:alpha index={primaryColorIndex} file={focusedFile} on:refresh={()=>refreshPalette={}} />
@ -302,7 +327,7 @@
}
.left {
display: grid;
grid-template-rows: minmax(0, 1fr) auto;
grid-template-rows: auto minmax(0, 1fr) auto;
}
.toolbar {
display: flex;

View File

@ -36,6 +36,16 @@
}
}
export let fakePalette: Uint32Array | undefined
let palette: Uint32Array | undefined[]
$: {
if (fakePalette) {
palette = fakePalette
} else {
palette = file ? file.canvas.palette : []
}
}
function paletteClick(event: MouseEvent) {
const target = event.target as HTMLSpanElement
const index = parseInt(target.getAttribute('x-index') || '0')
@ -48,16 +58,15 @@
}
}
function handleWheel(event: WheelEvent) {
if (!file) return
if (event.deltaX < 0) {
secondaryColorIndex = (secondaryColorIndex - 1 + file.canvas.palette.length) % file.canvas.palette.length
secondaryColorIndex = (secondaryColorIndex - 1 + palette.length) % palette.length
} else if (event.deltaX > 0) {
secondaryColorIndex = (secondaryColorIndex + 1) % file.canvas.palette.length
secondaryColorIndex = (secondaryColorIndex + 1) % palette.length
}
if (event.deltaY < 0) {
primaryColorIndex = (primaryColorIndex - 1 + file.canvas.palette.length) % file.canvas.palette.length
primaryColorIndex = (primaryColorIndex - 1 + palette.length) % palette.length
} else if (event.deltaY > 0) {
primaryColorIndex = (primaryColorIndex + 1) % file.canvas.palette.length
primaryColorIndex = (primaryColorIndex + 1) % palette.length
}
}
@ -118,24 +127,22 @@
</script>
<main on:wheel={handleWheel}>
{#if file}
{#each file.canvas.palette as palette, paletteIndex}
{#if draggingIndex !== -1 && (paletteIndex === hoveringIndex || (paletteIndex === hoveringIndex-1 && paletteIndex === file.canvas.palette.length-2))}
<span class="entry primary">
<span class="checkerboard"></span>
<span style="background-color: rgba({file.canvas.palette[draggingIndex]&0xFF},{(file.canvas.palette[draggingIndex]>>8)&0xFF},{(file.canvas.palette[draggingIndex]>>16)&0xFF},{((file.canvas.palette[draggingIndex]>>24)&0xFF)/255})" class="color"></span>
<span class='label'>{draggingIndex}</span>
</span>
{/if}
{#if paletteIndex !== draggingIndex}
<span on:click={paletteClick} x-index={paletteIndex} class='entry{paletteIndex===primaryColorIndex?' primary':''}{paletteIndex===secondaryColorIndex?' secondary':''}{paletteIndex===draggingIndex?' hide':''}' use:swatchDrag>
<span class="checkerboard"></span>
<span style="background-color: rgba({palette&0xFF},{(palette>>8)&0xFF},{(palette>>16)&0xFF},{((palette>>24)&0xFF)/255})" class="color"></span>
<span class='label'>{paletteIndex}</span>
</span>
{/if}
{/each}
{/if}
{#each palette as swatch, swatchIndex}
{#if draggingIndex !== -1 && (swatchIndex === hoveringIndex || (swatchIndex === hoveringIndex-1 && swatchIndex === palette.length-1))}
<span class="entry primary">
<span class="checkerboard"></span>
<span style="background-color: rgba({palette[draggingIndex]&0xFF},{(palette[draggingIndex]>>8)&0xFF},{(palette[draggingIndex]>>16)&0xFF},{((palette[draggingIndex]>>24)&0xFF)/255})" class="color"></span>
<span class='label'>{draggingIndex}</span>
</span>
{/if}
{#if swatchIndex !== draggingIndex}
<span on:click={paletteClick} x-index={swatchIndex} class='entry{swatchIndex===primaryColorIndex?' primary':''}{swatchIndex===secondaryColorIndex?' secondary':''}{swatchIndex===draggingIndex?' hide':''}' use:swatchDrag>
<span class="checkerboard"></span>
<span style="background-color: rgba({swatch&0xFF},{(swatch>>8)&0xFF},{(swatch>>16)&0xFF},{((swatch>>24)&0xFF)/255})" class="color"></span>
<span class='label'>{swatchIndex}</span>
</span>
{/if}
{/each}
</main>
<style>

View File

@ -4,6 +4,7 @@ export class Canvas {
width: number
height: number
palette: Uint32Array // 32-bit RGBA palette
fakePalette: Uint32Array // 32-bit RGBA palette
pixels: Uint8Array // 8-bit indices into the palette
public isIndexed: boolean = false
canvas: HTMLCanvasElement
@ -199,9 +200,19 @@ export class Canvas {
}
this.palette[to] = temp
}
setFakePalette(palette: Uint32Array | undefined) {
this.fakePalette = palette
}
refreshImageData() {
let palette = this.palette
if (this.fakePalette) {
palette = this.fakePalette
}
for (let i = 0; i < this.pixels.length; i++) {
let color = this.palette[this.pixels[i]]
let color: number = 0
if (this.pixels[i] < palette.length) {
color = palette[this.pixels[i]]
}
this.imageData.data[i * 4 + 0] = color & 0xFF
this.imageData.data[i * 4 + 1] = (color >> 8) & 0xFF
this.imageData.data[i * 4 + 2] = (color >> 16) & 0xFF