116 lines
3.8 KiB
JavaScript
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;
|