Add partially broken swatch moving
parent
4fea100ddb
commit
bd4a88f1db
|
@ -1,6 +1,6 @@
|
|||
<script lang='ts'>
|
||||
import type { Color } from '../types/palette'
|
||||
import { ReplaceSwatchUndoable, type LoadedFile, AddSwatchUndoable } from '../types/file'
|
||||
import { ReplaceSwatchUndoable, type LoadedFile, AddSwatchUndoable, MoveSwatchUndoable } from '../types/file'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import type { Undoable } from '../types/undo'
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
|||
const dispatch = createEventDispatcher()
|
||||
|
||||
const fileChanged = (item: Undoable<LoadedFile>) => {
|
||||
if (item instanceof ReplaceSwatchUndoable || item instanceof AddSwatchUndoable) {
|
||||
if (item instanceof ReplaceSwatchUndoable || item instanceof AddSwatchUndoable || item instanceof MoveSwatchUndoable) {
|
||||
file = file
|
||||
}
|
||||
}
|
||||
|
@ -59,15 +59,78 @@
|
|||
primaryColorIndex = (primaryColorIndex + 1) % file.canvas.palette.length
|
||||
}
|
||||
}
|
||||
|
||||
let draggingIndex: number = -1
|
||||
let hoveringIndex: number = -1
|
||||
function swatchDrag(node) {
|
||||
let index = parseInt(node.getAttribute('x-index') || '-1')
|
||||
let x = 0
|
||||
let y = 0
|
||||
let dx = 0
|
||||
let dy = 0
|
||||
node.addEventListener('mousedown', start)
|
||||
|
||||
function start(e: MouseEvent) {
|
||||
e.preventDefault()
|
||||
x = e.clientX
|
||||
y = e.clientY
|
||||
|
||||
window.addEventListener('mouseup', stop)
|
||||
window.addEventListener('mouseleave', stop)
|
||||
window.addEventListener('mousemove', move)
|
||||
}
|
||||
function stop(e: MouseEvent) {
|
||||
if (hoveringIndex !== -1 && hoveringIndex !== draggingIndex) {
|
||||
file.push(new MoveSwatchUndoable(draggingIndex, hoveringIndex))
|
||||
file = file
|
||||
}
|
||||
|
||||
draggingIndex = -1
|
||||
hoveringIndex = -1
|
||||
window.removeEventListener('mouseup', stop)
|
||||
window.removeEventListener('mouseleave', stop)
|
||||
window.removeEventListener('mousemove', move)
|
||||
}
|
||||
function move(e: MouseEvent) {
|
||||
dx += e.clientX - x
|
||||
dy += e.clientY - y
|
||||
|
||||
x = e.clientX
|
||||
y = e.clientY
|
||||
|
||||
if (Math.abs(dx)+Math.abs(dy) < 5) {
|
||||
return
|
||||
}
|
||||
draggingIndex = index
|
||||
|
||||
for (let i = 0; i < file.canvas.palette.length; i++) {
|
||||
const entry = document.querySelector(`.entry[x-index="${i}"]`) as HTMLSpanElement
|
||||
if (!entry) continue
|
||||
const rect = entry.getBoundingClientRect()
|
||||
if (x > rect.left && x < rect.right && y > rect.top && y < rect.bottom) {
|
||||
hoveringIndex = i+1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<main on:wheel={handleWheel}>
|
||||
{#if file}
|
||||
{#each file.canvas.palette as palette, paletteIndex}
|
||||
<span on:click={paletteClick} x-index={paletteIndex} class='entry{paletteIndex===primaryColorIndex?' primary':''}{paletteIndex===secondaryColorIndex?' secondary':''}'>
|
||||
<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>
|
||||
{#if 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>
|
||||
{/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>
|
||||
{/if}
|
||||
{/each}
|
||||
{/if}
|
||||
</main>
|
||||
|
@ -76,6 +139,7 @@
|
|||
main {
|
||||
background-color: var(--cds-background-selected);
|
||||
text-align: left;
|
||||
user-select: none;
|
||||
}
|
||||
.entry {
|
||||
position: relative;
|
||||
|
@ -86,6 +150,9 @@
|
|||
padding: 2px;
|
||||
border: 2px solid transparent;
|
||||
}
|
||||
.entry.hide {
|
||||
display: none;
|
||||
}
|
||||
.entry.primary {
|
||||
border: 2px dashed white;
|
||||
}
|
||||
|
|
|
@ -181,6 +181,24 @@ export class Canvas {
|
|||
}
|
||||
return false
|
||||
}
|
||||
swapPaletteColors(index1: number, index2: number) {
|
||||
let temp = this.palette[index1]
|
||||
this.palette[index1] = this.palette[index2]
|
||||
this.palette[index2] = temp
|
||||
}
|
||||
movePaletteColor(from: number, to: number) {
|
||||
let temp = this.palette[from]
|
||||
if (from < to) {
|
||||
for (let i = from; i < to; i++) {
|
||||
this.palette[i] = this.palette[i + 1]
|
||||
}
|
||||
} else {
|
||||
for (let i = from; i > to; i--) {
|
||||
this.palette[i] = this.palette[i - 1]
|
||||
}
|
||||
}
|
||||
this.palette[to] = temp
|
||||
}
|
||||
refreshImageData() {
|
||||
for (let i = 0; i < this.pixels.length; i++) {
|
||||
let color = this.palette[this.pixels[i]]
|
||||
|
|
|
@ -239,4 +239,42 @@ export class AddSwatchUndoable implements Undoable<LoadedFile> {
|
|||
unapply(file: LoadedFile) {
|
||||
file.canvas.removePaletteColor(-1)
|
||||
}
|
||||
}
|
||||
|
||||
export class SwapSwatchUndoable implements Undoable<LoadedFile> {
|
||||
private index1: number
|
||||
private index2: number
|
||||
constructor(index1: number, index2: number) {
|
||||
this.index1 = index1
|
||||
this.index2 = index2
|
||||
}
|
||||
apply(file: LoadedFile) {
|
||||
file.canvas.swapPaletteColors(this.index1, this.index2)
|
||||
file.canvas.refreshImageData()
|
||||
file.canvas.refreshCanvas()
|
||||
}
|
||||
unapply(file: LoadedFile) {
|
||||
file.canvas.swapPaletteColors(this.index2, this.index1)
|
||||
file.canvas.refreshImageData()
|
||||
file.canvas.refreshCanvas()
|
||||
}
|
||||
}
|
||||
|
||||
export class MoveSwatchUndoable implements Undoable<LoadedFile> {
|
||||
private index: number
|
||||
private newIndex: number
|
||||
constructor(index: number, newIndex: number) {
|
||||
this.index = index
|
||||
this.newIndex = newIndex
|
||||
}
|
||||
apply(file: LoadedFile) {
|
||||
file.canvas.movePaletteColor(this.index, this.newIndex)
|
||||
file.canvas.refreshImageData()
|
||||
file.canvas.refreshCanvas()
|
||||
}
|
||||
unapply(file: LoadedFile) {
|
||||
file.canvas.movePaletteColor(this.newIndex, this.index)
|
||||
file.canvas.refreshImageData()
|
||||
file.canvas.refreshCanvas()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue