- [React.js] 네이버 지도 API 마커 중앙 정렬과 레이어 제어2025년 05월 14일 19시 55분 18초에 업로드 된 글입니다.작성자: DandyNow728x90반응형
네이버 지도 API 마커 중앙 정렬과 레이어 제어
웹 인터페이스를 개발할 때 요소들을 정확한 위치에 배치하고, 사용자와의 인터랙션에 따라 요소들의 표시 순서를 바꾸는 것은 중요한 사용자 경험 요소이다. 이번 글에서는 CSS를 사용한 절대 위치 요소의 정밀한 중앙 정렬 기법과, React 컴포넌트 상태에 따라 네이버 지도 마커의 표시 레이어(z-index)를 동적으로 변경하는 방법에 대해 이야기해보겠다.
1. 절대 위치 요소의 정확한 중앙 정렬 기법
CSS에서
position: absolute
와left: 50%
또는right: 50%
를 함께 사용하여 요소를 가로 중앙에 배치하려 할 때, 요소가 화면 중앙에서 미묘하게 왼쪽이나 오른쪽으로 치우치는 경험을 할 수 있다. 이는left: 50%
가 요소의 왼쪽 가장자리를 부모 컨테이너의 가로 중앙에 맞추기 때문에 발생한다. 요소 자체의 너비를 고려하여 정확한 중앙에 배치하려면transform
속성을 추가해야 한다.left: 50%
와transform: translateX(-50%)
활용: 요소를 절대 위치로 설정하고left: 50%
를 지정하여 왼쪽 가장자리를 부모의 중앙에 맞춘다. 그 후transform: translateX(-50%)
속성을 추가하여 요소 너비의 절반만큼 요소를 왼쪽으로 이동시킨다. 이 과정을 통해 요소의 가로 중앙이 부모의 가로 중앙과 일치하게 된다. 만약right: 50%
를 사용한다면transform: translateX(50%)
를 사용하여 오른쪽으로 이동시켜야 한다.
예제 코드 (CSS):
/* 부모 요소 (기준점 설정) */ .parent-container { position: relative; /* 자식 절대 위치 요소의 기준점이 된다. */ width: 300px; /* 예시 너비 */ height: 200px; /* 예시 높이 */ border: 1px solid blue; /* 시각화를 위한 보더 */ } /* 중앙에 위치시킬 절대 위치 요소 */ .centered-element { position: absolute; top: 50px; /* 상단에서부터의 거리 (예시) */ left: 50%; /* 부모 너비의 중앙에 왼쪽 가장자리를 맞춘다. */ transform: translateX(-50%); /* 요소 너비의 절반만큼 왼쪽으로 이동하여 중앙 정렬 */ width: 100px; /* 예시 너비 */ height: 50px; /* 예시 높이 */ background-color: yellow; /* 배경색 */ text-align: center; line-height: 50px; }
이 기법은 툴팁의 화살표나 모달 중앙 배치 등 다양한 상황에서 절대 위치 요소를 정밀하게 중앙 정렬하는 데 유용하게 사용된다.
2. React와 네이버 지도 API 활용: 마커 레이어(z-index) 동적 제어
지도 위에서 여러 마커를 표시할 때, 특정 마커에 마우스를 올리거나 선택했을 때 해당 마커가 다른 마커들보다 항상 위에 보이도록 표시 순서(레이어)를 조정해야 하는 경우가 있다.
react-naver-maps
라이브러리의<Marker>
컴포넌트가 제공하는zIndex
prop과 React의 상태 관리를 통해 이를 구현할 수 있다.- 상태를 이용한 마커 식별: 부모 컴포넌트에서
useState
훅을 사용하여 현재 마우스 오버되거나 선택된 마커의 고유 식별자(ID)를 상태로 관리한다. - Props를 통해 마커 컴포넌트로 상태 전달: 마커 목록을 렌더링할 때, 각 마커 컴포넌트에게 해당 마커가 현재 활성화된(마우스 오버된) 상태인지 여부를 boolean 타입의 props(예:
isHovered
)로 전달한다. Marker
컴포넌트의zIndex
prop 활용: 마커 컴포넌트 내부에서는 전달받은isHovered
props 값을 확인하여, 활성화 상태일 경우 다른 마커들보다 높은zIndex
값을<Marker>
컴포넌트의zIndex
prop에 할당한다.
예제 코드 (React with react-naver-maps):
// Parent Component (MapComponent.js) import React, { useState } from 'react'; import { NaverMap, Marker } from 'react-naver-maps'; // 라이브러리 임포트 (예시) import CustomMarker from './CustomMarker'; // 커스텀 마커 컴포넌트 임포트 const initialMarkerData = [ { id: 'marker_a', lat: 35.134, lng: 129.058 }, // 부산 지역 예시 좌표 { id: 'marker_b', lat: 35.137, lng: 129.062 }, { id: 'marker_c', lat: 35.139, lng: 129.055 }, ]; function MapComponent() { const [hoveredMarkerId, setHoveredMarkerId] = useState(null); // 마우스 오버된 마커 ID 상태 관리 return ( <NaverMap mapDivId={'react-naver-map'} // 지도 컨테이너 div ID style={{ width: '100%', height: '500px' }} // 지도 스타일 defaultCenter={{ lat: 35.137, lng: 129.058 }} // 기본 중심 좌표 defaultZoom={13} // 기본 확대 레벨 > {initialMarkerData.map(marker => ( <CustomMarker key={marker.id} markerData={marker} onMouseEnter={() => setHoveredMarkerId(marker.id)} // 마우스 진입 시 ID 저장 onMouseLeave={() => setHoveredMarkerId(null)} // 마우스 이탈 시 ID 초기화 isHovered={marker.id === hoveredMarkerId} // 현재 마커가 호버 상태인지 전달 /> ))} </NaverMap> ); } // CustomMarker Component (CustomMarker.js) import React from 'react'; import { Marker } from 'react-naver-maps'; // react-naver-maps의 Marker 임포트 function CustomMarker({ markerData, onMouseEnter, onMouseLeave, isHovered }) { // 호버 상태에 따라 zIndex 값 결정 const markerZIndex = isHovered ? 1000 : 100; // 호버 시 높게 (예: 1000), 기본 값 (예: 100) return ( <Marker position={{ lat: markerData.lat, lng: markerData.lng }} onMouseover={onMouseEnter} // 네이버 맵스 이벤트 핸들러 (소문자 주의) onMouseout={onMouseLeave} zIndex={markerZIndex} // 계산된 zIndex 값을 Marker props에 적용 // 마커의 모양과 내용을 정의하는 icon prop 등은 여기에 추가한다. icon={{ // 예시 아이콘 설정 content: `<div style="padding: 5px; background: ${isHovered ? '#fff' : '#eee'}; border: 1px solid gray; border-radius: 5px; font-size: small;">${markerData.id}</div>`, size: { width: markerData.id.length * 8 + 20, height: 30 }, // 텍스트 길이에 따른 크기 조절 anchor: { x: (markerData.id.length * 8 + 20) / 2, y: 30 } // 중앙 하단 앵커 }} /> ); } export default MapComponent;
위 예제 코드는
<NaverMap>
컴포넌트 내에서initialMarkerData
배열을 순회하며<CustomMarker>
컴포넌트를 렌더링한다.MapComponent
는hoveredMarkerId
상태를 통해 어떤 마커가 현재 마우스 오버되었는지 추적하고, 이 정보를isHovered
props를 통해 각CustomMarker
에게 전달한다.CustomMarker
내부에서는isHovered
값에 따라<Marker>
컴포넌트의zIndex
prop을 다르게 설정하여 마커의 표시 레이어를 제어하게 된다.zIndex
값은 다른 요소들의 레이어 순서를 고려하여 적절히 설정해야 한다.결론
CSS의
left/right
,transform: translateX()
조합은 절대 위치 요소의 정확한 가로 중앙 정렬을 가능하게 하며, 이는 레이아웃의 정밀도를 높이는 데 기여한다. 더불어 React의 상태 관리와 props 전달을 활용하여react-naver-maps
와 같은 라이브러리 컴포넌트의 속성(예:zIndex
)을 동적으로 제어하는 기법은 지도 애플리케이션 등에서 사용자 인터랙션에 반응하여 요소들의 표시 순서를 유연하게 변경하는 데 매우 유용하다. 이러한 웹 개발의 기본적인 기법들을 숙지하면 더욱 풍부하고 동적인 사용자 경험을 제공하는 애플리케이션을 구현할 수 있을 것이다.728x90반응형'언어·프레임워크 > React.js' 카테고리의 다른 글
[React.js] 메모이제이션 완벽 가이드: memo, useCallback, useMemo와 Profiler 활용 (0) 2025.05.25 [React.js] `useEffect`와 `useLayoutEffect`의 차이: 깜박임 현상과 중간 값 노출 (0) 2025.05.23 [React.js] Naver 지도 resize 이벤트 오류 해결하기 (`__event_relations__` 에러) (0) 2025.04.30 [React.js] React Hooks와 컴포넌트 생명주기, 함수 컴포넌트의 진화 살펴보기 (0) 2025.04.25 [React.js] Input 성능 최적화: 디바운싱과 스로틀링으로 불필요한 리렌더링 줄이기 (0) 2025.04.24 다음글이 없습니다.이전글이 없습니다.댓글