fix: resolve crop errors

This commit is contained in:
2026-02-03 23:38:13 +05:00
parent c18ea19316
commit 539b836d39
4 changed files with 55 additions and 32 deletions
+31 -11
View File
@@ -6,12 +6,16 @@
import { ImageService } from "../lib/services/imageService"; import { ImageService } from "../lib/services/imageService";
import { uiStore, setLoading } from "../stores/uiStore"; import { uiStore, setLoading } from "../stores/uiStore";
let Cropper: any = $state(undefined); let Cropper: any;
onMount(async () => { onMount(async () => {
if (browser) { if (browser) {
console.log("Loading cropperjs module");
const cropperModule = await import("cropperjs"); const cropperModule = await import("cropperjs");
Cropper = cropperModule.default; console.log("cropperjs module loaded:", cropperModule);
Cropper = cropperModule.default || cropperModule;
console.log("Cropper class:", Cropper);
console.log("Cropper.getCroppedCanvas:", typeof Cropper?.prototype?.getCroppedCanvas);
// Импортируем стили только на клиенте // Импортируем стили только на клиенте
@@ -44,8 +48,13 @@
}); });
function initializeCropper() { function initializeCropper() {
if (!imageElement || !Cropper) return; console.log("initializeCropper called, imageElement:", !!imageElement, "Cropper:", !!Cropper);
if (!imageElement || !Cropper) {
console.error("Cannot initialize cropper: imageElement:", !!imageElement, "Cropper:", !!Cropper);
return;
}
console.log("Creating new Cropper instance");
cropper = new Cropper(imageElement, { cropper = new Cropper(imageElement, {
aspectRatio: NaN, // Allow any aspect ratio aspectRatio: NaN, // Allow any aspect ratio
viewMode: 1, viewMode: 1,
@@ -62,27 +71,38 @@
minCropBoxHeight: 50, minCropBoxHeight: 50,
responsive: true, responsive: true,
}); });
console.log("Cropper instance created:", cropper);
console.log("cropper.getCroppedCanvas:", typeof cropper?.getCroppedCanvas);
console.log("cropper methods:", Object.getOwnPropertyNames(Object.getPrototypeOf(cropper)));
} }
async function handleCrop() { async function handleCrop() {
if (!cropper) return; console.log("handleCrop called, cropper:", cropper);
if (!cropper) {
console.error("Cropper is not initialized");
return;
}
try { try {
isProcessing = true; isProcessing = true;
errorMessage = null; errorMessage = null;
setLoading(true); setLoading(true);
const canvas = cropper.getCroppedCanvas({ console.log("Calling getCropperImage");
width: 320, const image = cropper.getCropperImage();
imageSmoothingEnabled: true, console.log("Image result:", image);
imageSmoothingQuality: "high", console.log("Image type:", typeof image);
});
if (!canvas) { if (!image) {
throw new Error("Не удалось получить обрезанное изображение"); throw new Error("Не удалось получить обрезанное изображение");
} }
const croppedImage = canvas.toDataURL("image/png"); // Проверяем, есть ли у image метод toDataURL
if (typeof image.toDataURL === "function") {
const croppedImage = image.toDataURL("image/png");
} else {
throw new Error("Изображение не имеет метода toDataURL");
}
// Validate cropped image // Validate cropped image
const cropResult: ImageCropResult = { const cropResult: ImageCropResult = {
+11 -1
View File
@@ -8,6 +8,8 @@
let imageService = new ImageService(); let imageService = new ImageService();
let { onImageSelect }: { onImageSelect: (image: string) => void } = $props();
let dropZone = $state<HTMLElement | null>(null); let dropZone = $state<HTMLElement | null>(null);
let fileInput = $state<HTMLInputElement | null>(null); let fileInput = $state<HTMLInputElement | null>(null);
let urlInput = $state<HTMLInputElement | null>(null); let urlInput = $state<HTMLInputElement | null>(null);
@@ -66,14 +68,18 @@
} }
async function handleFileUpload(file: File) { async function handleFileUpload(file: File) {
console.log("handleFileUpload called with file:", file.name, "size:", file.size);
try { try {
setLoading(true); setLoading(true);
clearError(); clearError();
console.log("Calling imageService.handleFileUpload");
const result: ImageUploadResult = await imageService.handleFileUpload(file); const result: ImageUploadResult = await imageService.handleFileUpload(file);
console.log("Image upload result - success:", result.success, "has image:", !!result.image);
if (result.success && result.image) { if (result.success && result.image) {
uploadedImage = result.image; uploadedImage = result.image;
console.log("Calling onImageSelect with image length:", result.image.length);
onImageSelect(result.image);
setCurrentStep("crop"); setCurrentStep("crop");
} else { } else {
errorMessage = result.error || "Ошибка загрузки файла"; errorMessage = result.error || "Ошибка загрузки файла";
@@ -96,6 +102,8 @@
if (result.success && result.image) { if (result.success && result.image) {
uploadedImage = result.image; uploadedImage = result.image;
console.log("Calling onImageSelect with image length:", result.image.length);
onImageSelect(result.image);
setCurrentStep("crop"); setCurrentStep("crop");
} else { } else {
errorMessage = result.error || "Ошибка вставки изображения"; errorMessage = result.error || "Ошибка вставки изображения";
@@ -120,6 +128,8 @@
if (result.success && result.image) { if (result.success && result.image) {
uploadedImage = result.image; uploadedImage = result.image;
console.log("Calling onImageSelect with image length:", result.image.length);
onImageSelect(result.image);
setCurrentStep("crop"); setCurrentStep("crop");
showUrlInput = false; showUrlInput = false;
} else { } else {
+4 -4
View File
@@ -10,10 +10,10 @@
onDownload?: () => void; onDownload?: () => void;
} = $props(); } = $props();
let Stage: any = $state(undefined); let Stage: any;
let Layer: any = $state(undefined); let Layer: any;
let Image: any = $state(undefined); let Image: any;
let Text: any = $state(undefined); let Text: any;
let currentPanel = $state<Panel | null>(null); let currentPanel = $state<Panel | null>(null);
let backgroundImage: HTMLImageElement | undefined = $state(undefined); let backgroundImage: HTMLImageElement | undefined = $state(undefined);
+9 -16
View File
@@ -1,4 +1,3 @@
<script lang="ts"> <script lang="ts">
import { onMount } from "svelte"; import { onMount } from "svelte";
import { browser } from "$app/environment"; import { browser } from "$app/environment";
@@ -45,9 +44,12 @@
}); });
function handleImageUpload(image: string) { function handleImageUpload(image: string) {
console.log("handleImageUpload called with image length:", image.length);
uploadedImage = image; uploadedImage = image;
errorMessage = null; errorMessage = null;
uiStore.setCurrentStep("crop"); console.log("Setting current step to crop");
setCurrentStep("crop");
console.log("Current step after setting:", $uiStore.currentStep);
} }
function handleCropComplete(croppedImage: string) { function handleCropComplete(croppedImage: string) {
@@ -143,27 +145,22 @@
{#if $uiStore.currentStep === "upload"} {#if $uiStore.currentStep === "upload"}
{#if ImageUpload} {#if ImageUpload}
{@const Upload = ImageUpload.default} {@const Upload = ImageUpload.default}
<svelte:component this={Upload} onImageSelect={handleImageUpload} /> <Upload onImageSelect={handleImageUpload} />
{/if} {/if}
{:else if $uiStore.currentStep === "crop" && uploadedImage} {:else if $uiStore.currentStep === "crop" && uploadedImage}
{#if ImageCropper} {#if ImageCropper}
{@const Cropper = ImageCropper.default} {@const Cropper = ImageCropper.default}
<svelte:component <Cropper imageSrc={uploadedImage} onCropComplete={handleCropComplete} onCancel={handleCropCancel} />
this={Cropper}
imageSrc={uploadedImage}
onCropComplete={handleCropComplete}
onCancel={handleCropCancel}
/>
{/if} {/if}
{:else if $uiStore.currentStep === "text"} {:else if $uiStore.currentStep === "text"}
{#if TextManager} {#if TextManager}
{@const Manager = TextManager.default} {@const Manager = TextManager.default}
<svelte:component this={Manager} onTextUpdate={handleTextUpdate} /> <Manager onTextUpdate={handleTextUpdate} />
{/if} {/if}
{:else if $uiStore.currentStep === "preview"} {:else if $uiStore.currentStep === "preview"}
{#if PanelPreview} {#if PanelPreview}
{@const Preview = PanelPreview.default} {@const Preview = PanelPreview.default}
<svelte:component this={Preview} onDownload={handleDownload} /> <Preview onDownload={handleDownload} />
{/if} {/if}
{/if} {/if}
</div> </div>
@@ -171,11 +168,7 @@
<div class="sidebar"> <div class="sidebar">
{#if PanelList} {#if PanelList}
{@const List = PanelList.default} {@const List = PanelList.default}
<svelte:component <List onPanelSelect={handlePanelSelect} onPanelDelete={handlePanelDelete} />
this={List}
onPanelSelect={handlePanelSelect}
onPanelDelete={handlePanelDelete}
/>
{/if} {/if}
</div> </div>
</div> </div>