Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: 맵마커 클릭 시 변경 #209

Merged
merged 1 commit into from
Jan 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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