지도 컨테이너 내 좌표와 화면 좌표 픽셀 변환을 이용해 커스텀 오버레이를 드래그 기능을 구현합니다. 커스텀 오버레이를 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>