지도 컨테이너 내 좌표와 화면 좌표 픽셀 변환을 이용해 커스텀 오버레이를 드래그 기능을 구현합니다. 커스텀 오버레이를 mousedown 한 후 mousemove 이벤트를 등록해 마우스가 얼마나 이동했는지 계산하고 커스텀 오버레이 위치에 반영합니다.
var mapContainer = document.getElementById('map'), // 지도를 표시할 div mapOption = { center: new kakao.maps.LatLng(37.566826, 126.978656), // 지도의 중심좌표 level: 3 // 지도의 확대 레벨 }; // 지도를 표시할 div와 지도 옵션으로 지도를 생성합니다 var map = new kakao.maps.Map(mapContainer, mapOption); // 커스텀 오버레이 엘리먼트를 만들고, 컨텐츠를 추가합니다 var content = document.createElement('div'); content.className = 'overlay'; content.innerHTML = '드래그 해주세요 :D'; // 커스텀 오버레이를 생성합니다 var customoverlay = new kakao.maps.CustomOverlay({ map: map, content: content, position: new kakao.maps.LatLng(37.566826, 126.978656) }); // 커스텀 오버레이를 드래그 하기 위해 필요한 // 드래그 시작좌표, 커스텀 오버레이의 위치좌표를 넣을 변수를 선업합니다 var startX, startY, startOverlayPoint; // 커스텀 오버레이에 mousedown이벤트를 등록합니다 addEventHandle(content, 'mousedown', onMouseDown); // mouseup 이벤트가 일어났을때 mousemove 이벤트를 제거하기 위해 // document에 mouseup 이벤트를 등록합니다 addEventHandle(document, 'mouseup', onMouseUp); // 커스텀 오버레이에 mousedown 했을 때 호출되는 핸들러 입니다 function onMouseDown(e) { // 커스텀 오버레이를 드래그 할 때, 내부 텍스트가 영역 선택되는 현상을 막아줍니다. if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; } var proj = map.getProjection(), // 지도 객체로 부터 화면픽셀좌표, 지도좌표간 변환을 위한 MapProjection 객체를 얻어옵니다 overlayPos = customoverlay.getPosition(); // 커스텀 오버레이의 현재 위치를 가져옵니다 // 커스텀오버레이에서 마우스 관련 이벤트가 발생해도 지도가 움직이지 않도록 합니다 kakao.maps.event.preventMap(); // mousedown된 좌표를 설정합니다 startX = e.clientX; startY = e.clientY; // mousedown됐을 때의 커스텀 오버레이의 좌표를 // 지도 컨테이너내 픽셀 좌표로 변환합니다 startOverlayPoint = proj.containerPointFromCoords(overlayPos); // document에 mousemove 이벤트를 등록합니다 addEventHandle(document, 'mousemove', onMouseMove); } // 커스텀 오버레이에 mousedown 한 상태에서 // mousemove 하면 호출되는 핸들러 입니다 function onMouseMove(e) { // 커스텀 오버레이를 드래그 할 때, 내부 텍스트가 영역 선택되는 현상을 막아줍니다. if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; } var proj = map.getProjection(),// 지도 객체로 부터 화면픽셀좌표, 지도좌표간 변환을 위한 MapProjection 객체를 얻어옵니다 deltaX = startX - e.clientX, // mousedown한 픽셀좌표에서 mousemove한 좌표를 빼서 실제로 마우스가 이동된 픽셀좌표를 구합니다 deltaY = startY - e.clientY, // mousedown됐을 때의 커스텀 오버레이의 좌표에 실제로 마우스가 이동된 픽셀좌표를 반영합니다 newPoint = new kakao.maps.Point(startOverlayPoint.x - deltaX, startOverlayPoint.y - deltaY), // 계산된 픽셀 좌표를 지도 컨테이너에 해당하는 지도 좌표로 변경합니다 newPos = proj.coordsFromContainerPoint(newPoint); // 커스텀 오버레이의 좌표를 설정합니다 customoverlay.setPosition(newPos); } // mouseup 했을 때 호출되는 핸들러 입니다 function onMouseUp(e) { // 등록된 mousemove 이벤트 핸들러를 제거합니다 removeEventHandle(document, 'mousemove', onMouseMove); } // target node에 이벤트 핸들러를 등록하는 함수힙니다 function addEventHandle(target, type, callback) { if (target.addEventListener) { target.addEventListener(type, callback); } else { target.attachEvent('on' + type, callback); } } // target node에 등록된 이벤트 핸들러를 제거하는 함수힙니다 function removeEventHandle(target, type, callback) { if (target.removeEventListener) { target.removeEventListener(type, callback); } else { target.detachEvent('on' + type, callback); } }
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>커스텀오버레이를 드래그 하기</title> <style> .overlay { position:absolute; left: -50px; top:0; width:100px; height: 100px; background: #fff; border:1px solid #ccc; border-radius: 5px; padding:5px; font-size:12px; text-align: center; white-space: pre; word-wrap: break-word; } </style> </head> <body> <div id="map" style="width:100%;height:350px;"></div> <script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=발급받은 APP KEY를 사용하세요"></script> <script> var mapContainer = document.getElementById('map'), // 지도를 표시할 div mapOption = { center: new kakao.maps.LatLng(37.566826, 126.978656), // 지도의 중심좌표 level: 3 // 지도의 확대 레벨 }; // 지도를 표시할 div와 지도 옵션으로 지도를 생성합니다 var map = new kakao.maps.Map(mapContainer, mapOption); // 커스텀 오버레이 엘리먼트를 만들고, 컨텐츠를 추가합니다 var content = document.createElement('div'); content.className = 'overlay'; content.innerHTML = '드래그 해주세요 :D'; // 커스텀 오버레이를 생성합니다 var customoverlay = new kakao.maps.CustomOverlay({ map: map, content: content, position: new kakao.maps.LatLng(37.566826, 126.978656) }); // 커스텀 오버레이를 드래그 하기 위해 필요한 // 드래그 시작좌표, 커스텀 오버레이의 위치좌표를 넣을 변수를 선업합니다 var startX, startY, startOverlayPoint; // 커스텀 오버레이에 mousedown이벤트를 등록합니다 addEventHandle(content, 'mousedown', onMouseDown); // mouseup 이벤트가 일어났을때 mousemove 이벤트를 제거하기 위해 // document에 mouseup 이벤트를 등록합니다 addEventHandle(document, 'mouseup', onMouseUp); // 커스텀 오버레이에 mousedown 했을 때 호출되는 핸들러 입니다 function onMouseDown(e) { // 커스텀 오버레이를 드래그 할 때, 내부 텍스트가 영역 선택되는 현상을 막아줍니다. if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; } var proj = map.getProjection(), // 지도 객체로 부터 화면픽셀좌표, 지도좌표간 변환을 위한 MapProjection 객체를 얻어옵니다 overlayPos = customoverlay.getPosition(); // 커스텀 오버레이의 현재 위치를 가져옵니다 // 커스텀오버레이에서 마우스 관련 이벤트가 발생해도 지도가 움직이지 않도록 합니다 kakao.maps.event.preventMap(); // mousedown된 좌표를 설정합니다 startX = e.clientX; startY = e.clientY; // mousedown됐을 때의 커스텀 오버레이의 좌표를 // 지도 컨테이너내 픽셀 좌표로 변환합니다 startOverlayPoint = proj.containerPointFromCoords(overlayPos); // document에 mousemove 이벤트를 등록합니다 addEventHandle(document, 'mousemove', onMouseMove); } // 커스텀 오버레이에 mousedown 한 상태에서 // mousemove 하면 호출되는 핸들러 입니다 function onMouseMove(e) { // 커스텀 오버레이를 드래그 할 때, 내부 텍스트가 영역 선택되는 현상을 막아줍니다. if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; } var proj = map.getProjection(),// 지도 객체로 부터 화면픽셀좌표, 지도좌표간 변환을 위한 MapProjection 객체를 얻어옵니다 deltaX = startX - e.clientX, // mousedown한 픽셀좌표에서 mousemove한 좌표를 빼서 실제로 마우스가 이동된 픽셀좌표를 구합니다 deltaY = startY - e.clientY, // mousedown됐을 때의 커스텀 오버레이의 좌표에 실제로 마우스가 이동된 픽셀좌표를 반영합니다 newPoint = new kakao.maps.Point(startOverlayPoint.x - deltaX, startOverlayPoint.y - deltaY), // 계산된 픽셀 좌표를 지도 컨테이너에 해당하는 지도 좌표로 변경합니다 newPos = proj.coordsFromContainerPoint(newPoint); // 커스텀 오버레이의 좌표를 설정합니다 customoverlay.setPosition(newPos); } // mouseup 했을 때 호출되는 핸들러 입니다 function onMouseUp(e) { // 등록된 mousemove 이벤트 핸들러를 제거합니다 removeEventHandle(document, 'mousemove', onMouseMove); } // target node에 이벤트 핸들러를 등록하는 함수힙니다 function addEventHandle(target, type, callback) { if (target.addEventListener) { target.addEventListener(type, callback); } else { target.attachEvent('on' + type, callback); } } // target node에 등록된 이벤트 핸들러를 제거하는 함수힙니다 function removeEventHandle(target, type, callback) { if (target.removeEventListener) { target.removeEventListener(type, callback); } else { target.detachEvent('on' + type, callback); } } </script> </body> </html>