From bf54d37306d476a3cd87999b74bd2052bab43f7f Mon Sep 17 00:00:00 2001 From: ct Date: Tue, 17 Jun 2025 20:55:51 +0800 Subject: [PATCH] Update --- .../editor/partials/canvas/video-preview.jsx | 42 +++++++++++++------ .../modules/editor/partials/text-sidebar.jsx | 9 ++-- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/resources/js/modules/editor/partials/canvas/video-preview.jsx b/resources/js/modules/editor/partials/canvas/video-preview.jsx index 33d8b07..2374c0c 100644 --- a/resources/js/modules/editor/partials/canvas/video-preview.jsx +++ b/resources/js/modules/editor/partials/canvas/video-preview.jsx @@ -292,7 +292,7 @@ const VideoPreview = ({ [onElementUpdate, timelineElements], ); - // Handle transform events (scale, rotate) with snapping - USES NATIVE KONVA ROTATION SNAPPING + // Handle transform events - TRANSFORMER IS SOURCE OF TRUTH const handleTransform = useCallback( (elementId) => { const node = elementRefs.current[elementId]; @@ -307,11 +307,25 @@ const VideoPreview = ({ const scaleY = node.scaleY(); let newWidth, newHeight; + let updates = { rotation }; if (element.type === 'text') { - // For text, allow free scaling - newWidth = node.width() * scaleX; - newHeight = node.height() * scaleY; + // For text: Convert scale to actual fontSize and reset scale to 1 + const avgScale = Math.max(Math.abs(scaleX), Math.abs(scaleY)); + const newFontSize = Math.round(element.fontSize * avgScale); + + // Clamp font size to reasonable limits + const clampedFontSize = Math.max(8, Math.min(120, newFontSize)); + + updates.fontSize = clampedFontSize; + + // Reset scale to 1 since we've applied it to fontSize + node.scaleX(1); + node.scaleY(1); + + // Text dimensions are handled by Konva based on content and fontSize + newWidth = node.width(); + newHeight = node.height(); } else { // For images/videos, maintain aspect ratio by using the larger scale const scale = Math.max(Math.abs(scaleX), Math.abs(scaleY)); @@ -327,6 +341,9 @@ const VideoPreview = ({ // Update offset for center rotation node.offsetX(newWidth / 2); node.offsetY(newHeight / 2); + + updates.width = newWidth; + updates.height = newHeight; } // Calculate position for snapping @@ -375,16 +392,12 @@ const VideoPreview = ({ }); } - // Update state with the final calculated values - const finalTransform = { - x: topLeftX, - y: topLeftY, - width: newWidth, - height: newHeight, - rotation: rotation, - }; + // Add position to updates + updates.x = topLeftX; + updates.y = topLeftY; - onElementUpdate(elementId, finalTransform); + // Update state with all calculated values + onElementUpdate(elementId, updates); }, [onElementUpdate, dimensions.width, dimensions.height, timelineElements], ); @@ -471,6 +484,9 @@ const VideoPreview = ({ align="center" // Let text have natural width and height for multiline support wrap="word" + // Always scale 1 - size changes go through fontSize + scaleX={1} + scaleY={1} draggable dragBoundFunc={createDragBoundFunc(element.id)} onClick={() => handleElementSelect(element.id)} diff --git a/resources/js/modules/editor/partials/text-sidebar.jsx b/resources/js/modules/editor/partials/text-sidebar.jsx index e22b1ae..24f8975 100644 --- a/resources/js/modules/editor/partials/text-sidebar.jsx +++ b/resources/js/modules/editor/partials/text-sidebar.jsx @@ -35,11 +35,11 @@ export default function TextSidebar({ isOpen, onClose }) { const MAX_FONT_SIZE = 120; const FONT_SIZE_STEP = 2; - // Update state when selected element changes + // Update state when selected element changes - THIS KEEPS SIDEBAR IN SYNC WITH TRANSFORMER useEffect(() => { if (selectedTextElement) { setTextValue(selectedTextElement.text || ''); - setFontSize(selectedTextElement.fontSize || 24); + setFontSize(selectedTextElement.fontSize || 24); // Always use current fontSize from element setIsBold(selectedTextElement.fontWeight === 'bold' || selectedTextElement.fontWeight === 700 || true); setIsItalic(selectedTextElement.fontStyle === 'italic' || false); setFontFamily(selectedTextElement.fontFamily || 'Montserrat'); @@ -59,7 +59,7 @@ export default function TextSidebar({ isOpen, onClose }) { } }; - // Handle font size changes + // Handle font size changes - CLAMP AND UPDATE const handleFontSizeChange = (newSize) => { const clampedSize = Math.max(MIN_FONT_SIZE, Math.min(MAX_FONT_SIZE, newSize)); setFontSize(clampedSize); @@ -196,6 +196,9 @@ export default function TextSidebar({ isOpen, onClose }) {
Size range: {MIN_FONT_SIZE}px - {MAX_FONT_SIZE}px
+ + {/* Note about transformer resize */} +
💡 You can also resize by dragging the corners
{/* Font Style Controls */}