This commit is contained in:
ct
2025-06-28 12:54:30 +08:00
parent f8dc4c01f2
commit fe1066583a
13 changed files with 781 additions and 175 deletions

View File

@@ -2,14 +2,17 @@ import { Button } from '@/components/ui/button';
import { useMitt } from '@/plugins/MittContext';
import useVideoEditorStore from '@/stores/VideoEditorStore';
import { Type } from 'lucide-react';
import { useEffect, useRef } from 'react';
import { useEffect, useRef, useState } from 'react';
import { Group, Image, Layer, Line, Stage, Text, Transformer } from 'react-konva';
import { Html } from 'react-konva-utils';
// Import our custom hooks and utilities
import { useElementSelection } from './video-preview/video-preview-element-selection';
import { useElementTransform } from './video-preview/video-preview-element-transform';
import { getImageSource, getTextFontStyle } from './video-preview/video-preview-utils';
import { getImageSource } from './video-preview/video-preview-utils';
// Import centralized font management
import { getFontStyle, loadTimelineFonts, WATERMARK_CONFIG } from '@/modules/editor/fonts';
const VideoPreview = ({
watermarked,
@@ -56,6 +59,51 @@ const VideoPreview = ({
const stageRef = useRef(null);
const elementRefs = useRef({});
// Font loading state
const [fontsLoaded, setFontsLoaded] = useState(false);
const [fontLoadingAttempted, setFontLoadingAttempted] = useState(false);
// Load fonts when timeline elements change
useEffect(() => {
const loadFonts = async () => {
if (timelineElements.length > 0 && !fontLoadingAttempted) {
setFontLoadingAttempted(true);
try {
await loadTimelineFonts(timelineElements);
setFontsLoaded(true);
console.log('✅ Fonts loaded in preview');
// Force redraw after fonts load to recalculate text dimensions
setTimeout(() => {
if (layerRef.current) {
layerRef.current.batchDraw();
}
}, 100);
} catch (error) {
console.warn('⚠️ Font loading failed:', error);
setFontsLoaded(true); // Continue anyway with fallback fonts
}
}
};
loadFonts();
}, [timelineElements, fontLoadingAttempted]);
// Force text remeasurement when fonts load
useEffect(() => {
if (fontsLoaded && layerRef.current) {
// Find all text nodes and force them to recalculate
const textNodes = layerRef.current.find('Text');
textNodes.forEach((textNode) => {
// Force Konva to recalculate text dimensions
textNode._setTextData();
textNode.cache();
textNode.clearCache();
});
layerRef.current.batchDraw();
}
}, [fontsLoaded]);
// Use our custom hooks
const {
selectedElementId,
@@ -140,19 +188,44 @@ const VideoPreview = ({
);
} else if (element.type === 'text') {
return (
<Group key={element.id}>
<Group key={`${element.id}-${fontsLoaded}`}>
<Text
ref={(node) => {
if (node) {
elementRefs.current[element.id] = node;
// Force text measurement after font loading
if (fontsLoaded) {
setTimeout(() => {
node._setTextData();
// Debug log preview text properties
console.log(`🔍 Preview Text ${element.id} Properties:`);
console.log(' text:', element.text);
console.log(' x:', element.x);
console.log(' y:', element.y);
console.log(' fontSize:', element.fontSize);
console.log(' fontFamily:', element.fontFamily);
console.log(' width (fixedWidth):', element.fixedWidth);
console.log(' offsetX:', element.offsetX);
console.log(' node.width():', node.width());
console.log(' node.height():', node.height());
console.log(' node.textWidth:', node.textWidth);
console.log(' node.textHeight:', node.textHeight);
if (layerRef.current) {
layerRef.current.batchDraw();
}
}, 0);
}
}
}}
text={element.text}
x={element.x}
y={element.y}
fontSize={element.fontSize}
fontStyle={getTextFontStyle(element)}
fontFamily={element.fontFamily || 'Arial'}
fontStyle={getFontStyle(element)} // Use centralized function
fontFamily={element.fontFamily || 'Montserrat'}
fill={element.fill || '#ffffff'}
stroke={element.strokeWidth > 0 ? element.stroke || '#000000' : undefined}
strokeWidth={element.strokeWidth * 3 || 0}
@@ -246,15 +319,16 @@ const VideoPreview = ({
{/* Watermark - only show when watermarked is true */}
{watermarked && (
<Text
key={`watermark-${fontsLoaded}`}
text="MEMEAIGEN.COM"
x={dimensions.width / 2}
y={dimensions.height / 2 + dimensions.height * 0.2}
fontSize={20}
fontFamily="Bungee"
fill="white"
stroke="black"
strokeWidth={2}
opacity={0.5}
fontSize={WATERMARK_CONFIG.fontSize}
fontFamily={WATERMARK_CONFIG.fontFamily}
fill={WATERMARK_CONFIG.fill}
stroke={WATERMARK_CONFIG.stroke}
strokeWidth={WATERMARK_CONFIG.strokeWidth}
opacity={WATERMARK_CONFIG.opacity}
align="center"
verticalAlign="middle"
offsetX={90} // Approximate half-width to center the text