Drawing2Sat / frontend /src /lib /ResultCanvas.svelte
Ruben
update
b7b124d
<script lang="ts">
let canvas: HTMLCanvasElement;
import { API } from '../data';
import { nanoid } from 'nanoid';
import type { Params } from '../types';
import {
selectedParams,
generateMap,
currentCanvas,
resultImage,
saveResult
} from '$lib/store';
$: (async () => {
if ($generateMap) {
const results = await predict($currentCanvas.toDataURL(), $selectedParams);
$resultImage = results;
$generateMap = false;
}
})();
$: (async () => {
if ($saveResult) {
const results = await saveImage($resultImage);
$saveResult = false;
}
})();
let predictStatus: string = '';
async function saveImage(base64Image: string) {
return new Promise((resolve, reject) => {
try {
const a = document.createElement('a');
a.download = `sucess-${Date.now()}.png`;
a.target = '_self';
a.onclick = async (e) => {
if (a.href) {
URL.revokeObjectURL(a.href);
}
a.href = base64Image;
};
requestAnimationFrame(() => {
console.log('Downloading image.');
a.click();
resolve(null);
});
} catch (err) {
reject();
}
});
}
async function predict(base64Image: string, { prompt, modifier, steps, seed }: Params) {
const response = await fetch('/predict', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
data: [base64Image, prompt+'. '+modifier, steps, seed.toString()],
}),
});
if (!response.ok) {
throw new Error('Prediction request failed.');
}
const result = await response.text();
return result;
}
</script>
<div class="relative overflow-clip flex flex-col justify-center items-center w-full h-full">
{#if $resultImage}
<img
class="image {$generateMap ? 'opacity-30' : ''}"
alt="Generative Map Result"
src={$resultImage}
width="512"
height="512"
/>
{/if}
{#if $generateMap}
<div class="loading">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
class="animate-spin max-w-[3rem]"
>
<path
fill="currentColor"
d="M20 12a8 8 0 0 1-8 8v4a12 12 0 0 0 12-12h-4Zm-2-5.3a8 8 0 0 1 2 5.3h4c0-3-1.1-5.8-3-8l-3 2.7Z"
/>
</svg>
<span class="text-xs">{predictStatus}</span>
</div>
{/if}
</div>
<!-- {/if} -->
<style lang="postcss" scoped>
.image {
@apply box-border z-0 border dark:border-gray-300 border-gray-500 aspect-[512/512];
}
.loading {
@apply absolute top-0 left-0 right-0 bottom-0 flex flex-col justify-center items-center;
}
</style>