Kakao
Maps API

오버레이
로드뷰
정적지도
라이브러리

커스텀오버레이를 드래그 하기

지도 컨테이너 내 좌표와 화면 좌표 픽셀 변환을 이용해 커스텀 오버레이를 드래그 기능을 구현합니다. 커스텀 오버레이를 mousedown 한 후 mousemove 이벤트를 등록해 마우스가 얼마나 이동했는지 계산하고 커스텀 오버레이 위치에 반영합니다.

직접 해보기

Javascript

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);
    }
}

Javascript + HTML

<!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>