Files
dpage-editor/src/pages/viewer/utils/dataTransformer.ts
T
hamid zarghami ca02a621da
deploy to danak / build_and_deploy (push) Has been cancelled
paint
2026-06-20 15:32:02 +03:30

206 lines
7.0 KiB
TypeScript

import type { EditorObject, TableData } from "@/pages/editor/store/editorStore";
import { normalizeCustomShapeObject, normalizePencilObject } from "@/pages/editor/utils/customShape";
import type { PageData } from "../types";
type ViewerDataPage = {
id: string;
name: string;
backgroundType?: "color" | "gradient" | "image";
backgroundColor?: string;
backgroundGradient?: {
from: string;
to: string;
angle: number;
};
backgroundImageUrl?: string;
objects: Array<{
id: string;
type: string;
x: number;
y: number;
width?: number;
height?: number;
text?: string;
fontSize?: number;
fontFamily?: string;
fontWeight?: string;
lineHeight?: number;
textAlign?: "left" | "center" | "right";
fill?: string;
fillType?: "solid" | "gradient";
gradient?: {
from: string;
to: string;
angle: number;
};
stroke?: string;
strokeWidth?: number;
shapeType?: string;
borderRadius?: number;
imageUrl?: string;
videoUrl?: string;
audioUrl?: string;
linkUrl?: string;
rotation?: number;
opacity?: number;
letterSpacing?: number;
tableData?: TableData;
entranceAnimation?: EditorObject["entranceAnimation"];
entranceDurationMs?: number;
entranceDelayMs?: number;
isMask?: boolean;
maskId?: string;
maskInvert?: boolean;
points?: number[];
closed?: boolean;
tension?: number;
}>;
};
type ViewerData = {
pages: ViewerDataPage[];
};
/**
* تبدیل داده‌های viewer-data.json به فرمت PageData
*/
export function transformViewerDataToPages(data: ViewerData): PageData[] {
return data.pages.map((page, index) => {
const objects: EditorObject[] = page.objects.map((obj) => {
const baseObject: EditorObject = {
id: obj.id,
type: obj.type as EditorObject["type"],
x: obj.x,
y: obj.y,
// در JSON، opacity به صورت 0-100 است (درصد)
// در editor هم opacity به صورت 0-100 است
// پس opacity را مستقیماً استفاده می‌کنیم
opacity: obj.opacity !== undefined ? obj.opacity : 100,
visible: true,
};
// برای line و arrow، width و height در viewer-data.json به عنوان مختصات انتهایی هستند
// در EditorObject هم به عنوان مختصات انتهایی ذخیره می‌شوند
if (obj.type === "line" || obj.type === "arrow") {
// width و height مستقیماً مختصات نقطه پایان هستند
if (obj.width !== undefined) {
baseObject.width = obj.width;
}
if (obj.height !== undefined) {
baseObject.height = obj.height;
}
} else {
if (obj.width !== undefined) baseObject.width = obj.width;
if (obj.height !== undefined) baseObject.height = obj.height;
}
// برای circle در viewer-data.json، x, y به عنوان گوشه بالا-چپ bounding box است
// اما در editor، circle با مرکز در x, y ذخیره می‌شود
// پس باید تبدیل کنیم
// اما بر اساس بررسی، در JSON موقعیت به عنوان مرکز ذخیره شده است
// پس نباید تبدیل کنیم - مستقیماً استفاده می‌کنیم
// اگر در آینده JSON به صورت گوشه بالا-چپ export شود، باید تبدیل کنیم:
// baseObject.x = obj.x + (obj.width || 100) / 2;
// baseObject.y = obj.y + (obj.height || 100) / 2;
// اما فعلاً JSON به صورت مرکز است، پس تبدیل نمی‌کنیم
if (obj.fill !== undefined) baseObject.fill = obj.fill;
if (obj.fillType !== undefined) baseObject.fillType = obj.fillType;
if (obj.gradient !== undefined) baseObject.gradient = obj.gradient;
if (obj.stroke !== undefined) baseObject.stroke = obj.stroke;
if (obj.strokeWidth !== undefined)
baseObject.strokeWidth = obj.strokeWidth;
if (obj.rotation !== undefined) baseObject.rotation = obj.rotation;
// ویژگی‌های متنی
if (obj.text !== undefined) baseObject.text = obj.text;
if (obj.fontSize !== undefined) baseObject.fontSize = obj.fontSize;
if (obj.fontFamily !== undefined) baseObject.fontFamily = obj.fontFamily;
if (obj.fontWeight !== undefined) baseObject.fontWeight = obj.fontWeight;
if (obj.letterSpacing !== undefined)
baseObject.letterSpacing = obj.letterSpacing;
if (obj.lineHeight !== undefined) baseObject.lineHeight = obj.lineHeight;
if (obj.textAlign !== undefined) baseObject.textAlign = obj.textAlign;
// انواع خاص objectها
if (obj.type === "rectangle" && obj.shapeType) {
baseObject.shapeType = obj.shapeType as EditorObject["shapeType"];
}
if (obj.type === "rectangle" && obj.borderRadius !== undefined) {
baseObject.borderRadius = obj.borderRadius;
}
if (
(obj.type === "image" || obj.type === "sticker" || obj.type === "document") &&
obj.imageUrl
) {
baseObject.imageUrl = obj.imageUrl;
}
if (obj.type === "video" && obj.videoUrl) {
baseObject.videoUrl = obj.videoUrl;
}
if (obj.type === "audio" && obj.audioUrl) {
baseObject.audioUrl = obj.audioUrl;
}
if (obj.type === "link" && obj.linkUrl) {
baseObject.linkUrl = obj.linkUrl;
}
if (obj.type === "grid" && obj.tableData) {
baseObject.tableData = obj.tableData;
}
if (obj.entranceAnimation !== undefined) {
baseObject.entranceAnimation = obj.entranceAnimation;
}
if (obj.entranceDurationMs !== undefined) {
baseObject.entranceDurationMs = obj.entranceDurationMs;
}
if (obj.entranceDelayMs !== undefined) {
baseObject.entranceDelayMs = obj.entranceDelayMs;
}
if (obj.isMask !== undefined) {
baseObject.isMask = obj.isMask;
}
if (obj.maskId !== undefined) {
baseObject.maskId = obj.maskId;
}
if (obj.maskInvert !== undefined) {
baseObject.maskInvert = obj.maskInvert;
}
if (obj.type === "custom-shape") {
if (obj.points !== undefined) baseObject.points = obj.points;
if (obj.closed !== undefined) baseObject.closed = obj.closed;
}
if (obj.type === "pencil") {
if (obj.points !== undefined) baseObject.points = obj.points;
if (obj.closed !== undefined) baseObject.closed = obj.closed;
if (obj.tension !== undefined) baseObject.tension = obj.tension;
}
const normalized =
obj.type === "pencil"
? normalizePencilObject(baseObject)
: normalizeCustomShapeObject(baseObject);
return normalized;
});
return {
id: index + 1,
width: 794,
height: 1123,
elements: objects,
backgroundType: page.backgroundType,
backgroundColor: page.backgroundColor,
backgroundGradient: page.backgroundGradient,
backgroundImageUrl: page.backgroundImageUrl,
};
});
}