fix: resolve - first draw dont show preview image
This commit is contained in:
@@ -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}
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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(() => {});
|
|
||||||
|
|||||||
Reference in New Issue
Block a user