diff --git a/index.html b/index.html index 3bcad9c5..047495c9 100644 --- a/index.html +++ b/index.html @@ -8,6 +8,10 @@ integrity="sha384-6MFdIr0zOira1CHQkedUqJVql0YtcZA1P0nbPrQYJXVJZUkTk/oX4U9GhUIs3/z8" crossorigin="anonymous" > + Vite + React + TS diff --git a/src/assets/homeIcons/home/closeButton.svg b/src/assets/homeIcons/home/closeButton.svg new file mode 100644 index 00000000..b7149793 --- /dev/null +++ b/src/assets/homeIcons/home/closeButton.svg @@ -0,0 +1,12 @@ + + + \ No newline at end of file diff --git a/src/assets/homeIcons/home/fireIcon.svg b/src/assets/homeIcons/home/fireIcon.svg new file mode 100644 index 00000000..84f22046 --- /dev/null +++ b/src/assets/homeIcons/home/fireIcon.svg @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/src/assets/homeIcons/home/rank1.svg b/src/assets/homeIcons/home/rank1.svg new file mode 100644 index 00000000..4a222517 --- /dev/null +++ b/src/assets/homeIcons/home/rank1.svg @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file diff --git a/src/assets/homeIcons/home/rank2.svg b/src/assets/homeIcons/home/rank2.svg new file mode 100644 index 00000000..3c452abe --- /dev/null +++ b/src/assets/homeIcons/home/rank2.svg @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file diff --git a/src/components/Home/Onboarding/Icons.tsx b/src/assets/homeIcons/home/snowIcon.svg similarity index 61% rename from src/components/Home/Onboarding/Icons.tsx rename to src/assets/homeIcons/home/snowIcon.svg index c856a1ca..3857919c 100644 --- a/src/components/Home/Onboarding/Icons.tsx +++ b/src/assets/homeIcons/home/snowIcon.svg @@ -1,35 +1,4 @@ -const closeButton = ( - - - -); -const fireIcon = ( - - - -); -const snowIcon = ( - - -); -const rank1 = ( - - - - - -); -const rank2 = ( - - - - - -); - -export { closeButton, fireIcon, rank1, rank2, snowIcon }; + \ No newline at end of file diff --git a/src/assets/homeIcons/map/flag.svg b/src/assets/homeIcons/map/flag.svg new file mode 100644 index 00000000..cb62dc83 --- /dev/null +++ b/src/assets/homeIcons/map/flag.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/homeIcons/map/flag_big.svg b/src/assets/homeIcons/map/flag_big.svg new file mode 100644 index 00000000..8756063a --- /dev/null +++ b/src/assets/homeIcons/map/flag_big.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/homeIcons/map/house.svg b/src/assets/homeIcons/map/house.svg new file mode 100644 index 00000000..deaef1ec --- /dev/null +++ b/src/assets/homeIcons/map/house.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/assets/homeIcons/map/house_big.svg b/src/assets/homeIcons/map/house_big.svg new file mode 100644 index 00000000..e2bae998 --- /dev/null +++ b/src/assets/homeIcons/map/house_big.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/homeIcons/map/restaurant.svg b/src/assets/homeIcons/map/restaurant.svg new file mode 100644 index 00000000..9fe41efb --- /dev/null +++ b/src/assets/homeIcons/map/restaurant.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/homeIcons/map/restaurant_big.svg b/src/assets/homeIcons/map/restaurant_big.svg new file mode 100644 index 00000000..0a6e24fc --- /dev/null +++ b/src/assets/homeIcons/map/restaurant_big.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/Home/Onboarding/Onboarding.tsx b/src/components/Home/Onboarding/Onboarding.tsx index 2e3c9e49..2390c44f 100644 --- a/src/components/Home/Onboarding/Onboarding.tsx +++ b/src/components/Home/Onboarding/Onboarding.tsx @@ -3,7 +3,11 @@ import { useNavigate } from "react-router-dom"; import styles from "./Onboarding.module.scss"; -import { closeButton, fireIcon, rank1, rank2, snowIcon } from "./Icons"; +import CloseButton from "@/assets/homeIcons/home/closeButton.svg?react"; +import FireIcon from "@/assets/homeIcons/home/fireIcon.svg?react"; +import Rank1 from "@/assets/homeIcons/home/rank1.svg?react"; +import Rank2 from "@/assets/homeIcons/home/rank2.svg?react"; +import SnowIcon from "@/assets/homeIcons/home/snowIcon.svg?react"; interface PropsType { set: React.Dispatch>; @@ -16,15 +20,15 @@ function Onboarding({ set }: PropsType) { const data = [ { title: "뜨끈한 온천탕", - icon: fireIcon, + icon: , percent: "60%", - rank: rank1, + rank: , }, { title: "눈 내린 스키장", - icon: snowIcon, + icon: , percent: "40%", - rank: rank2, + rank: , }, ]; @@ -40,7 +44,7 @@ function Onboarding({ set }: PropsType) {
+
(); + const [map, setMap] = useState(null); + const [markers, setMarkers] = useState([]); + + function addPin(data: SearchItemType[]) { + const currentMarkers: any[] = []; + + data.map((data, i) => { + let image; + let imageSize; + let imageOption; + if (i === currentpin) { + image = + data.category === "숙소" + ? bigHomeMarker + : data.category === "맛집" + ? bigForkMarker + : bigFlagMarker; + imageSize = new window.kakao.maps.Size(44, 52); + imageOption = { offset: new window.kakao.maps.Point(0, 0) }; + } else { + image = + data.category === "숙소" + ? homeMarker + : data.category === "맛집" + ? forkMarker + : flagMarker; + imageSize = new window.kakao.maps.Size(32, 32); + imageOption = { offset: new window.kakao.maps.Point(-6, -10) }; + } + + const markerImage = new window.kakao.maps.MarkerImage( + image, + imageSize, + imageOption, + ); + const marker = new window.kakao.maps.Marker({ + position: new window.kakao.maps.LatLng( + data.location.latitude, + data.location.longtitude, + ), + image: markerImage, + }); + if (i == currentpin) { + marker.setZIndex(10); + } + marker.setMap(map); + currentMarkers.push(marker); + }); + setMarkers([...currentMarkers]); + } + function removePin(marker: any[]) { + marker.map((marker) => { + marker.setMap(null); + }); + return true; + } + + // 컴포넌트 마운트, 카테고리 전환 시 새로운 맵 생성 + useEffect(() => { + const container = document.getElementById("map"); + + // React.StrictMode로 인해 map이 두 번 중첩되어 겹치는 현상 방지 + if (container) { + while (container.firstChild) { + container.removeChild(container.firstChild); + } + } + + const options = { + center: new window.kakao.maps.LatLng(33.450701, 126.570667), + level: 3, + }; + setMap(new window.kakao.maps.Map(container, options)); + }, [data]); + + // 맵 생성 시 현재 데이터 좌표들의 바운드를 만들어 중심점 생성 + useEffect(() => { + if (map) { + const bounds = new window.kakao.maps.LatLngBounds(); + addPin(data); + data.map((data) => { + bounds.extend( + new window.kakao.maps.LatLng( + data.location.latitude, + data.location.longtitude, + ), + ); + }); + map.setBounds(bounds); + } + }, [map]); + + // 현재 화면에 보이는 아이템의 아이콘 변경 + useEffect(() => { + if (map) { + removePin(markers); + addPin(data); + } + }, [currentpin]); + return (
-

Map

- +
+
+ +
); } diff --git a/src/components/SearchFromHome/SearchList/Map/MapItems/MapItem/MapItem.tsx b/src/components/SearchFromHome/SearchList/Map/MapItems/MapItem/MapItem.tsx index d795d614..0b4bf3c6 100644 --- a/src/components/SearchFromHome/SearchList/Map/MapItems/MapItem/MapItem.tsx +++ b/src/components/SearchFromHome/SearchList/Map/MapItems/MapItem/MapItem.tsx @@ -18,7 +18,7 @@ function MapItem({ data, categoryChange }: PropsType) {

{data.title} - {data.category}·{data.location} + {data.category}·{data.location.address}

diff --git a/src/components/SearchFromHome/SearchList/Map/MapItems/MapItems.tsx b/src/components/SearchFromHome/SearchList/Map/MapItems/MapItems.tsx index 1ea4ec5a..f12d6136 100644 --- a/src/components/SearchFromHome/SearchList/Map/MapItems/MapItems.tsx +++ b/src/components/SearchFromHome/SearchList/Map/MapItems/MapItems.tsx @@ -13,11 +13,41 @@ import { SearchItemType } from "@/types/home"; interface PropsType { data: SearchItemType[]; categoryChange: boolean; + setCurrentPin: React.Dispatch>; } -function MapItems({ data, categoryChange }: PropsType) { +function MapItems({ data, categoryChange, setCurrentPin }: PropsType) { const [slideLocation, setSlideLocation] = useState(0); const [componentRef, size] = useComponentSize(); + const [throttle, setThrottle] = useState(false); + + function setCurrentIndex() { + const criterion = document.querySelector("#map_slide_container"); + const elements = document.querySelectorAll("#map_slide"); + const childrenArray = Array.from(elements[0].children); + + for (const item of childrenArray) { + const currentLeft = + criterion && + item.getBoundingClientRect().x - criterion.getBoundingClientRect().x; + if (currentLeft) { + if (0 < currentLeft && currentLeft < 196) { + const index = childrenArray.indexOf(item); + setCurrentPin(index); + } + } + } + } + + const handleScroll = () => { + if (throttle) return; + if (!throttle) { + setThrottle(true); + setTimeout(async () => { + setThrottle(false); + }, 300); + } + }; useEffect(() => { if (size.width < 449) { @@ -27,8 +57,20 @@ function MapItems({ data, categoryChange }: PropsType) { } }, [data, size, componentRef]); + useEffect(() => { + setTimeout(() => { + setCurrentIndex(); + }, 600); + }, [slideLocation]); + + useEffect(() => { + if (throttle) { + setCurrentIndex(); + } + }, [throttle]); + return ( -
+
{data && ( {data && data.map((data, i) => ( diff --git a/src/components/SearchFromHome/SearchList/MapButton/MapButton.tsx b/src/components/SearchFromHome/SearchList/MapButton/MapButton.tsx index 73539784..2760d1cf 100644 --- a/src/components/SearchFromHome/SearchList/MapButton/MapButton.tsx +++ b/src/components/SearchFromHome/SearchList/MapButton/MapButton.tsx @@ -4,12 +4,12 @@ import styles from "./MapButton.module.scss"; function MapButton() { return ( - +
); } diff --git a/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.tsx b/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.tsx index 7253a870..d54ddab0 100644 --- a/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.tsx +++ b/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.tsx @@ -20,7 +20,7 @@ function SearchItem({ data, categoryChange }: PropsType) {

{data.title} - {data.category}·{data.location} + {data.category}·{data.location.address}

diff --git a/src/components/SearchFromHome/SearchList/Tabs/Tab/Tab.tsx b/src/components/SearchFromHome/SearchList/Tabs/Tab/Tab.tsx index b17e8964..6791198b 100644 --- a/src/components/SearchFromHome/SearchList/Tabs/Tab/Tab.tsx +++ b/src/components/SearchFromHome/SearchList/Tabs/Tab/Tab.tsx @@ -17,7 +17,7 @@ function Tab({ setCategoryChange(true); setTimeout(() => { setCategoryChange(false); - }, 200); + }, 150); setCategory(key); } diff --git a/src/components/SlideButton/SlideButton.tsx b/src/components/SlideButton/SlideButton.tsx index 0f9ec289..0caee92d 100644 --- a/src/components/SlideButton/SlideButton.tsx +++ b/src/components/SlideButton/SlideButton.tsx @@ -1,5 +1,3 @@ -import { useEffect } from "react"; - import styles from "./SlideButton.module.scss"; import LeftButton from "./LeftButton/LeftButton"; @@ -16,9 +14,6 @@ function SlideButton({ flexGap, buttonSize, }: SlideButtonPropsType) { - useEffect(() => { - console.log(slideSize); - }, [slideSize]); return (