Add WIP palette support
parent
2afd2ff119
commit
d2b90298cd
|
@ -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;
|
||||
|
|
|
@ -35,6 +35,16 @@
|
|||
lastFile = file
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue