141 lines
4.4 KiB
JavaScript
141 lines
4.4 KiB
JavaScript
// 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,
|
|
},
|
|
};
|
|
};
|