fix: resolve - first draw dont show preview image

This commit is contained in:
2026-02-09 10:12:54 +05:00
parent c4103e937d
commit 94060630ef
3 changed files with 31 additions and 67 deletions
+1 -3
View File
@@ -11,8 +11,6 @@
let { text, stage = $bindable() }: Props = $props(); let { text, stage = $bindable() }: Props = $props();
let image: HTMLImageElement | undefined = imageConfigState.image;
let x = $derived(textConfigState.paddingX); let x = $derived(textConfigState.paddingX);
let y = $derived(10 + textConfigState.offsetY); let y = $derived(10 + textConfigState.offsetY);
let width = $derived(PANEL_SETTINGS.PANEL_WIDTH - 2 * textConfigState.paddingX); let width = $derived(PANEL_SETTINGS.PANEL_WIDTH - 2 * textConfigState.paddingX);
@@ -21,7 +19,7 @@
<Stage width={320} height={100} bind:this={stage}> <Stage width={320} height={100} bind:this={stage}>
<Layer> <Layer>
<Image {image}></Image> <Image image={imageConfigState.image}></Image>
<Text <Text
{text} {text}
{x} {x}
+7 -1
View File
@@ -1,7 +1,9 @@
<script lang="ts"> <script lang="ts">
import AppHeader from "$components/layout/AppHeader.svelte"; import AppHeader from "$components/layout/AppHeader.svelte";
import { PANEL_SETTINGS } from "$lib/constants";
import { imageConfigState } from "$states/imageConfig.svelte";
import { themeState } from "$states/theme.svelte"; import { themeState } from "$states/theme.svelte";
import type { Snippet } from "svelte"; import { onMount, type Snippet } from "svelte";
interface Props { interface Props {
children: Snippet; children: Snippet;
@@ -14,6 +16,10 @@
}); });
let { children }: Props = $props(); let { children }: Props = $props();
onMount(async () => {
await imageConfigState.uploadImageByLink(PANEL_SETTINGS.DEFAULT_BACKGROUND_IMAGE);
});
</script> </script>
<div class="container"> <div class="container">
+23 -63
View File
@@ -1,5 +1,3 @@
import { PANEL_SETTINGS } from "$lib/constants";
export type ImageConfig = { export type ImageConfig = {
image: HTMLImageElement | undefined; image: HTMLImageElement | undefined;
imageLink: string; imageLink: string;
@@ -11,72 +9,35 @@ export type ImageConfig = {
}; };
export class ImageConfigState { export class ImageConfigState {
#state: ImageConfig = $state({ image = $state<HTMLImageElement | undefined>(undefined);
image: undefined, imageLink = $state("");
imageLink: "", imageReady = $state(false);
imageReady: false, cropLeft = $state(0);
cropLeft: 0, cropTop = $state(0);
cropTop: 0, cropRight = $state(0);
cropRight: 0, cropBottom = $state(0);
cropBottom: 0,
});
#currentAbortController: AbortController | null = null; #currentAbortController: AbortController | null = null;
get image() {
return this.#state.image;
}
get imageReady() {
return this.#state.imageReady;
}
get imageLink() {
return this.#state.imageLink;
}
get cropLeft() {
return this.#state.cropLeft;
}
get cropTop() {
return this.#state.cropTop;
}
get cropRight() {
return this.#state.cropRight;
}
get cropBottom() {
return this.#state.cropBottom;
}
set cropLeft(v) {
this.#state.cropLeft = v;
}
set cropTop(v) {
this.#state.cropTop = v;
}
set cropRight(v) {
this.#state.cropRight = v;
}
set cropBottom(v) {
this.#state.cropBottom = v;
}
private cleanup() { private cleanup() {
if (this.#currentAbortController) { if (this.#currentAbortController) {
this.#currentAbortController.abort(); this.#currentAbortController.abort();
this.#currentAbortController = null; this.#currentAbortController = null;
} }
if (this.#state.image) { if (this.image) {
this.#state.image.onload = null; this.image.onload = null;
this.#state.image.onerror = null; this.image.onerror = null;
this.#state.image.src = ""; this.image.src = "";
this.#state.image = undefined; this.image = undefined;
} }
} }
async uploadImageByLink(link: string): Promise<void> { async uploadImageByLink(link: string): Promise<void> {
this.cleanup(); this.cleanup();
this.#state.imageReady = false; this.imageReady = false;
this.#state.imageLink = link; this.imageLink = link;
this.#currentAbortController = new AbortController(); this.#currentAbortController = new AbortController();
const { signal } = this.#currentAbortController; const { signal } = this.#currentAbortController;
@@ -93,15 +54,15 @@ export class ImageConfigState {
img.onload = () => { img.onload = () => {
if (signal.aborted) return; if (signal.aborted) return;
onFinished(); onFinished();
this.#state.image = img; this.image = img;
this.#state.imageReady = true; this.imageReady = true;
resolve(); resolve();
}; };
img.onerror = () => { img.onerror = () => {
if (signal.aborted) return; if (signal.aborted) return;
onFinished(); onFinished();
this.#state.imageReady = false; this.imageReady = false;
reject(new Error(`Failed to load image: ${link}`)); reject(new Error(`Failed to load image: ${link}`));
}; };
@@ -121,12 +82,12 @@ export class ImageConfigState {
reset() { reset() {
this.cleanup(); this.cleanup();
this.#state.imageLink = ""; this.imageLink = "";
this.#state.imageReady = false; this.imageReady = false;
this.#state.cropLeft = 0; this.cropLeft = 0;
this.#state.cropTop = 0; this.cropTop = 0;
this.#state.cropRight = 0; this.cropRight = 0;
this.#state.cropBottom = 0; this.cropBottom = 0;
} }
destroy() { destroy() {
@@ -135,4 +96,3 @@ export class ImageConfigState {
} }
export const imageConfigState = new ImageConfigState(); export const imageConfigState = new ImageConfigState();
imageConfigState.uploadImageByLink(PANEL_SETTINGS.DEFAULT_BACKGROUND_IMAGE).catch(() => {});