import React, { useEffect, useState } from 'react'; import { TransitionEffect } from '../types'; interface SlideshowBackgroundProps { images: string[]; durationPerImage?: number; transitionDuration?: number; effect?: TransitionEffect; // 선택된 효과 } const EFFECTS_MAP: Record = { 'Mix': ['fade', 'blur-fade'], 'Zoom': ['zoom-in', 'zoom-out', 'ken-burns-extreme'], 'Slide': ['slide-left', 'slide-right', 'slide-up', 'slide-down'], 'Wipe': ['pixelate-sim', 'flash', 'glitch'] // Wipe 대신 화려한 효과들을 매핑 }; const ALL_EFFECTS = [ 'fade', 'slide-left', 'slide-right', 'slide-up', 'slide-down', 'zoom-in', 'zoom-out', 'zoom-spin', 'flip-x', 'flip-y', 'blur-fade', 'glitch', 'ken-burns-extreme', 'pixelate-sim', 'flash' ]; /** * 사용자 선택에 따른 전환 효과를 적용한 슬라이드쇼 컴포넌트 */ const SlideshowBackground: React.FC = ({ images, durationPerImage = 6000, transitionDuration = 1500, effect = 'Mix' // 기본값 Mix }) => { const [activeIndex, setActiveIndex] = useState(0); const [currentAnimName, setCurrentAnimName] = useState('fade'); // 효과 매핑 로직 const getNextEffect = () => { const candidates = EFFECTS_MAP[effect] || EFFECTS_MAP['Mix']; return candidates[Math.floor(Math.random() * candidates.length)]; }; useEffect(() => { if (images.length <= 1) return; // 초기 효과 설정 setCurrentAnimName(getNextEffect()); const interval = setInterval(() => { const nextIndex = (activeIndex + 1) % images.length; setCurrentAnimName(getNextEffect()); // 다음 효과 랜덤 선택 (카테고리 내에서) setActiveIndex(nextIndex); }, durationPerImage); return () => clearInterval(interval); }, [activeIndex, images.length, durationPerImage, effect]); if (!images || images.length === 0) return
; return (
{images.map((src, index) => { const isActive = index === activeIndex; const isPrev = index === (activeIndex - 1 + images.length) % images.length; let effectClass = ''; if (isActive) { effectClass = `animate-${currentAnimName}-in`; } else if (isPrev) { effectClass = `animate-fade-out`; } return (
{`Slide {/* 텍스트 가독성을 위한 오버레이 */}
); })}
); }; export default SlideshowBackground;