+
{#if backgroundImage}
{/if}
- {#each panel.texts || [] as textItem (textItem.id)}
- {@const textPosition = getTextPosition(textItem)}
+
+
+
+
+ {#if panel.text}
+ {@const textPosition = getTextPosition(panel.text)}
+
- {/each}
+ {/if}
diff --git a/src/lib/services/exportService.ts b/src/lib/services/exportService.ts
index 948454d..cb8fc10 100644
--- a/src/lib/services/exportService.ts
+++ b/src/lib/services/exportService.ts
@@ -38,18 +38,17 @@ export class ExportService {
ctx.drawImage(bgImage, 0, 0, 320, panel.height);
// Рисуем текст
- panel.texts.forEach((textItem) => {
- ctx.font = `${textItem.fontSize}px ${textItem.fontFamily}`;
- ctx.fillStyle = textItem.color;
- ctx.textAlign = "center";
- ctx.textBaseline = "middle";
+ const textItem = panel.text;
+ ctx.font = `${textItem.fontSize}px ${textItem.fontFamily}`;
+ ctx.fillStyle = textItem.color;
+ ctx.textAlign = "center";
+ ctx.textBaseline = "middle";
- // Calculate position based on existing system
- const x = 160; // Center of 320px panel
- const y = panel.height / 2 + textItem.verticalOffset;
+ // Calculate position based on existing system
+ const x = 160; // Center of 320px panel
+ const y = panel.height / 2 + textItem.verticalOffset;
- ctx.fillText(textItem.text, x, y);
- });
+ ctx.fillText(textItem.text, x, y);
// Конвертируем в blob и сохраняем
canvas.toBlob((blob) => {
diff --git a/src/lib/types/panel.ts b/src/lib/types/panel.ts
index 3c88aae..74aded8 100644
--- a/src/lib/types/panel.ts
+++ b/src/lib/types/panel.ts
@@ -14,7 +14,7 @@ export interface TextItem {
export interface Panel {
id: string;
backgroundImage: string;
- texts: TextItem[];
+ text: TextItem;
height: number;
createdAt: Date;
updatedAt: Date;
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 91c009c..f7d1638 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -13,11 +13,31 @@
let backgroundImage = $state
(undefined);
onMount(async () => {
+ // Initialize with default texts for common Twitch panels
+ console.log("[INIT] Creating default texts...");
+ const defaultTexts = [
+ { id: crypto.randomUUID(), text: "About" },
+ { id: crypto.randomUUID(), text: "Links" },
+ ];
+ texts = defaultTexts;
+ console.log("[INIT] Default texts created:", texts);
+
+ // Load background image
try {
- backgroundImage = await imageService.loadDefaultBackground();
+ console.log("[INIT] Loading default background...");
+ const loadedBackground = await imageService.loadDefaultBackground();
+ console.log("[INIT] Background loaded:", loadedBackground);
+ backgroundImage = loadedBackground;
} catch (error) {
+ console.error("[INIT] Error loading background:", error);
exportService.setErrorMessage("Не удалось загрузить фоновое изображение по умолчанию");
}
+
+ // Create panels from texts (with or without background)
+ console.log("[INIT] Creating panels from texts...");
+ const initialPanels = panelService.updatePanelsFromTexts(texts, [], backgroundImage || "");
+ console.log("[INIT] Panels created:", initialPanels);
+ panels = initialPanels;
});
function handleImageUpload(image: string) {
diff --git a/src/services/panelService.ts b/src/services/panelService.ts
index 6442cb7..e15ca18 100644
--- a/src/services/panelService.ts
+++ b/src/services/panelService.ts
@@ -18,7 +18,7 @@ export class PanelService {
}
isDuplicateText(texts: Array<{ id: string; text: string }>, text: string, excludeId?: string): boolean {
- return texts.some(t => t.id !== excludeId && t.text === text);
+ return texts.some((t) => t.id !== excludeId && t.text === text);
}
addText(texts: Array<{ id: string; text: string }>, text: string): Array<{ id: string; text: string }> {
@@ -28,20 +28,24 @@ export class PanelService {
return [...texts, { id: crypto.randomUUID(), text }];
}
- updateText(texts: Array<{ id: string; text: string }>, id: string, newText: string): Array<{ id: string; text: string }> {
+ updateText(
+ texts: Array<{ id: string; text: string }>,
+ id: string,
+ newText: string,
+ ): Array<{ id: string; text: string }> {
if (!this.validateText(newText)) return texts;
if (this.isDuplicateText(texts, newText, id)) return texts;
- return texts.map(t => t.id === id ? { ...t, text: newText } : t);
+ return texts.map((t) => (t.id === id ? { ...t, text: newText } : t));
}
deleteText(texts: Array<{ id: string; text: string }>, id: string): Array<{ id: string; text: string }> {
- return texts.filter(t => t.id !== id);
+ return texts.filter((t) => t.id !== id);
}
updatePanelsFromTexts(texts: Array<{ id: string; text: string }>, panels: Panel[], backgroundImage: string): Panel[] {
- return texts.map(textItem => {
- const existingPanel = panels.find(p => p.texts[0]?.text === textItem.text);
+ return texts.map((textItem) => {
+ const existingPanel = panels.find((p) => p.text.text === textItem.text);
if (existingPanel) {
return updatePanelText(existingPanel, textItem.text);
}
@@ -50,7 +54,7 @@ export class PanelService {
}
updatePanelsBackground(panels: Panel[], newBackground: string): Panel[] {
- return panels.map(panel => ({
+ return panels.map((panel) => ({
...panel,
backgroundImage: newBackground,
updatedAt: new Date(),
diff --git a/src/stores/panelStore.ts b/src/stores/panelStore.ts
index a04252a..2b1b1b0 100644
--- a/src/stores/panelStore.ts
+++ b/src/stores/panelStore.ts
@@ -4,11 +4,24 @@ import { type Panel, type TextItem } from "../lib/types/panel";
export const panelStore: Writable = writable(undefined);
+// Panel creation should go through panelService.updatePanelsFromTexts()
+// These functions are kept for backward compatibility but should be avoided
export const createEmptyPanel = (height: number = 100): Panel => {
+ const defaultText: TextItem = {
+ id: uuidv4(),
+ text: "",
+ fontSize: 18,
+ fontFamily: "Arial",
+ color: "#ffffff",
+ textAlign: "center",
+ paddingX: 10,
+ verticalOffset: 0,
+ };
+
return {
id: uuidv4(),
backgroundImage: "",
- texts: [],
+ text: defaultText,
height,
createdAt: new Date(),
updatedAt: new Date(),
@@ -23,32 +36,16 @@ export const updatePanel = (panel: Panel, updates: Partial): Panel => {
};
};
-export const addTextToPanel = (panel: Panel, text: string): Panel => {
- const newText: TextItem = {
- id: uuidv4(),
- text,
- fontSize: 18,
- fontFamily: "Arial",
- color: "#ffffff",
- textAlign: "center",
- paddingX: 10,
- verticalOffset: 0,
- };
-
+export const updatePanelText = (panel: Panel, text: string): Panel => {
return updatePanel(panel, {
- texts: [...panel.texts, newText],
+ text: { ...panel.text, text },
});
};
-export const updateTextInPanel = (panel: Panel, textId: string, updates: Partial): Panel => {
- const updatedTexts = panel.texts.map((text) => (text.id === textId ? { ...text, ...updates } : text));
-
- return updatePanel(panel, { texts: updatedTexts });
-};
-
-export const removeTextFromPanel = (panel: Panel, textId: string): Panel => {
- const updatedTexts = panel.texts.filter((text) => text.id !== textId);
- return updatePanel(panel, { texts: updatedTexts });
+export const updateTextProperties = (panel: Panel, updates: Partial): Panel => {
+ return updatePanel(panel, {
+ text: { ...panel.text, ...updates },
+ });
};
export const createPanelFromText = (backgroundImage: string, text: string, height: number = 100): Panel => {
@@ -66,14 +63,9 @@ export const createPanelFromText = (backgroundImage: string, text: string, heigh
return {
id: uuidv4(),
backgroundImage,
- texts: [newText],
+ text: newText,
height,
createdAt: new Date(),
updatedAt: new Date(),
};
};
-
-export const updatePanelText = (panel: Panel, text: string): Panel => {
- const updatedTexts = panel.texts.map((t) => ({ ...t, text }));
- return updatePanel(panel, { texts: updatedTexts });
-};