Skip to content

Commit

Permalink
Add embedded stack preview and settings
Browse files Browse the repository at this point in the history
  • Loading branch information
kettek committed Nov 7, 2024
1 parent 8e7998a commit e4737e8
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 16 deletions.
24 changes: 24 additions & 0 deletions frontend/src/components/settings/SmallPreview.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script lang="ts">
import { Column, Grid, Row } from 'carbon-components-svelte'
import { smallPreviewSettings, smallPreviewSettingsDefault } from '../../stores/smallpreview'
import Input from '../common/Input.svelte'
import SettingsInput from '../common/SettingsInput.svelte'
</script>

<Grid narrow condensed fullWidth>
<Column>
<Row>
<Input noPadding labelWidth="10" id="showSizeOutline" type="checkbox" label="Show" bind:checked={$smallPreviewSettings.show} />
</Row>
<Row>
<Input noPadding labelWidth="10" id="background" type="color" label="Background Color" bind:value={$smallPreviewSettings.background} />
<SettingsInput noPadding id="background" type="text" bind:value={$smallPreviewSettings.background} defaultValue={smallPreviewSettingsDefault.background} />
</Row>
<Row>
<SettingsInput noPadding labelWidth="10" id="spinSpeed" type="number" label="Spin Speed" bind:value={$smallPreviewSettings.spinSpeed} step={0.1} defaultValue={smallPreviewSettingsDefault.spinSpeed} />
</Row>
<Row>
<SettingsInput noPadding labelWidth="10" id="wheelIncrement" type="number" label="Mousewheel Increment" bind:value={$smallPreviewSettings.wheelIncrement} defaultValue={smallPreviewSettingsDefault.wheelIncrement} />
</Row>
</Column>
</Grid>
4 changes: 4 additions & 0 deletions frontend/src/sections/Settings.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import Checkerboard from '../components/settings/Checkerboard.svelte'
import Borders from '../components/settings/Borders.svelte'
import Grid from '../components/settings/Grid.svelte'
import SmallPreview from '../components/settings/SmallPreview.svelte'
</script>

<main>
Expand All @@ -27,6 +28,9 @@
<AccordionItem title="Preview">
<Preview />
</AccordionItem>
<AccordionItem title="Embedded Preview">
<SmallPreview />
</AccordionItem>
</Accordion>
</main>

