/** * CanvasBackground Component * * Background image, video, and audio for the constructor canvas. * Handles blob URLs, Next.js Image optimization, and previous background overlay. * Supports custom video playback settings (autoplay, loop, muted, start/end time). */ import React from 'react'; import NextImage from 'next/image'; import { useBackgroundVideoPlayback } from '../../hooks/useBackgroundVideoPlayback'; import PreviousBackgroundOverlay from '../PreviousBackgroundOverlay'; interface CanvasBackgroundProps { backgroundImageUrl?: string; backgroundVideoUrl?: string; backgroundAudioUrl?: string; previousBgImageUrl?: string; previousBgVideoUrl?: string; isSwitching?: boolean; isNewBgReady?: boolean; isFadingIn?: boolean; onBackgroundReady?: () => void; // Video playback settings videoAutoplay?: boolean; videoLoop?: boolean; videoMuted?: boolean; videoStartTime?: number | null; videoEndTime?: number | null; } const CanvasBackground: React.FC = ({ backgroundImageUrl, backgroundVideoUrl, backgroundAudioUrl, previousBgImageUrl, previousBgVideoUrl, isSwitching = false, isNewBgReady = false, isFadingIn = false, onBackgroundReady, videoAutoplay = true, videoLoop = true, videoMuted = true, videoStartTime = null, videoEndTime = null, }) => { // Use background video playback hook for custom start/end time handling const { videoRef, shouldBlockAutoplay } = useBackgroundVideoPlayback({ videoUrl: backgroundVideoUrl, autoplay: videoAutoplay, loop: videoLoop, muted: videoMuted, startTime: videoStartTime, endTime: videoEndTime, }); // Block autoplay if video already played this session (when loop=false) const effectiveAutoplay = videoAutoplay && !shouldBlockAutoplay; const handleLoad = () => { onBackgroundReady?.(); }; const handleError = () => { onBackgroundReady?.(); }; // When endTime is set, we disable native loop and handle it via the hook const useNativeLoop = videoEndTime == null ? videoLoop : false; return ( <> {/* Background image - z-1 keeps it below backdrop blur layer (z-5) */} {backgroundImageUrl && (
{backgroundImageUrl.startsWith('blob:') ? ( // eslint-disable-next-line @next/next/no-img-element Background ) : ( )}
)} {/* Previous background overlays - show during loading AND crossfade. Uses CSS animation for fade-out effect during crossfade. z-0 keeps them BELOW new backgrounds (z-1). */} {/* Background video - z-1 keeps it below backdrop blur layer (z-5) */} {backgroundVideoUrl && (