From 8351607ea80bebea652bca770ba26cd923d74ca3 Mon Sep 17 00:00:00 2001 From: Hyoeunkh Date: Fri, 17 May 2024 11:12:28 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=B6=80=EC=8A=A4=EB=B3=84=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=8A=AC=EB=9D=BC=EC=9D=B4=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/display/BoothInfo.styled.ts | 39 +++++++++++++- src/components/display/BoothInfo.tsx | 60 +++++++++++++++++++--- 2 files changed, 91 insertions(+), 8 deletions(-) diff --git a/src/components/display/BoothInfo.styled.ts b/src/components/display/BoothInfo.styled.ts index 0c2621d..d23c3f3 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..a114a00 100644 --- a/src/components/display/BoothInfo.tsx +++ b/src/components/display/BoothInfo.tsx @@ -1,23 +1,71 @@ import React 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"; +import { useState, useRef,useCallback, useEffect } from "react"; + //zustand 로 refactor 필요 const BoothInfo: React.FC = () => { const boothdetail = "멋쟁이사자처럼 주점에서는 노래방 마이크로 김대건이 노래를 하고 춤도 추고 히어로 서사에 대해 설명할 것입니다."; 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) => ( + + ))} + +