Expand Down
78 changes: 63 additions & 15 deletions frontend/src/sections/SmallStackPreview.svelte
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
<!--
@component
This component provides a sprite stack view of a file.
This component provides an embedded stack preview of a stack.
-->
<script lang="ts">
import { Grid, Row, Column, Checkbox, Slider, Dropdown } from 'carbon-components-svelte'
import { fileStates } from '../stores/file'
import { onMount } from 'svelte'
import { previewSettings } from '../stores/preview'
import type { LoadedFile } from '../types/file'
import type { StaxStack } from '../types/png'
import Input from '../components/common/Input.svelte'
import { smallPreviewSettings } from '../stores/smallpreview'
export let file: LoadedFile
let rotation: number = 0
let zoom: number = 2
let zoom: number = 4
let spin: boolean = false
let sliceDistance: number = 1
let automaticShading: boolean = true
Expand All @@ -29,12 +26,17 @@
let minWidth: number = 80
$: minWidth = $file.frameWidth * zoom
let minSize: number = 1
$: minSize = Math.max(minWidth, minHeight)
let canvas: HTMLCanvasElement
function draw(ts: DOMHighResTimeStamp) {
if (!canvas) return
timeElapsed += ts - lastTime
lastTime = ts
rotation += 0.5
if (spin) {
rotation += $smallPreviewSettings.spinSpeed ?? 0.5
}
if (canvas.width !== minWidth || canvas.height !== minHeight) {
canvas.width = minWidth
Expand All @@ -47,20 +49,26 @@
ctx.imageSmoothingEnabled = false
let y = 0
const frameWidth = file.frameWidth * zoom
const frameHeight = file.frameHeight * zoom
if (file.animation) {
const animation = file.animation
let frameIndex = Math.floor(timeElapsed / animation.frameTime) % animation.frames.length
let frame = animation.frames[frameIndex]
if (!frame) {
frameIndex = 0
return
}
let y = frame.slices.length * sliceDistance * zoom
for (let sliceIndex = 0; sliceIndex < frame.slices.length; sliceIndex++) {
const slice = frame.slices[sliceIndex]
ctx.save()
ctx.translate(canvas.width / 2, canvas.height / 2)
//ctx.translate(cx, cy)
ctx.translate(0, y - sliceDistance * zoom)
ctx.translate((file.frameWidth * zoom) / 2, (file.frameHeight * zoom) / 2)
ctx.translate(0, y)
ctx.translate(frameWidth / 2, frameHeight / 2)
ctx.rotate((rotation * Math.PI) / 180)
ctx.translate((-file.frameWidth * zoom) / 2, (-file.frameHeight * zoom) / 2)
ctx.translate(-frameWidth / 2, -frameHeight / 2)
if (automaticShading) {
// FIXME: Adjust this math to use configurable min/max values.
Expand All @@ -76,6 +84,33 @@
}
}
function handleWheel(event: WheelEvent) {
event.preventDefault()
if (event.ctrlKey) {
if (event.deltaY < 0) {
zoom += 1
} else {
zoom -= 1
}
zoom = Math.min(Math.max(1, zoom), 10)
} else {
spin = false
if (event.deltaY < 0) {
rotation += $smallPreviewSettings.wheelIncrement
} else {
rotation -= $smallPreviewSettings.wheelIncrement
}
if (isNaN(rotation)) {
rotation = 0
}
console.log(rotation, $smallPreviewSettings.wheelIncrement)
}
}
function handleClick(event: MouseEvent) {
spin = !spin
}
onMount(() => {
let frameID: number = 0
let frameDraw = (ts: DOMHighResTimeStamp) => {
Expand All @@ -87,4 +122,17 @@
})
</script>

<canvas bind:this={canvas} style="width: {minWidth}px; height: {minHeight}px"></canvas>
<main on:wheel={handleWheel} on:click={handleClick} style={`background: ${$smallPreviewSettings.background}`}>
<canvas bind:this={canvas} style="width: {minWidth}px; height: {minHeight}px"></canvas>
</main>

<style>
main {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: black;
}
</style>
10 changes: 9 additions & 1 deletion frontend/src/sections/Stacks.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import Button from '../components/common/Button.svelte'
import { fileStates } from '../stores/file'
import RenameModal from '../components/RenameModal.svelte'
import SmallStackPreview from './SmallStackPreview.svelte'
import { smallPreviewSettings } from '../stores/smallpreview'
export let file: LoadedFile
Expand Down Expand Up @@ -188,6 +190,11 @@
</script>

<main>
{#if $smallPreviewSettings.show}
<SmallStackPreview file={$file} />
{:else}
<span></span>
{/if}
<menu class="toolbar">
<Button kind="ghost" size="small" icon={FolderAdd} tooltip="Add Stack" tooltipPosition="bottom" tooltipAlignment="end" disabled={!file} on:click={addStack} />
<hr />
Expand Down Expand Up @@ -245,7 +252,8 @@
main {
height: 100%;
display: grid;
grid-template-rows: auto 1fr 4fr;
grid-template-rows: auto auto 1fr 4fr;
grid-template-columns: minmax(0, 1fr);
}
.toolbar {
display: flex;
Expand Down
17 changes: 17 additions & 0 deletions frontend/src/stores/smallpreview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { makeLocalStorageStore } from './localstore'

type SmallPreviewSettings = {
show: boolean
background: string
spinSpeed: number
wheelIncrement: number
}

export const smallPreviewSettingsDefault: SmallPreviewSettings = {
show: true,
background: '#111111',
spinSpeed: 0.5,
wheelIncrement: 1,
}

export const smallPreviewSettings = makeLocalStorageStore<SmallPreviewSettings>('smallPreview', { ...smallPreviewSettingsDefault })

0 comments on commit e4737e8

Please sign in to comment.