From 3a98a0821538ebd5d3aac650662aed39bca1760c Mon Sep 17 00:00:00 2001 From: Ku6epXBOCTuK Date: Wed, 4 Feb 2026 00:18:20 +0500 Subject: [PATCH] feat: change text settings to common --- src/components/TextManager.svelte | 379 +++++++++++++++++++++++------- src/lib/types/panel.ts | 13 +- src/stores/panelStore.ts | 10 +- 3 files changed, 309 insertions(+), 93 deletions(-) diff --git a/src/components/TextManager.svelte b/src/components/TextManager.svelte index ef903cc..62d825c 100644 --- a/src/components/TextManager.svelte +++ b/src/components/TextManager.svelte @@ -9,10 +9,55 @@ } = $props(); let currentPanel = $state($panelStore); - let selectedTextId = $state(null); let newText = $state(""); let errorMessage = $state(null); + // Общие настройки текста для всех текстов + let commonTextSettings = $state({ + fontSize: 18, + fontFamily: "Arial", + color: "#ffffff", + textAlign: "center" as "left" | "center" | "right", + padding: { + top: 10, + right: 10, + bottom: 10, + left: 10, + }, + verticalOffset: 0, + }); + + // Список доступных шрифтов + const availableFonts = [ + "Arial", + "Verdana", + "Georgia", + "Times New Roman", + "Courier New", + "Impact", + "Comic Sans MS", + "Trebuchet MS", + ]; + + // Применить общие настройки ко всем текстам + function applyCommonSettingsToAll() { + if (!currentPanel) return; + + const updatedTexts = currentPanel.texts.map(text => ({ + ...text, + fontSize: commonTextSettings.fontSize, + fontFamily: commonTextSettings.fontFamily, + color: commonTextSettings.color, + textAlign: commonTextSettings.textAlign, + padding: { ...commonTextSettings.padding }, + verticalOffset: commonTextSettings.verticalOffset, + })); + + const updatedPanel = updatePanel(currentPanel, { texts: updatedTexts }); + panelStore.set(updatedPanel); + onTextUpdate(updatedTexts); + } + // Subscribe to panel store $effect(() => { currentPanel = $panelStore; @@ -37,7 +82,6 @@ panelStore.set(updatedPanel); onTextUpdate(updatedPanel.texts); newText = ""; - selectedTextId = updatedPanel.texts[updatedPanel.texts.length - 1].id; } catch (error) { errorMessage = error instanceof Error ? error.message : "Ошибка добавления текста"; } @@ -64,18 +108,10 @@ const updatedPanel = removeTextFromPanel(currentPanel, textId); panelStore.set(updatedPanel); onTextUpdate(updatedPanel.texts); - - if (selectedTextId === textId) { - selectedTextId = null; - } } catch (error) { errorMessage = error instanceof Error ? error.message : "Ошибка удаления текста"; } } - - function handleSelectText(textId: string) { - selectedTextId = textId; - }
@@ -83,6 +119,183 @@

Управление текстом

+ +
+

Общие настройки текста

+ +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+
0}
{#each currentPanel.texts as textItem (textItem.id)} -
handleSelectText(textItem.id)} - > +
{textItem.text}
- - {#if selectedTextId === textItem.id} -
-
- -
- -
- -
- -
- -
- -
- -
-
- {/if}
{/each}
@@ -214,6 +356,71 @@ font-size: 1.5rem; } + .common-settings-section { + background: #f8f9fa; + border: 2px solid #e9ecef; + border-radius: 8px; + padding: 1.5rem; + margin-bottom: 1.5rem; + } + + .common-settings-section h3 { + margin: 0 0 1rem 0; + color: #333; + font-size: 1.25rem; + } + + .settings-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 1rem; + } + + .alignment-buttons { + display: flex; + gap: 0.5rem; + } + + .btn-align { + flex: 1; + padding: 0.5rem; + border: 2px solid #ddd; + border-radius: 4px; + background: white; + cursor: pointer; + font-size: 1.2rem; + transition: all 0.2s ease; + } + + .btn-align:hover { + border-color: #007bff; + background: #f0f8ff; + } + + .btn-align.active { + background: #007bff; + color: white; + border-color: #007bff; + } + + .padding-controls { + display: flex; + flex-direction: column; + gap: 0.5rem; + } + + .padding-input { + display: flex; + align-items: center; + gap: 0.5rem; + } + + .padding-input span { + min-width: 40px; + font-size: 0.9rem; + color: #666; + } + .add-text-section { display: flex; flex-direction: column; @@ -279,18 +486,12 @@ transition: all 0.3s ease; } - .text-item.selected { - border-color: #007bff; - background: #f0f8ff; - } - .text-preview { display: flex; justify-content: space-between; align-items: center; padding: 1rem; background: #f9f9f9; - cursor: pointer; } .text-content { diff --git a/src/lib/types/panel.ts b/src/lib/types/panel.ts index 167be6e..19a2c67 100644 --- a/src/lib/types/panel.ts +++ b/src/lib/types/panel.ts @@ -4,8 +4,17 @@ export interface TextItem { fontSize: number; fontFamily: string; color: string; - x: number; - y: number; + // Выравнивание текста: left, center, right + textAlign: "left" | "center" | "right"; + // Внутренние отступы + padding: { + top: number; + right: number; + bottom: number; + left: number; + }; + // Смещение от центра по вертикали (для компенсации визуального центра разных шрифтов) + verticalOffset: number; } export interface Panel { diff --git a/src/stores/panelStore.ts b/src/stores/panelStore.ts index 12bc60e..4e93248 100644 --- a/src/stores/panelStore.ts +++ b/src/stores/panelStore.ts @@ -30,8 +30,14 @@ export const addTextToPanel = (panel: Panel, text: string): Panel => { fontSize: 18, fontFamily: "Arial", color: "#ffffff", - x: 160, // center horizontally - y: 50, // center vertically + textAlign: "center" as const, + padding: { + top: 10, + right: 10, + bottom: 10, + left: 10, + }, + verticalOffset: 0, }; return updatePanel(panel, {