Skip to content

Commit

Permalink
Feat: 맵마커 클릭 시 변경
Browse files Browse the repository at this point in the history
  • Loading branch information
suehub committed Jan 20, 2024
1 parent 788c9e1 commit bdaab02
Showing 1 changed file with 89 additions and 50 deletions.
139 changes: 89 additions & 50 deletions src/components/Plan/TripMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ const TripMap = ({ paths }: { paths: Paths[] }) => {
const latitude = firstPath?.fromLatitude;
const longitude = firstPath?.fromLongitude;

// Kakao Maps SDK 로드 상태
const mapRef = useRef<kakao.maps.Map | null>(null);
const [selectedMarker, setSelectedMarker] = useState<number | null>(null);

const defaultPosition = { lat: Number(latitude), lng: Number(longitude) };

const [_] = useKakaoLoader({
appkey: VITE_KAKAO_MAP_API_KEY,
});

const defaultPosition = { lat: Number(latitude), lng: Number(longitude) };

const getCenterPosition = () => {
if (paths.length === 0) {
return defaultPosition;
Expand Down Expand Up @@ -59,8 +61,6 @@ const TripMap = ({ paths }: { paths: Paths[] }) => {
});
}

const mapRef = useRef<kakao.maps.Map | null>(null);

// 지도 범위 재설정 함수
const setBounds = () => {
if (mapRef.current) {
Expand All @@ -87,46 +87,97 @@ const TripMap = ({ paths }: { paths: Paths[] }) => {
setBounds();
}, [paths]);

// 선택된 마커의 인덱스를 추적하기 위한 상태
const [selectedMarker, setSelectedMarker] = useState<number | null>(null);

// 마커를 클릭할 때 호출되는 함수
const handleMarkerClick = (index: number) => {
setSelectedMarker(index);
};

// SVG 문자열을 Data URI로 변환하는 함수
const getSequenceIconUrl = (number: number) => {
let svgString;
let width, height;

if (selectedMarker === number + 1) {
return `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(
SequenceMarker(number),
)}`;
width = 32;
height = 39;
svgString = encodeURIComponent(`<svg
xmlns="http://www.w3.org/2000/svg"
width="41"
height="49"
viewBox="0 0 41 49"
fill="none">
<g filter="url(#filter0_d_2972_16425)">
<path
d="M20.2773 40.1372C28.2773 32.2684 36.2773 25.2224 36.2773 16.5307C36.2773 7.83898 29.1139 0.792969 20.2773 0.792969C11.4408 0.792969 4.27734 7.83898 4.27734 16.5307C4.27734 25.2224 12.2773 32.2684 20.2773 40.1372Z"
fill="${getColor(number)}"
/>
<path
d="M32.5203 16.6923C32.5203 23.4539 27.0389 28.9353 20.2772 28.9353C13.5156 28.9353 8.03418 23.4539 8.03418 16.6923C8.03418 9.93062 13.5156 4.44922 20.2772 4.44922C27.0389 4.44922 32.5203 9.93062 32.5203 16.6923Z"
fill="white"
/>
<text
x="17px"
y="23px"
dominantBaseline="middle"
textAnchor="middle"
fontSize="15"
fill="${getColor(number)}"
font-weight="900">
${number}
</text>
</g>
<defs>
<filter
id="filter0_d_2972_16425"
x="0.277344"
y="0.792969"
width="40"
height="47.3438"
filterUnits="userSpaceOnUse"
colorInterpolationFilters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feColorMatrix
in="SourceAlpha"
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
result="hardAlpha"
/>
<feOffset dy="4" />
<feGaussianBlur stdDeviation="2" />
<feComposite in2="hardAlpha" operator="out" />
<feColorMatrix
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
/>
<feBlend
mode="normal"
in2="BackgroundImageFix"
result="effect1_dropShadow_2972_16425"
/>
<feBlend
mode="normal"
in="SourceGraphic"
in2="effect1_dropShadow_2972_16425"
result="shape"
/>
</filter>
</defs>
</svg>`);
} else {
width = 24;
height = 24;
svgString = encodeURIComponent(`
<svg width="24" height="24" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="10.5" cy="10.5" r="10" fill="${getColor(number)}" />
<text x="10.5" y="15" text-anchor="middle" fill="white" font-size="12" font-weight="bold">${number}</text>
</svg>
`);
}
const svgString = encodeURIComponent(`
<svg width="24" height="24" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="10.5" cy="10.5" r="10" fill="${getColor(number)}" />
<text x="10.5" y="15" text-anchor="middle" fill="white" font-size="12" font-weight="bold">${number}</text>
</svg>
`);
return `data:image/svg+xml;charset=UTF-8,${svgString}`;
};

const SequenceMarker = (number: number) => {
const fillColor = getColor(number);

return `
<svg xmlns="http://www.w3.org/2000/svg" width="41" height="49" viewBox="0 0 41 49" fill="none">
<g filter="url(#filter0_d_2972_16425)">
<path d="M20.2773 40.1372C28.2773 32.2684 36.2773 25.2224 36.2773 16.5307C36.2773 7.83898 29.1139 0.792969 20.2773 0.792969C11.4408 0.792969 4.27734 7.83898 4.27734 16.5307C4.27734 25.2224 12.2773 32.2684 20.2773 40.1372Z" fill="${fillColor}"/>
<path d="M32.5203 16.6923C32.5203 23.4539 27.0389 28.9353 20.2772 28.9353C13.5156 28.9353 8.03418 23.4539 8.03418 16.6923C8.03418 9.93062 13.5156 4.44922 20.2772 4.44922C27.0389 4.44922 32.5203 9.93062 32.5203 16.6923Z" fill="${fillColor}"/>
<text x="50%" y="50%" dominantBaseline="middle" textAnchor="middle" fontSize="12" fill="white" fontweight="bold">${number}</text>
</g>
<defs>
<filter id="filter0_d_2972_16425" x="0.277344" y="0.792969" width="40" height="47.3438" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
</filter>
</defs>
</svg>
`;
return {
src: `data:image/svg+xml;charset=UTF-8,${svgString}`,
size: { width, height },
};
};

return (
Expand All @@ -146,13 +197,7 @@ const TripMap = ({ paths }: { paths: Paths[] }) => {
lng: Number(path.fromLongitude),
}}
onClick={() => handleMarkerClick(path.toSeqNum)}
image={{
src: getSequenceIconUrl(path.toSeqNum - 1),
size: {
width: 24,
height: 24,
},
}}
image={getSequenceIconUrl(path.toSeqNum - 1)}
/>
{/* 마지막 항목인 경우, 목적지 위치에 마커 추가 */}
{index === paths.length - 1 && (
Expand All @@ -161,14 +206,8 @@ const TripMap = ({ paths }: { paths: Paths[] }) => {
lat: Number(path.toLatitude),
lng: Number(path.toLongitude),
}}
onClick={() => handleMarkerClick(path.toSeqNum + 1)} // 마지막 seqNum을 위한 +1
image={{
src: getSequenceIconUrl(path.toSeqNum),
size: {
width: 24,
height: 24,
},
}}
onClick={() => handleMarkerClick(path.toSeqNum + 1)}
image={getSequenceIconUrl(path.toSeqNum)}
/>
)}
<Polyline
Expand Down

0 comments on commit bdaab02

Please sign in to comment.