diff options
Diffstat (limited to 'apps/web/src/components/editor/preview-panel.tsx')
| -rw-r--r-- | apps/web/src/components/editor/preview-panel.tsx | 66 |
1 files changed, 32 insertions, 34 deletions
diff --git a/apps/web/src/components/editor/preview-panel.tsx b/apps/web/src/components/editor/preview-panel.tsx index 2359ecd8..639858d0 100644 --- a/apps/web/src/components/editor/preview-panel.tsx +++ b/apps/web/src/components/editor/preview-panel.tsx @@ -23,6 +23,7 @@ import { formatTimeCode } from "@/lib/time"; import { FONT_CLASS_MAP } from "@/lib/font-config"; import { BackgroundSettings } from "../background-settings"; import { useProjectStore } from "@/stores/project-store"; +import { TextElementDragState } from "@/types/editor"; interface ActiveElement { element: TimelineElement; @@ -43,21 +44,7 @@ export function PreviewPanel() { }); const [isExpanded, setIsExpanded] = useState(false); const { activeProject } = useProjectStore(); - - // Drag state for text elements - const [dragState, setDragState] = useState<{ - isDragging: boolean; - elementId: string | null; - trackId: string | null; - startX: number; - startY: number; - initialElementX: number; - initialElementY: number; - currentX: number; - currentY: number; - elementWidth: number; - elementHeight: number; - }>({ + const [dragState, setDragState] = useState<TextElementDragState>({ isDragging: false, elementId: null, trackId: null, @@ -156,7 +143,6 @@ export function PreviewPanel() { }; }, [isExpanded]); - // Handle mouse events for text dragging useEffect(() => { const handleMouseMove = (e: MouseEvent) => { if (!dragState.isDragging) return; @@ -168,11 +154,17 @@ export function PreviewPanel() { const newX = dragState.initialElementX + deltaX / scaleRatio; const newY = dragState.initialElementY + deltaY / scaleRatio; - const halfWidth = (dragState.elementWidth / scaleRatio) / 2; - const halfHeight = (dragState.elementHeight / scaleRatio) / 2; + const halfWidth = dragState.elementWidth / scaleRatio / 2; + const halfHeight = dragState.elementHeight / scaleRatio / 2; - const constrainedX = Math.max(-canvasSize.width / 2 + halfWidth, Math.min(canvasSize.width / 2 - halfWidth, newX)); - const constrainedY = Math.max(-canvasSize.height / 2 + halfHeight, Math.min(canvasSize.height / 2 - halfHeight, newY)); + const constrainedX = Math.max( + -canvasSize.width / 2 + halfWidth, + Math.min(canvasSize.width / 2 - halfWidth, newX) + ); + const constrainedY = Math.max( + -canvasSize.height / 2 + halfHeight, + Math.min(canvasSize.height / 2 - halfHeight, newY) + ); setDragState((prev) => ({ ...prev, @@ -192,24 +184,28 @@ export function PreviewPanel() { }; if (dragState.isDragging) { - document.addEventListener('mousemove', handleMouseMove); - document.addEventListener('mouseup', handleMouseUp); - document.body.style.cursor = 'grabbing'; - document.body.style.userSelect = 'none'; + document.addEventListener("mousemove", handleMouseMove); + document.addEventListener("mouseup", handleMouseUp); + document.body.style.cursor = "grabbing"; + document.body.style.userSelect = "none"; } return () => { - document.removeEventListener('mousemove', handleMouseMove); - document.removeEventListener('mouseup', handleMouseUp); - document.body.style.cursor = ''; - document.body.style.userSelect = ''; + document.removeEventListener("mousemove", handleMouseMove); + document.removeEventListener("mouseup", handleMouseUp); + document.body.style.cursor = ""; + document.body.style.userSelect = ""; }; }, [dragState, previewDimensions, canvasSize, updateTextElement]); - const handleTextMouseDown = (e: React.MouseEvent<HTMLDivElement>, element: any, trackId: string) => { + const handleTextMouseDown = ( + e: React.MouseEvent<HTMLDivElement>, + element: any, + trackId: string + ) => { e.preventDefault(); e.stopPropagation(); - + const rect = e.currentTarget.getBoundingClientRect(); setDragState({ @@ -249,7 +245,7 @@ export function PreviewPanel() { element.mediaId === "test" ? null : mediaItems.find((item) => item.id === element.mediaId) || - null; + null; } activeElements.push({ element, track, mediaItem }); } @@ -355,7 +351,9 @@ export function PreviewPanel() { <div key={element.id} className="absolute flex items-center justify-center cursor-grab" - onMouseDown={(e) => handleTextMouseDown(e, element, elementData.track.id)} + onMouseDown={(e) => + handleTextMouseDown(e, element, elementData.track.id) + } style={{ left: `${50 + ((dragState.isDragging && dragState.elementId === element.id ? dragState.currentX : element.x) / canvasSize.width) * 100}%`, top: `${50 + ((dragState.isDragging && dragState.elementId === element.id ? dragState.currentY : element.y) / canvasSize.height) * 100}%`, @@ -467,7 +465,7 @@ export function PreviewPanel() { ref={containerRef} className="flex-1 flex flex-col items-center justify-center p-3 min-h-0 min-w-0" > - <div className="flex-1"></div> + <div className="flex-1" /> {hasAnyElements ? ( <div ref={previewRef} @@ -501,7 +499,7 @@ export function PreviewPanel() { </div> ) : null} - <div className="flex-1"></div> + <div className="flex-1" /> <PreviewToolbar hasAnyElements={hasAnyElements} |
