// video-preview-utils.js // Import centralized font management import { getFontStyle } from '@/modules/editor/fonts'; // Snap settings export const POSITION_SNAP_THRESHOLD = 10; // Pixels within which to snap to center // Function to determine which image source to use for videos export const getImageSource = (element, videoStates, isPlaying) => { const isVideoActive = videoStates[element.id] && isPlaying; if (isVideoActive && element.videoElement && element.isVideoReady) { return element.videoElement; } else if (element.posterImage && element.isVideoPoster) { return element.posterImage; } return null; }; // Re-export the centralized font style function for backward compatibility export { getFontStyle as getTextFontStyle }; // Check if element uses center-offset positioning export const usesCenterPositioning = (elementType) => { return elementType === 'video' || elementType === 'image'; }; // Helper function to get the visual bounds of an element accounting for offsetX export const getVisualBounds = (element, x, y, width, height) => { // Check if element has offsetX property if (element.offsetX !== undefined) { // For elements with offsetX, calculate the visual position const visualLeft = x - element.offsetX; const elementWidth = element.fixedWidth || width; return { left: visualLeft, top: y, right: visualLeft + elementWidth, bottom: y + height, width: elementWidth, height: height, centerX: visualLeft + elementWidth / 2, centerY: y + height / 2, }; } else if (usesCenterPositioning(element.type)) { // For center-positioned elements (video/image) const left = x - width / 2; const top = y - height / 2; return { left: left, top: top, right: left + width, bottom: top + height, width: width, height: height, centerX: x, centerY: y, }; } else { // For regular top-left positioned elements return { left: x, top: y, right: x + width, bottom: y + height, width: width, height: height, centerX: x + width / 2, centerY: y + height / 2, }; } }; // Check if position should snap to center and calculate guide lines export const calculateSnapAndGuides = (elementId, newX, newY, width, height, timelineElements, dimensions) => { const centerX = dimensions.width / 2; const centerY = dimensions.height / 2; const element = timelineElements.find((el) => el.id === elementId); if (!element) return { x: newX, y: newY, guideLines: { vertical: null, horizontal: null, showVertical: false, showHorizontal: false, }, }; // Get visual bounds accounting for offsetX and fixedWidth const visualBounds = getVisualBounds(element, newX, newY, width, height); let snapX = newX; let snapY = newY; let showVertical = false; let showHorizontal = false; let verticalLine = null; let horizontalLine = null; // Check vertical center snap using visual center if (Math.abs(visualBounds.centerX - centerX) < POSITION_SNAP_THRESHOLD) { if (element.offsetX !== undefined) { // For elements with offsetX, calculate the x position that will center the visual bounds const targetVisualLeft = centerX - visualBounds.width / 2; snapX = targetVisualLeft + element.offsetX; } else if (usesCenterPositioning(element.type)) { snapX = centerX; } else { snapX = centerX - width / 2; } showVertical = true; verticalLine = centerX; } // Check horizontal center snap using visual center if (Math.abs(visualBounds.centerY - centerY) < POSITION_SNAP_THRESHOLD) { if (usesCenterPositioning(element.type)) { snapY = centerY; } else { snapY = centerY - height / 2; } showHorizontal = true; horizontalLine = centerY; } return { x: snapX, y: snapY, guideLines: { vertical: verticalLine, horizontal: horizontalLine, showVertical, showHorizontal, }, }; };