206 lines
7.0 KiB
TypeScript
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,
|
|
};
|
|
});
|
|
}
|