지도를 서비스에 도입할 때의 가장 기본적인 기능 중 하나.
- 클릭된 마커의 이미지를 변경하며,
- 한번에 하나의 마커만 클릭될 수 있도록 한다.
해당 로직을 고민하고 구현했던 과정을 정리한다.
우선 결과물부터 보면,
위와 같이 클릭된 마커의 이미지와, 한번에 하나의 마커만 클릭되도록 하는 로직을 구현해본다.
우선 두 가지의 변수를 사용하였다.
- 마커가 클릭되어 있는지 확인하는 플래그
- 현재 클릭되어 있는 마커를 저장하는 변수
1번은 마커가 클릭되었을 때 이미지 변경만이 아닌 다른 로직들을 수행하기 위해 사용하였고, 2번은 해당 마커의 이미지를 조작하기 위해 사용되었다.
마커의 이미지만 변경하기 위해서라면 1번은 굳이 사용하지 않아도 된다.
이번 예제에서 사용한 카카오 맵 sdk는 마커 이미지를 카카오에서 정해놓은 마커 이미지 객체로 만들어야 한다. 따라서 아래와 같이 마커 이미지 객체를 생성하였다.
this.defaultMarker = new kakao.maps.MarkerImage(
iconUrl,
new kakao.maps.Size(25, 25),
{
alt: 'marker img',
}
);
카카오맵의 마커 객체는 위와 같이 이미지 주소, 사이즈, 그리고 그 밖의 optional 속성을 입력해 생성할 수 있다.
위와 같은 방법으로 defaultMarker(기본 이미지), clickedMarker(클릭되었을 때의 이미지)를 생성하였다.
마커를 생성하기 위해선, 아래와 같이 역시 해당 맵에서 요구하는 형식으로 객체화 해야 한다. 카카오 맵에서는 아래와 같이 구현하면 된다.
const marker = new kakao.maps.Marker({
map: this.map,
position: new kakao.maps.LatLng(place.lat, place.lng),
image: this.defaultMarker
});
카카오 맵 객체를 가리키는 this.map,
마커를 찍을 위치의 위,경도 값,
마커에 적용할 이미지
를 이용한다. 이때 적용할 이미지는 위에서 생성한 객체를 전달해야 한다.
이제 본격적으로 클릭 했을때의 로직을 구현해보자.
마커를 클릭할 때의 동작을 제어하기 위해선 마커에 클릭 리스너를 붙여주어야 한다.
맨 처음에 언급했던 기능을 구현하기 위해서는, 리스너를 설계할 때에 고려해야 할 점들이 몇 가지 있다.
- 클릭된 마커가 기존에 클릭되어 있는 마커인지 확인해야 한다.
- 1번이 맞다면, 아무것도 하지 않는다.
- 1번이 아니라면, 새로 선택된 마커를 클릭된 이미지로 변경한다.
- 3번을 할 때, 원래 선택된 마커는 기본 이미지로 변경해야 한다.
위와 같은 프로세스로 구현했을 때에, 초기 실행 시 3번에서 에러가 발생하였다.
그 이유는 맨 처음 클릭 시에는 기존에 선택된 마커 정보가 없으므로 해당 값을 참조하지 못해서였다.
위와 같은 과정을 고려하여 최종적으로 아래와 같이 코드를 작성하였다.
//마커 클릭 리스너
kakao.maps.event.addListener(marker, 'click', () => {
//클릭된 마커가 없는 경우 -> 초기이므로, selectedMarker 값을 설정해 줘야 한다.
if(!this.markerClicked) {
this.markerClicked = true;
this.selectedMarker = marker;
marker.setImage(this.clickedMarker);
}
//클릭된 마커가 현재 마커가 아닌 경우
if(this.selectedMarker !== marker) {
//새로 클릭된 마커는 이미지를 변경한다.
marker.setImage(this.clickedMarker);
//기존에 선택되어 있는 마커는 기본으로 바꾼다.
this.selectedMarker.setImage(this.defaultMarker);
}
//현재 클릭된 마커를 선택된 마커로 업데이트한다.
this.selectedMarker = marker;
});