Add brush size visualizer
parent
0703417339
commit
02fe8ea1dc
|
@ -9,15 +9,16 @@
|
|||
import { LoadedFile } from './types/file'
|
||||
|
||||
import "carbon-components-svelte/css/all.css"
|
||||
import { Tabs, Tab, TabContent, Theme, Button, Modal, Truncate, ButtonSet } from "carbon-components-svelte"
|
||||
import { Tabs, Tab, TabContent, Theme, Button, Modal, Truncate, ButtonSet, NumberInput } from "carbon-components-svelte"
|
||||
import { ComposedModal } from "carbon-components-svelte"
|
||||
|
||||
import { OverflowMenu, OverflowMenuItem } from "carbon-components-svelte"
|
||||
|
||||
import { Close, Erase, PaintBrushAlt, RainDrop, Redo, Select_01, Undo } from "carbon-icons-svelte"
|
||||
import { Close, Erase, PaintBrushAlt, RainDrop, Redo, Select_01, Undo, Scale } from "carbon-icons-svelte"
|
||||
import StackPreview from './sections/StackPreview.svelte'
|
||||
import type { Canvas } from './types/canvas'
|
||||
import { BrushTool, EraserTool, FillTool, type Tool } from './types/tools';
|
||||
import BrushSize from './components/BrushSize.svelte';
|
||||
|
||||
let theme: 'white'|'g10'|'g80'|'g90'|'g100' = 'g90'
|
||||
|
||||
|
@ -38,6 +39,7 @@
|
|||
let toolErase = new EraserTool()
|
||||
let toolBrush = new BrushTool()
|
||||
let currentTool: Tool = toolBrush
|
||||
let brushSize: number = 1
|
||||
|
||||
function swapTool(tool: Tool) {
|
||||
currentTool = tool
|
||||
|
@ -104,6 +106,13 @@
|
|||
<Button isSelected={currentTool === toolErase} kind="ghost" size="small" icon={Erase} iconDescription="erase" tooltipPosition="right" on:click={()=>swapTool(toolErase)}></Button>
|
||||
</menu>
|
||||
<section class='middle'>
|
||||
<menu class='toolsettings'>
|
||||
{#if currentTool === toolBrush || currentTool === toolErase}
|
||||
<Scale/>
|
||||
<BrushSize bind:brushSize/>
|
||||
<NumberInput size="sm" min={1} max={100} step={1} bind:value={brushSize}/>
|
||||
{/if}
|
||||
</menu>
|
||||
<Tabs>
|
||||
{#each files as file, index}
|
||||
<Tab on:click={()=>selectFile(file, index)}>
|
||||
|
@ -116,7 +125,7 @@
|
|||
<svelte:fragment slot="content">
|
||||
{#each files as file}
|
||||
<TabContent>
|
||||
<Editor2D bind:file={file} refresh={refresh} primaryColorIndex={primaryColorIndex} secondaryColorIndex={secondaryColorIndex} bind:currentTool={currentTool} />
|
||||
<Editor2D bind:file={file} refresh={refresh} primaryColorIndex={primaryColorIndex} secondaryColorIndex={secondaryColorIndex} bind:currentTool={currentTool} brushSize={brushSize} />
|
||||
</TabContent>
|
||||
{/each}
|
||||
</svelte:fragment>
|
||||
|
@ -173,10 +182,21 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
padding-top: 2rem;
|
||||
}
|
||||
.toolsettings {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
min-height: 2rem;
|
||||
}
|
||||
:global(menu.toolsettings > .bx--form-item) {
|
||||
flex: initial;
|
||||
}
|
||||
.middle {
|
||||
display: grid;
|
||||
grid-template-rows: auto minmax(0, 1fr);
|
||||
grid-template-rows: auto auto minmax(0, 1fr);
|
||||
}
|
||||
.tab {
|
||||
display: inline-grid;
|
||||
|
@ -193,4 +213,14 @@
|
|||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
:global(.middle .bx--tabs__nav-link) {
|
||||
height: 1rem;
|
||||
}
|
||||
:global(.middle .bx--tabs) {
|
||||
min-height: 1.4rem;
|
||||
}
|
||||
:global(.middle .bx--tabs .bx--btn) {
|
||||
padding-top: 0;
|
||||
top: -.25rem;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<script lang='ts'>
|
||||
import { FilledCircle } from "../types/shapes"
|
||||
|
||||
export let brushSize: number
|
||||
|
||||
$: ((brushSize: number) => {
|
||||
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 = FilledCircle(canvas.width/2, canvas.height/2, brushSize, 1)
|
||||
for (let i = 0; i < shape.length; i++) {
|
||||
ctx.fillStyle = 'white'
|
||||
ctx.fillRect(shape[i].x, shape[i].y, 1, 1)
|
||||
}
|
||||
}
|
||||
})(brushSize)
|
||||
|
||||
let canvas: HTMLCanvasElement
|
||||
</script>
|
||||
|
||||
<canvas bind:this={canvas}>
|
||||
</canvas>
|
||||
|
||||
<style>
|
||||
canvas {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
</style>
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
export let primaryColorIndex: number
|
||||
export let secondaryColorIndex: number
|
||||
export let brushSize: number
|
||||
|
||||
let rootCanvas: HTMLCanvasElement
|
||||
let overlayCanvas: HTMLCanvasElement = document.createElement('canvas')
|
||||
|
@ -208,9 +209,9 @@
|
|||
|
||||
if (e.button === 0) {
|
||||
if (currentTool instanceof BrushTool) {
|
||||
currentTool.pointerDown({file, brushSize: 3, colorIndex: primaryColorIndex}, {x: mousePixelX, y: mousePixelY, id: e.button })
|
||||
currentTool.pointerDown({file, brushSize, colorIndex: primaryColorIndex}, {x: mousePixelX, y: mousePixelY, id: e.button })
|
||||
} else if (currentTool instanceof EraserTool) {
|
||||
currentTool.pointerDown({file, brushSize: 3}, {x: mousePixelX, y: mousePixelY, id: e.button })
|
||||
currentTool.pointerDown({file, brushSize}, {x: mousePixelX, y: mousePixelY, id: e.button })
|
||||
} else if (currentTool instanceof FillTool) {
|
||||
currentTool.pointerDown({file, colorIndex: primaryColorIndex}, {x: mousePixelX, y: mousePixelY, id: e.button })
|
||||
} else {
|
||||
|
@ -268,9 +269,9 @@
|
|||
if (buttons.has(0)) {
|
||||
if (currentTool.isActive()) {
|
||||
if (currentTool instanceof BrushTool) {
|
||||
currentTool.pointerMove({file, brushSize: 3, colorIndex: primaryColorIndex}, {x: mousePixelX, y: mousePixelY, id: 0 })
|
||||
currentTool.pointerMove({file, brushSize, colorIndex: primaryColorIndex}, {x: mousePixelX, y: mousePixelY, id: 0 })
|
||||
} else if (currentTool instanceof EraserTool) {
|
||||
currentTool.pointerMove({file, brushSize: 3}, {x: mousePixelX, y: mousePixelY, id: 0 })
|
||||
currentTool.pointerMove({file, brushSize}, {x: mousePixelX, y: mousePixelY, id: 0 })
|
||||
} else if (currentTool instanceof FillTool) {
|
||||
currentTool.pointerMove({file, colorIndex: primaryColorIndex}, {x: mousePixelX, y: mousePixelY, id: 0 })
|
||||
} else {
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
<style>
|
||||
main {
|
||||
background-color: var(--cds-background-selected);
|
||||
text-align: left;
|
||||
}
|
||||
.entry {
|
||||
position: relative;
|
||||
|
|
Loading…
Reference in New Issue