Files
memefast/resources/js/modules/editor/partials/canvas/video-preview.jsx
2025-06-16 15:00:15 +08:00

116 lines
3.8 KiB
JavaScript

// Use minimal react-konva core to avoid Node.js dependencies
import 'konva/lib/Animation';
import 'konva/lib/shapes/Image';
import 'konva/lib/shapes/Text';
import { Image, Layer, Stage, Text } from 'react-konva/lib/ReactKonvaCore';
const VideoPreview = ({
// Dimensions
dimensions,
// Timeline state
currentTime,
totalDuration,
isPlaying,
status,
// Export state
isExporting,
exportProgress,
exportStatus,
// Data
timelineElements,
activeElements,
videoElements,
loadedVideos,
videoStates,
ffmpegCommand,
// Event handlers
handlePlay,
handlePause,
handleReset,
handleSeek,
copyFFmpegCommand,
exportVideo,
// Refs
layerRef,
}) => {
// Function to determine which image source to use for videos
const getImageSource = (element) => {
// Check if this video should be playing right now
const isVideoActive = videoStates[element.id] && isPlaying;
// Use video if it's ready and currently active, otherwise use poster
if (isVideoActive && element.videoElement && element.isVideoReady) {
return element.videoElement;
} else if (element.posterImage && element.isVideoPoster) {
return element.posterImage;
}
// Fallback - no image ready yet
return null;
};
return (
<div>
<Stage width={dimensions.width} height={dimensions.height} className="">
<Layer ref={layerRef}>
{activeElements.map((element) => {
if (element.type === 'video') {
const imageSource = getImageSource(element);
if (!imageSource) {
return null; // Don't render if no source is ready
}
return (
<Image
key={element.id}
image={imageSource}
x={element.x}
y={element.y}
width={element.width}
height={element.height}
draggable
/>
);
} else if (element.type === 'text') {
return (
<Text
key={element.id}
text={element.text}
x={element.x}
y={element.y}
fontSize={element.fontSize}
fill={element.fill}
stroke={element.stroke}
strokeWidth={element.strokeWidth}
draggable
/>
);
} else if (element.type === 'image' && element.imageElement && element.isImageReady) {
return (
<Image
key={element.id}
image={element.imageElement}
x={element.x}
y={element.y}
width={element.width}
height={element.height}
draggable
/>
);
}
return null;
})}
</Layer>
</Stage>
</div>
);
};
export default VideoPreview;