feat: change workflow
This commit is contained in:
@@ -54,18 +54,14 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="panel-preview">
|
<div class="panel-preview">
|
||||||
|
{#if $panelStore}
|
||||||
<div class="preview-header">
|
<div class="preview-header">
|
||||||
<h2>Предпросмотр панели</h2>
|
<Button variant="primary" onclick={handleDownload}>Скачать панель</Button>
|
||||||
{#if $panelStore}
|
|
||||||
<Button variant="primary" onclick={handleDownload}>Скачать</Button>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if $panelStore}
|
|
||||||
<div class="preview-sections">
|
<div class="preview-sections">
|
||||||
<!-- Превью чистой картинки -->
|
<!-- Превью чистой картинки -->
|
||||||
<div class="preview-section">
|
<div class="preview-section">
|
||||||
<h3>Чистая картинка</h3>
|
<h3>Фон</h3>
|
||||||
<div class="canvas-container">
|
<div class="canvas-container">
|
||||||
<Stage width={320} height={$panelStore.height}>
|
<Stage width={320} height={$panelStore.height}>
|
||||||
<Layer>
|
<Layer>
|
||||||
@@ -79,7 +75,7 @@
|
|||||||
|
|
||||||
<!-- Превью с текстом -->
|
<!-- Превью с текстом -->
|
||||||
<div class="preview-section">
|
<div class="preview-section">
|
||||||
<h3>С текстом</h3>
|
<h3>Финальный результат</h3>
|
||||||
<div class="canvas-container">
|
<div class="canvas-container">
|
||||||
<Stage width={320} height={$panelStore.height}>
|
<Stage width={320} height={$panelStore.height}>
|
||||||
<Layer>
|
<Layer>
|
||||||
@@ -121,16 +117,10 @@
|
|||||||
|
|
||||||
.preview-header {
|
.preview-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0.75rem 1rem;
|
padding: 1rem;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 1rem;
|
||||||
}
|
|
||||||
|
|
||||||
.preview-header h2 {
|
|
||||||
margin: 0;
|
|
||||||
color: #333;
|
|
||||||
font-size: 1.25rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview-sections {
|
.preview-sections {
|
||||||
|
|||||||
@@ -111,10 +111,6 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="text-manager">
|
<div class="text-manager">
|
||||||
<div class="text-manager-header">
|
|
||||||
<h2>Управление текстом</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Общие настройки текста -->
|
<!-- Общие настройки текста -->
|
||||||
<div class="common-settings-section">
|
<div class="common-settings-section">
|
||||||
<h3>Общие настройки текста</h3>
|
<h3>Общие настройки текста</h3>
|
||||||
@@ -293,12 +289,6 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-manager-header h2 {
|
|
||||||
margin: 0;
|
|
||||||
color: #333;
|
|
||||||
font-size: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.common-settings-section {
|
.common-settings-section {
|
||||||
background: #f8f9fa;
|
background: #f8f9fa;
|
||||||
border: 2px solid #e9ecef;
|
border: 2px solid #e9ecef;
|
||||||
|
|||||||
+70
-7
@@ -1,4 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { onMount } from "svelte";
|
||||||
import { panelStore, createEmptyPanel } from "../stores/panelStore";
|
import { panelStore, createEmptyPanel } from "../stores/panelStore";
|
||||||
import { uiStore, setLoading, setCurrentStep } from "../stores/uiStore";
|
import { uiStore, setLoading, setCurrentStep } from "../stores/uiStore";
|
||||||
|
|
||||||
@@ -15,6 +16,32 @@
|
|||||||
let currentPanel = $state<Panel | null>(null);
|
let currentPanel = $state<Panel | null>(null);
|
||||||
let errorMessage = $state<string | null>(null);
|
let errorMessage = $state<string | null>(null);
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
// Загружаем фоновое изображение по умолчанию
|
||||||
|
try {
|
||||||
|
const defaultBackground = "/backgrounds/b1.jpg";
|
||||||
|
const response = await fetch(defaultBackground);
|
||||||
|
if (!response.ok) throw new Error("Не удалось загрузить фоновое изображение");
|
||||||
|
const blob = await response.blob();
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = () => {
|
||||||
|
const base64 = reader.result as string;
|
||||||
|
initializePanel(base64);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(blob);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Ошибка загрузки фонового изображения:", error);
|
||||||
|
errorMessage = "Не удалось загрузить фоновое изображение по умолчанию";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function initializePanel(backgroundImage: string) {
|
||||||
|
const newPanel = createEmptyPanel();
|
||||||
|
newPanel.backgroundImage = backgroundImage;
|
||||||
|
panelStore.set(newPanel);
|
||||||
|
currentPanel = newPanel;
|
||||||
|
}
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
currentPanel = $panelStore;
|
currentPanel = $panelStore;
|
||||||
});
|
});
|
||||||
@@ -25,22 +52,30 @@
|
|||||||
setCurrentStep("crop");
|
setCurrentStep("crop");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleUploadNewImage() {
|
||||||
|
setCurrentStep("upload");
|
||||||
|
}
|
||||||
|
|
||||||
function handleCropComplete(croppedImage: string) {
|
function handleCropComplete(croppedImage: string) {
|
||||||
croppedImage = croppedImage;
|
croppedImage = croppedImage;
|
||||||
|
|
||||||
// Создаем новую панель с обрезанным изображением
|
// Обновляем текущую панель с обрезанным изображением
|
||||||
const newPanel = createEmptyPanel();
|
if (currentPanel) {
|
||||||
newPanel.backgroundImage = croppedImage;
|
const updatedPanel = {
|
||||||
|
...currentPanel,
|
||||||
panelStore.set(newPanel);
|
backgroundImage: croppedImage,
|
||||||
currentPanel = newPanel;
|
updatedAt: new Date(),
|
||||||
|
};
|
||||||
|
panelStore.set(updatedPanel);
|
||||||
|
currentPanel = updatedPanel;
|
||||||
|
}
|
||||||
|
|
||||||
setCurrentStep("text");
|
setCurrentStep("text");
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCropCancel() {
|
function handleCropCancel() {
|
||||||
uploadedImage = null;
|
uploadedImage = null;
|
||||||
setCurrentStep("upload");
|
setCurrentStep("text");
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTextUpdate(texts: Panel["texts"]) {
|
function handleTextUpdate(texts: Panel["texts"]) {
|
||||||
@@ -95,7 +130,13 @@
|
|||||||
{:else if $uiStore.currentStep === "crop" && uploadedImage}
|
{:else if $uiStore.currentStep === "crop" && uploadedImage}
|
||||||
<ImageCropper imageSrc={uploadedImage} onCropComplete={handleCropComplete} onCancel={handleCropCancel} />
|
<ImageCropper imageSrc={uploadedImage} onCropComplete={handleCropComplete} onCancel={handleCropCancel} />
|
||||||
{:else if $uiStore.currentStep === "text"}
|
{:else if $uiStore.currentStep === "text"}
|
||||||
|
<div class="text-section">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2>Управление текстом</h2>
|
||||||
|
<button class="btn btn-primary" onclick={handleUploadNewImage}>Загрузить другое изображение</button>
|
||||||
|
</div>
|
||||||
<TextManager onTextUpdate={handleTextUpdate} />
|
<TextManager onTextUpdate={handleTextUpdate} />
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -146,6 +187,28 @@
|
|||||||
gap: 1.5rem;
|
gap: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1rem;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
border-radius: 8px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header h2 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { type UIState } from "../lib/types/panel";
|
|||||||
export const uiStore: Writable<UIState> = writable({
|
export const uiStore: Writable<UIState> = writable({
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
error: null,
|
error: null,
|
||||||
currentStep: "upload",
|
currentStep: "text",
|
||||||
showCropModal: false,
|
showCropModal: false,
|
||||||
showTextManager: false,
|
showTextManager: false,
|
||||||
});
|
});
|
||||||
@@ -37,7 +37,7 @@ export const resetUI = (): void => {
|
|||||||
uiStore.set({
|
uiStore.set({
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
error: null,
|
error: null,
|
||||||
currentStep: "upload",
|
currentStep: "text",
|
||||||
showCropModal: false,
|
showCropModal: false,
|
||||||
showTextManager: false,
|
showTextManager: false,
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user