spriteStackist/frontend/src/components/BrushSize.svelte

57 lines
1.8 KiB
Svelte

<!--
@component
This component provides a visualization of the current brush size and shape and controls for changing them.
-->
<script lang='ts'>
import { OverflowMenu, OverflowMenuItem } from "carbon-components-svelte";
import { FilledCircle, FilledSquare, type PixelPosition } from "../types/shapes"
export let brushSize: number
export let brushType: 'circle' | 'square' = 'circle'
$: ((brushSize: number, brushType: 'circle' | 'square') => {
if (canvas) {
let {width, height} = getComputedStyle(canvas)
canvas.width = parseInt(width)
canvas.height = parseInt(height)
const ctx = canvas.getContext('2d')
ctx.fillStyle = 'black'
ctx.fillRect(0, 0, canvas.width, canvas.height)
let shape: PixelPosition[]
if (brushType === 'square' || brushSize <= 2) {
shape = FilledSquare(canvas.width/2, canvas.height/2, brushSize, 1)
} else if (brushType === 'circle') {
shape = FilledCircle(canvas.width/2, canvas.height/2, brushSize-2, 1)
}
for (let i = 0; i < shape.length; i++) {
ctx.fillStyle = 'white'
ctx.fillRect(shape[i].x, shape[i].y, 1, 1)
}
}
})(brushSize, brushType)
function handleWheel(event: WheelEvent) {
event.preventDefault()
brushSize = Math.max(1, brushSize - Math.sign(event.deltaY))
}
let canvas: HTMLCanvasElement
</script>
<div on:wheel={handleWheel}>
<OverflowMenu size="sm" style="width: auto">
<canvas slot="menu" bind:this={canvas}>
</canvas>
<OverflowMenuItem primaryFocus={brushType==='circle'} text="circle" on:click={()=>brushType='circle'}/>
<OverflowMenuItem primaryFocus={brushType==='square'} text="square" on:click={()=>brushType='square'}/>
</OverflowMenu>
</div>
<style>
canvas {
width: 2rem;
height: 2rem;
}
</style>