fix big size image
deploy to danak / build_and_deploy (push) Has been cancelled

This commit is contained in:
hamid zarghami
2026-06-15 16:40:08 +03:30
parent 8b194fd7cd
commit b8de25e9d1
5 changed files with 105 additions and 17 deletions
@@ -2,6 +2,7 @@ import { useEffect, useRef } from "react";
import { Group, Rect, Circle, RegularPolygon, Star } from "react-konva"; import { Group, Rect, Circle, RegularPolygon, Star } from "react-konva";
import Konva from "konva"; import Konva from "konva";
import type { EditorObject } from "../../store/editorStore"; import type { EditorObject } from "../../store/editorStore";
import { getNodeTransformDimensions } from "../../utils/transformCommit";
import { import {
RectangleShape, RectangleShape,
CircleShape, CircleShape,
@@ -404,9 +405,10 @@ const ObjectRenderer = ({
newWidth = Math.max(5, (obj.width || 100) * scaleX); newWidth = Math.max(5, (obj.width || 100) * scaleX);
newHeight = Math.max(5, (obj.height || 100) * scaleY); newHeight = Math.max(5, (obj.height || 100) * scaleY);
} else { } else {
// Default for other objects (image, etc.) const { width: baseWidth, height: baseHeight } =
newWidth = Math.max(5, (obj.width || 100) * scaleX); getNodeTransformDimensions(node);
newHeight = Math.max(5, (obj.height || 100) * scaleY); newWidth = Math.max(5, baseWidth * scaleX);
newHeight = Math.max(5, baseHeight * scaleY);
} }
// به‌روزرسانی object // به‌روزرسانی object
@@ -1,6 +1,11 @@
import { useEffect, type RefObject } from "react"; import { useEffect, useRef, type RefObject } from "react";
import Konva from "konva"; import Konva from "konva";
import { useEditorStore } from "../../store/editorStore"; import { useEditorStore } from "../../store/editorStore";
import {
getNodeTransformDimensions,
nodeHasPendingTransform,
resolveObjectFromNodeId,
} from "../../utils/transformCommit";
export const useTransformHandlers = ( export const useTransformHandlers = (
transformerRef: RefObject<Konva.Transformer | null>, transformerRef: RefObject<Konva.Transformer | null>,
@@ -12,6 +17,7 @@ export const useTransformHandlers = (
updateObject, updateObject,
applyTableResize, applyTableResize,
} = useEditorStore(); } = useEditorStore();
const commitTransformRef = useRef<(() => void) | null>(null);
// Attach transformer to selected objects when they change // Attach transformer to selected objects when they change
useEffect(() => { useEffect(() => {
@@ -60,7 +66,15 @@ export const useTransformHandlers = (
} }
}, 100); }, 100);
return () => clearTimeout(timeoutId); return () => {
clearTimeout(timeoutId);
const transformer = transformerRef.current;
if (!transformer) return;
const nodes = transformer.nodes();
if (nodes.some(nodeHasPendingTransform)) {
commitTransformRef.current?.();
}
};
}, [selectedObjectIds, objects, transformerRef, layerRef]); }, [selectedObjectIds, objects, transformerRef, layerRef]);
useEffect(() => { useEffect(() => {
@@ -148,7 +162,7 @@ export const useTransformHandlers = (
nodes.forEach((node) => { nodes.forEach((node) => {
const nodeId = node.id(); const nodeId = node.id();
const selectedObject = objects.find((obj) => obj.id === nodeId); const selectedObject = resolveObjectFromNodeId(nodeId, objects);
if (!selectedObject) return; if (!selectedObject) return;
// Handle group objects // Handle group objects
@@ -505,23 +519,28 @@ export const useTransformHandlers = (
height: Math.max(1, newHeight), height: Math.max(1, newHeight),
}); });
} else { } else {
// Default for other objects (image, etc.) // Default for raster objects (image, sticker, document, video, …)
const { width: baseWidth, height: baseHeight } =
getNodeTransformDimensions(node);
updateObject(selectedObject.id, { updateObject(selectedObject.id, {
x: node.x(), x: node.x(),
y: node.y(), y: node.y(),
rotation: node.rotation(), rotation: node.rotation(),
width: Math.max(5, (selectedObject.width || 100) * scaleX), width: Math.max(5, baseWidth * scaleX),
height: Math.max(5, (selectedObject.height || 100) * scaleY), height: Math.max(5, baseHeight * scaleY),
}); });
} }
} }
}); });
}; };
commitTransformRef.current = handleTransformEnd;
transformer.on("transform", handleTransform); transformer.on("transform", handleTransform);
transformer.on("transformend", handleTransformEnd); transformer.on("transformend", handleTransformEnd);
return () => { return () => {
commitTransformRef.current = null;
transformer.off("transform", handleTransform); transformer.off("transform", handleTransform);
transformer.off("transformend", handleTransformEnd); transformer.off("transformend", handleTransformEnd);
}; };
+47
View File
@@ -0,0 +1,47 @@
import Konva from "konva";
import type { EditorObject } from "../store/editorStore";
/** Resolve editor object from a Konva node id (supports masked-* groups). */
export const resolveObjectFromNodeId = (
nodeId: string,
objects: EditorObject[],
): EditorObject | undefined => {
if (nodeId.startsWith("masked-")) {
const objectId = nodeId.slice("masked-".length);
return objects.find((obj) => obj.id === objectId);
}
return objects.find((obj) => obj.id === nodeId);
};
/**
* Base width/height used for transform baking.
* For images, Konva may use natural image size while store width is still unset.
*/
export const getNodeTransformDimensions = (
node: Konva.Node,
): { width: number; height: number } => {
const nodeWidth = node.width();
const nodeHeight = node.height();
if (nodeWidth > 0 && nodeHeight > 0) {
return { width: nodeWidth, height: nodeHeight };
}
const imageNode =
"findOne" in node
? (node as Konva.Container).findOne<Konva.Image>("Image")
: undefined;
if (imageNode && imageNode.width() > 0 && imageNode.height() > 0) {
return { width: imageNode.width(), height: imageNode.height() };
}
const rect = node.getClientRect({ skipTransform: true });
if (rect.width > 0 && rect.height > 0) {
return { width: rect.width, height: rect.height };
}
return { width: 100, height: 100 };
};
export const nodeHasPendingTransform = (node: Konva.Node): boolean =>
Math.abs(node.scaleX() - 1) > 0.0001 ||
Math.abs(node.scaleY() - 1) > 0.0001;
+24 -7
View File
@@ -14,6 +14,28 @@ import { mergeEntranceAnimationStyle } from '@/pages/viewer/utils/entranceAnimat
import { getMaskImageStyle, getMaskedLayout } from '@/pages/viewer/utils/maskStyle'; import { getMaskImageStyle, getMaskedLayout } from '@/pages/viewer/utils/maskStyle';
import type { EntrancePhase } from '@/pages/viewer/hooks/useBookEntranceController'; import type { EntrancePhase } from '@/pages/viewer/hooks/useBookEntranceController';
const getRasterObjectStyle = (
obj: EditorObject,
scale: number,
baseStyle: React.CSSProperties,
index: number,
): React.CSSProperties => {
const scaleX = obj.scaleX ?? 1;
const scaleY = obj.scaleY ?? 1;
const width = obj.width != null ? obj.width * scaleX * scale : undefined;
const height = obj.height != null ? obj.height * scaleY * scale : undefined;
return {
...baseStyle,
display: 'block',
maxWidth: 'none',
width: width != null ? `${width}px` : 'auto',
height: height != null ? `${height}px` : 'auto',
objectFit: 'fill',
zIndex: index,
};
};
type RenderObjectOptions = { type RenderObjectOptions = {
skipEntrance?: boolean; skipEntrance?: boolean;
}; };
@@ -200,19 +222,14 @@ const BookPage = forwardRef<HTMLDivElement, BookPageProps>(
case 'image': case 'image':
case 'sticker': case 'sticker':
case 'document':
return ( return (
<img <img
key={obj.id || index} key={obj.id || index}
src={obj.imageUrl || ''} src={obj.imageUrl || ''}
alt="" alt=""
style={applyStyle( style={applyStyle(
{ getRasterObjectStyle(obj, scale, baseStyle, index),
...baseStyle,
width: obj.width ? `${obj.width * scale}px` : 'auto',
height: obj.height ? `${obj.height * scale}px` : 'auto',
objectFit: 'fill', // مشابه Konva که image را با width و height مشخص شده رندر می‌کند
zIndex: index, // برای حفظ ترتیب رندر
},
obj, obj,
index, index,
)} )}
+4 -1
View File
@@ -128,7 +128,10 @@ export function transformViewerDataToPages(data: ViewerData): PageData[] {
baseObject.borderRadius = obj.borderRadius; baseObject.borderRadius = obj.borderRadius;
} }
if ((obj.type === "image" || obj.type === "sticker") && obj.imageUrl) { if (
(obj.type === "image" || obj.type === "sticker" || obj.type === "document") &&
obj.imageUrl
) {
baseObject.imageUrl = obj.imageUrl; baseObject.imageUrl = obj.imageUrl;
} }