Add StackPreview basic version

main
kts of kettek 2024-02-10 06:28:57 -08:00
parent 62c68a8b55
commit 875fe06d62
2 changed files with 91 additions and 0 deletions

View File

@ -3,6 +3,7 @@
import Editor2D from './sections/Editor2D.svelte'
import Importer from './sections/Importer.svelte';
import PaletteSection from './sections/Palette.svelte'
import FloatingPanel from './components/FloatingPanel.svelte'
import { Palette, PaletteEntry, defaultPalette } from './types/palette'
import type { LoadedFile } from './types/file.ts'
@ -14,6 +15,7 @@
import { OverflowMenu, OverflowMenuItem } from "carbon-components-svelte"
import { Close } from "carbon-icons-svelte"
import StackPreview from './sections/StackPreview.svelte'
let theme: 'white'|'g10'|'g80'|'g90'|'g100' = 'g90'
@ -84,6 +86,12 @@
</svelte:fragment>
</Tabs>
</section>
<FloatingPanel
label="Stack Preview"
noPadding
>
<StackPreview files={files} />
</FloatingPanel>
</section>
</main>
<ComposedModal bind:open={showImport} size="sm" preventCloseOnClickOutside on:click:button--primary={engageImport}>

View File

@ -0,0 +1,83 @@
<script lang='ts'>
import { Grid, Row, Column, Checkbox, Slider } from "carbon-components-svelte"
import type { LoadedFile } from "src/types/file"
import { onMount } from "svelte";
export let files: LoadedFile[]
let shownFiles: Record<string, boolean> = {}
let rotation: number = 0
let canvas: HTMLCanvasElement
function draw() {
if (!canvas) return
let computedSize = getComputedStyle(canvas)
if (canvas.width !== parseInt(computedSize.width) || canvas.height !== parseInt(computedSize.height)) {
canvas.width = parseInt(computedSize.width)
canvas.height = parseInt(computedSize.height)
}
let ctx = canvas.getContext('2d')
if (!ctx) return
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.fillStyle = '#222222'
ctx.fillRect(0, 0, canvas.width, canvas.height)
let x = canvas.width/2
let y = canvas.height/2
for (let file of files) {
if (shownFiles[file.title]) {
// For now, just get the first frame of the first animation.
let done = false
for (let [groupName, group] of Object.entries(file.data.groups)) {
for (let [animationName, animation] of Object.entries(group.animations)) {
for (let frame of animation.frames) {
for (let layer of frame.layers) {
ctx.save()
ctx.translate(x, y)
ctx.rotate(rotation * Math.PI / 180)
ctx.drawImage(file.image, layer.x, layer.y, group.width, group.height, -group.width/2, -group.height/2, group.width, group.height)
ctx.restore()
y -= 1
}
done = true
if (done) break
}
if (done) break
}
x += group.width
y = canvas.height/2
if (done) break
}
}
}
}
onMount(()=>{
let frameID: number = 0
let frameDraw = () => {
draw()
frameID = requestAnimationFrame(frameDraw)
}
frameID = requestAnimationFrame(frameDraw)
return () => cancelAnimationFrame(frameID)
})
</script>
<Grid narrow condensed fullWidth>
<Row narrow condensed>
<Column sm>
{#each files as file, i}
<Checkbox bind:checked={shownFiles[file.title]} labelText={file.title.length>20?'…'+file.title.substring(file.title.length-20):file.title}></Checkbox>
{/each}
</Column>
<Column>
<canvas bind:this={canvas}></canvas>
<Slider labelText="Rotation" min={0} max={360} step={1} bind:value={rotation} fullWidth></Slider>
</Column>
</Row>
</Grid>
<style>
</style>