[251119] feat: FloatingGradientLayer..Experimental..3
🕐 커밋 시간: 2025. 11. 19. 19:56:11 📊 변경 통계: • 총 파일: 2개 • 추가: +95줄 • 삭제: -27줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx ~ com.twin.app.shoptime/src/views/DetailPanel/components/DetailPanelBackground/DetailPanelBackground.jsx 🔧 주요 변경 내용: • UI 컴포넌트 아키텍처 개선 • 소규모 기능 개선
This commit is contained in:
@@ -148,24 +148,16 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
};
|
||||
}, [dispatch]);
|
||||
|
||||
// ✅ DOM 렌더링 후 그라데이션 배경 숨기기 - HomePanel→DetailPanel 전환 완료 시
|
||||
useEffect(() => {
|
||||
// DOM이 렌더링된 후 약간의 지연 시간을 두고 그라데이션 숨김
|
||||
const timer = setTimeout(() => {
|
||||
// ✅ DetailPanelBackground 이미지 완전 렌더링 후 그라데이션 배경 숨기기
|
||||
const handleBackgroundImageReady = useCallback(() => {
|
||||
console.log('[TRACE-GRADIENT] ✅ DetailPanel - BackgroundImage fully rendered, hiding gradient');
|
||||
dispatch(updateHomeInfo({
|
||||
name: panel_names.HOME_PANEL,
|
||||
panelInfo: {
|
||||
showGradientBackground: false,
|
||||
}
|
||||
}));
|
||||
console.log('[TRACE-GRADIENT] 🔴 DetailPanel mounted 100ms timeout set showGradientBackground: false');
|
||||
}, 100); // 100ms 지연으로 DOM 렌더링 완료 후 실행
|
||||
|
||||
return () => {
|
||||
clearTimeout(timer); // 컴포넌트 언마운트 시 타이머 정리
|
||||
console.log('[TRACE-GRADIENT] 🔴 DetailPanel unmount - gradient timer cleared');
|
||||
};
|
||||
}, [dispatch]); // dispatch 포함
|
||||
}, [dispatch]);
|
||||
|
||||
// ✅ [251118] DetailPanel이 사라질 때 HomePanel 활성화
|
||||
useEffect(() => {
|
||||
@@ -806,7 +798,11 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
return (
|
||||
<div ref={containerRef}>
|
||||
|
||||
<DetailPanelBackground launchedFromPlayer={panelLaunchedFromPlayer} patnrId={panelPatnrId}/>
|
||||
<DetailPanelBackground
|
||||
launchedFromPlayer={panelLaunchedFromPlayer}
|
||||
patnrId={panelPatnrId}
|
||||
onImageReady={handleBackgroundImageReady}
|
||||
/>
|
||||
|
||||
<TPanel
|
||||
isTabActivated={false}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
// src/views/DetailPanel/components/DetailPanelBackground/DetailPanelBackground.jsx
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
@@ -25,9 +27,11 @@ import css from './DetailPanelBackground.module.less';
|
||||
* - true: PlayerPanel의 MEDIA 재생 완료 후 진입 (updatePanel로 전달됨)
|
||||
* - false/undefined: 다른 패널(Shop Now, You May Like 등)에서 진입
|
||||
* - 이 값에 따라 배경 UI를 다르게 표시할 수 있음
|
||||
* @param {Function} onImageReady - 이미지가 DOM에 완전히 렌더링되었을 때 호출되는 콜백
|
||||
*/
|
||||
export default function DetailPanelBackground({ launchedFromPlayer = false, patnrId }) {
|
||||
export default function DetailPanelBackground({ launchedFromPlayer = false, patnrId, onImageReady }) {
|
||||
const [imageReady, setImageReady] = useState(false);
|
||||
const imgRef = useRef(null);
|
||||
|
||||
const BG_MAP = {
|
||||
1: qvc,
|
||||
@@ -43,10 +47,44 @@ export default function DetailPanelBackground({ launchedFromPlayer = false, patn
|
||||
return BG_MAP[patnrId] || qvc;
|
||||
}, [patnrId]);
|
||||
|
||||
// ✅ [251119] 프리로드된 이미지 사용 로직 수정
|
||||
// launchedFromPlayer와 상관없이 항상 배경 이미지를 표시하도록 수정
|
||||
// ✅ 이미지가 DOM에 완전히 렌더링되었는지 확인하는 함수
|
||||
const checkImageFullyLoaded = useCallback(() => {
|
||||
const img = imgRef.current;
|
||||
if (!img) return false;
|
||||
|
||||
// 이미지 로드 완료 및 실제 크기가 파싱됨
|
||||
const isLoaded = img.complete && img.naturalWidth > 0;
|
||||
// 렌더링된 DOM에 크기가 설정됨
|
||||
const isRendered = img.offsetHeight > 0 && img.offsetWidth > 0;
|
||||
|
||||
const isDOMReady = isLoaded && isRendered;
|
||||
|
||||
if (isDOMReady) {
|
||||
console.log('[DetailPanelBackground] ✅ 이미지 DOM 완전 렌더링 완료:', {
|
||||
imgSrc: detailPanelBg,
|
||||
complete: img.complete,
|
||||
naturalWidth: img.naturalWidth,
|
||||
naturalHeight: img.naturalHeight,
|
||||
offsetHeight: img.offsetHeight,
|
||||
offsetWidth: img.offsetWidth,
|
||||
});
|
||||
}
|
||||
|
||||
return isDOMReady;
|
||||
}, [detailPanelBg]);
|
||||
|
||||
// 🔧 [251119] PlayerPanel에서 올라온 DetailPanel은 배경 이미지를 표시하지 않음
|
||||
// launchedFromPlayer가 false일 때만 배경 이미지를 로드하고 표시
|
||||
useEffect(() => {
|
||||
// 이미지가 프리로드되었는지 확인
|
||||
// launchedFromPlayer가 true이면 배경 이미지를 로드하지 않음 (PlayerPanel 비디오 보이도록)
|
||||
if (launchedFromPlayer) {
|
||||
console.log('[DetailPanelBackground] Skip background image loading - launchedFromPlayer=true (showing PlayerPanel video)');
|
||||
setImageReady(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// launchedFromPlayer가 false일 때만 배경 이미지 로드
|
||||
console.log('[DetailPanelBackground] Loading background image - launchedFromPlayer=false');
|
||||
if (ImagePreloader.isLoaded(detailPanelBg)) {
|
||||
console.log('[DetailPanelBackground] Using preloaded image:', detailPanelBg);
|
||||
setImageReady(true);
|
||||
@@ -64,7 +102,40 @@ export default function DetailPanelBackground({ launchedFromPlayer = false, patn
|
||||
setImageReady(true);
|
||||
});
|
||||
}
|
||||
}, [detailPanelBg]); // launchedFromPlayer 제거
|
||||
}, [detailPanelBg, launchedFromPlayer]); // launchedFromPlayer 추가
|
||||
|
||||
// ✅ 이미지가 DOM에 완전히 렌더링되면 부모에 콜백 호출
|
||||
useEffect(() => {
|
||||
if (!imageReady || !imgRef.current) return;
|
||||
|
||||
// 이미 렌더링된 경우 (캐시된 이미지)
|
||||
if (checkImageFullyLoaded()) {
|
||||
if (onImageReady) {
|
||||
onImageReady();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 아직 렌더링 중인 경우: onLoad 대기
|
||||
const img = imgRef.current;
|
||||
const handleLoad = () => {
|
||||
if (checkImageFullyLoaded()) {
|
||||
if (onImageReady) {
|
||||
onImageReady();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// img 요소가 ready 상태라면 즉시 실행
|
||||
if (img.complete) {
|
||||
handleLoad();
|
||||
} else {
|
||||
img.addEventListener('load', handleLoad);
|
||||
return () => {
|
||||
img.removeEventListener('load', handleLoad);
|
||||
};
|
||||
}
|
||||
}, [imageReady, onImageReady, checkImageFullyLoaded]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log('[DetailPanelBackground] 배경 이미지 경로:', detailPanelBg);
|
||||
@@ -84,9 +155,10 @@ export default function DetailPanelBackground({ launchedFromPlayer = false, patn
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 실제 배경 이미지 - 항상 표시되도록 수정 */}
|
||||
{imageReady && (
|
||||
{/* 실제 배경 이미지 - launchedFromPlayer가 false일 때만 표시 */}
|
||||
{imageReady && !launchedFromPlayer && (
|
||||
<img
|
||||
ref={imgRef}
|
||||
src={detailPanelBg}
|
||||
alt=""
|
||||
className={css.backgroundImage}
|
||||
|
||||
Reference in New Issue
Block a user