diff --git a/src/components/display/BoothInfo.styled.ts b/src/components/display/BoothInfo.styled.ts index 0c2621d..fae8d87 100644 --- a/src/components/display/BoothInfo.styled.ts +++ b/src/components/display/BoothInfo.styled.ts @@ -1,18 +1,53 @@ import styled from "styled-components"; +export const ImgContainer = styled.div` + margin: 0 auto; +`; + export const ImgWrapper = styled.div` overflow: hidden; width: 90%; + margin: 0 auto; aspect-ratio: 1 / 1; border-radius: 20px; - margin-bottom: 30px; + margin-bottom: 10px; + + display: flex; + flex-direction: row; + overflow-x: auto; + scroll-behavior: smooth; + scroll-snap-type: x mandatory; + scrollbar-width: none; + -ms-overflow-style: none; + &::-webkit-scrollbar { + display: none; + } `; export const BoothImg = styled.img` width: 100%; - height: 100%; + scroll-snap-align: center; + flex-shrink: 0; object-fit: cover; object-position: 50% 50%; + border-radius: 20px; +`; + +export const DotWrapper = styled.div` + display: flex; + justify-content: center; + gap: 10px; + margin-bottom: 30px; +`; + +export const Dot = styled.div<{ active: boolean }>` + width: 8px; + height: 8px; + border-radius: 50%; + background-color: ${({ active }) => (active ? "#3F3A6C" : "#dddddd")}; + display: inline-block; + transition: background-color 0.3s ease; + cursor: pointer; `; export const InfoWrapper = styled.div` diff --git a/src/components/display/BoothInfo.tsx b/src/components/display/BoothInfo.tsx index ad83c27..d6dd39c 100644 --- a/src/components/display/BoothInfo.tsx +++ b/src/components/display/BoothInfo.tsx @@ -1,9 +1,20 @@ import React from "react"; +import { useState, useRef, useCallback, useEffect } from "react"; -import mainPageImage from "@/assets/main_page.jpg"; +import jannaviImage from "@/assets/jannavi.jpg"; +import norazoImage from "@/assets/norazo.jpg"; import { Text } from "../typography/Text"; -import { BoothDetail, BoothImg, BoothName, ImgWrapper, InfoWrapper } from "./BoothInfo.styled"; +import { + BoothDetail, + BoothImg, + BoothName, + ImgWrapper, + ImgContainer, + InfoWrapper, + DotWrapper, + Dot, +} from "./BoothInfo.styled"; import { Heart } from "./Heart"; //zustand 로 refactor 필요 @@ -12,12 +23,57 @@ const BoothInfo: React.FC = () => { "멋쟁이사자처럼 주점에서는 노래방 마이크로 김대건이 노래를 하고 춤도 추고 히어로 서사에 대해 설명할 것입니다."; const boothName = "멋쟁이 사자처럼 주점"; const num = 365; + const boothImg = [jannaviImage, norazoImage, jannaviImage]; + + const [currentIndex, setCurrentIndex] = useState(0); + const slideRefs = useRef<(HTMLDivElement | null)[]>([]); + + const updateCurrentIndex = useCallback((entries: IntersectionObserverEntry[]) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + const index = slideRefs.current.indexOf(entry.target as HTMLDivElement); + if (index !== -1) { + setCurrentIndex(index); + } + } + }); + }, []); + + useEffect(() => { + const observer = new IntersectionObserver(updateCurrentIndex, { + root: null, + threshold: 0.5, + }); + + slideRefs.current.forEach((slide) => { + if (slide) { + observer.observe(slide); + } + }); + + return () => { + slideRefs.current.forEach((slide) => { + if (slide) { + observer.unobserve(slide); + } + }); + }; + }, [updateCurrentIndex]); return ( <> - - - + + + {boothImg.map((src, index) => { + return (slideRefs.current[index] = el)} />; + })} + + + {boothImg.map((_, index) => ( + + ))} + + diff --git a/src/pages/BoothDetailPage.styled.tsx b/src/pages/BoothDetailPage.styled.tsx index 2b7a13f..e068c81 100644 --- a/src/pages/BoothDetailPage.styled.tsx +++ b/src/pages/BoothDetailPage.styled.tsx @@ -13,7 +13,7 @@ export const DetailPageWrapper = styled.div` `; export const BottomBox = styled.div` height: 70px; - width: 90%; + width: min(100%, 700px); position: fixed; display: flex; bottom: 0; @@ -23,7 +23,7 @@ export const BottomBox = styled.div` `; export const ContentContainer = styled.form` height: 46px; - width: 100%; + width: 90%; display: flex; flex-direction: row; justify-content: space-between; @@ -31,6 +31,7 @@ export const ContentContainer = styled.form` align-items: center; border: 1px solid #3f3a6c; border-radius: 30px; + position: relative; textarea { color: #5d5a88;