회전 및 draggable 가능한 동동이는 어떻게 만들죠?

샘플코드 : 동동이를 이용하여 로드뷰와 지도 연동하기(https://apis.map.kakao.com/web/sample/moveRoadview/)에서

동동이가 draggable 가능한 코드가 필요합니다.

샘플코드상에서 draggable이 불가능한데, new kakao.maps.Marker 는 draggable이 가능합니다.

그런데 new kakao.maps.Marker는 동동이가 회전되는 기능은 안되는 것같은데

동동이가 회전, draggable 가능한 방법은 샘플코드상의 MapWalker의 클래스를 수정해야 되는지요?..

방법을 알려주시면 고맙겠습니다.

커스텀 오버레이로 생성된 동동이에 드래그가 가능하도록 구현해주셔야 합니다.
아래 소스는 샘플 코드를 활용한 로직입니다.
참고해서 원하는 방향으로 수정해주세요.

function MapWalker(position) {
    //…
    // 커스텀 오버레이에 mousedown이벤트를 등록합니다
    addEventHandle(this.content, 'mousedown', onMouseDown);

    // 커스텀 오버레이에 mouseup이벤트를 등록합니다.
    addEventHandle(this.content, 'mouseup', onMouseUp);
}

//mousedown, mousemove 핸들러 함수는 드래그가 가능한 오버레이 예제와 동일합니다. 
// http://apis.map.kakao.com/web/sample/dragCustomOverlay 참고해주세요.
function onMouseDown(e) { 
    //…
}

// mouseup 했을 때 호출되는 핸들러 입니다
function onMouseUp(e) {
    // 등록된 mousemove 이벤트 핸들러를 제거합니다
    removeEventHandle(document, 'mousemove', onMouseMove);
    //이동한 마커 위치의 panoId를 가져올 수 있도록 toggleRoadview를 호출합니다.
    toggleRoadview(mapWalker.getPosition());
}

// map walker의 위치를 가져오는 함수
MapWalker.prototype.getPosition = function() {
    return this.walker.getPosition();
}

// 로드뷰 toggle함수
function toggleRoadview(position){
    //전달받은 좌표(position)에 가까운 로드뷰의 panoId를 추출하여 로드뷰를 띄웁니다
    roadviewClient.getNearestPanoId(position, 200, function(panoId) {
        if (panoId !== null) {
            roadview.setPanoId(panoId, position); //panoId를 통한 로드뷰 실행
        }
    });
}

http://apis.map.kakao.com/web/sample/moveRoadview/
http://apis.map.kakao.com/web/sample/dragCustomOverlay/
http://apis.map.kakao.com/web/sample/basicRoadview2/

1개의 좋아요

정말 감사합니다. 잘 활용해보겠습니다.^^

1개의 좋아요

커스텀오버레이로 구현된 MapWalker의 관련예제(http://apis.map.kakao.com/web/sample/dragCustomOverlay/)는 마우스 이벤트로 잘 구현됩니다.

그런데 스마트폰에서도 html 파일을 구동하기위해 동동이를 draggable 이벤트를 구현하기 위해 'touchmove, touchup,

touchstart’을 반영해야 하는 것같습니다.

addEventHandle(this.content, ‘mousedown’, onMouseDown); 를(up, move 포함) 이용하여 다음줄에

addEventHandle(this.content, ‘touchstart’, onMouseDown); 으로 한줄추가하는 것만으로는 작동이 안됩니다.

예제문에서 PC와 스마트폰 모두 draggable가능하기 위해서 touch이벤트 적용이 가능하다면 추가 또는 수정해야 할 부분이 있는 것인지요?

마우스 이벤트와 다르게 터치 이벤트에서 clientX 은 아래 문서와 같이 접근해야 합니다.
https://developer.mozilla.org/en-US/docs/Web/API/Touch/clientX

문서 참고해서 clientX, clientY 값을 이용한 로직을 마우스, 터치 모두 가능하도록 수정해주시고
마우스 이벤트와 동일하게 touchstart, touchmove, touchend 이벤트를 등록해주세요.

정말 감사합니다. 제공해주신 문서자료로 활용해보겠습니다. ^^

1개의 좋아요

lea.ju 카카오님 정말 감사하고요.

알려주신 방법대로 반영하여 실행가능한 소스를 올립니다…

혹시 이러한 기능 필요하신분 잘 활용하시길…

  • 반영내용: 커스텀오버레이형 동동이 회전, 드래그이동(PC, 스마트폰)

          var startX, startY, startOverlayPoint;
      function MapWalker(position){
      //커스텀 오버레이에 사용할 map walker 엘리먼트
      var content = document.createElement('div');
      var figure = document.createElement('div');
      var angleBack = document.createElement('div');
    
      //map walker를 구성하는 각 노드들의 class명을 지정 - style셋팅을 위해 필요
      content.className = 'MapWalker';
      figure.className = 'figure';
      angleBack.className = 'angleBack';
    
      content.appendChild(angleBack);
      content.appendChild(figure);
    
      //커스텀 오버레이 객체를 사용하여, map walker 아이콘을 생성
      var walker = new kakao.maps.CustomOverlay({
          position: position,
          content: content,
          yAnchor: 1
      });
    
      this.walker = walker;
      this.content = content;
    
          // 커스텀 오버레이에 mousedown, mouseup 이벤트를 등록합니다
          addEventHandle(this.content, 'mousedown', onMouseDown);
          addEventHandle(this.content, 'mouseup', onMouseUp);
    
          // 커스텀 오버레이에 touchstart, touchend 이벤트를 등록합니다
          addEventHandle(this.content, 'touchstart', onMouseDown);
          addEventHandle(this.content, 'touchend', onMouseUp);
      }
    
      function onMouseDown(e) { 
          // 커스텀 오버레이를 드래그 할 때, 내부 텍스트가 영역 선택되는 현상을 막아줍니다.
          if (e.preventDefault) {
              e.preventDefault();
          } else {
              e.returnValue = false;
          }
    
          var proj = map.getProjection(), 
              overlayPos = mapWalker.getPosition(); // 커스텀 오버레이의 현재 위치를 가져옵니다
    
          // 커스텀오버레이에서 마우스 관련 이벤트가 발생해도 지도가 움직이지 않도록 합니다
          kakao.maps.event.preventMap();
    
          if(e.type=='mousedown')
          {   startX = e.clientX; 
              startY = e.clientY;
          }
          else if (e.type=='touchstart') {
              startX = e.touches[0].clientX; 
              startY = e.touches[0].clientY;
          }
    
          // mousedown됐을 때의 커스텀 오버레이의 좌표를
          // 지도 컨테이너내 픽셀 좌표로 변환합니다 
          startOverlayPoint = proj.containerPointFromCoords(overlayPos);
    
          // document에 mousemove 이벤트를 등록합니다 
              addEventHandle(document, 'mousemove', onMouseMove);
              addEventHandle(document, 'touchmove', onMouseMove);
      }
    
      function onMouseMove(e) {
          // 커스텀 오버레이를 드래그 할 때, 내부 텍스트가 영역 선택되는 현상을 막아줍니다.
          if (e.preventDefault) {
              e.preventDefault();
          } else {
              e.returnValue = false;
          }
    
          if(e.type=='mousemove')
          {
              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);
          }
          else if (e.type=='touchmove') {
              var proj = map.getProjection(),// 지도 객체로 부터 화면픽셀좌표, 지도좌표간 변환을 위한 MapProjection 객체를 얻어옵니다 
              deltaX = startX - e.touches[0].clientX, // mousedown한 픽셀좌표에서 mousemove한 좌표를 빼서 실제로 마우스가 이동된 픽셀좌표를 구합니다 
              deltaY = startY - e.touches[0].clientY,
              // mousedown됐을 때의 커스텀 오버레이의 좌표에 실제로 마우스가 이동된 픽셀좌표를 반영합니다 
              newPoint = new kakao.maps.Point(startOverlayPoint.x - deltaX, startOverlayPoint.y - deltaY), 
              // 계산된 픽셀 좌표를 지도 컨테이너에 해당하는 지도 좌표로 변경합니다 
              newPos = proj.coordsFromContainerPoint(newPoint);
          }
          // 커스텀 오버레이의 좌표를 설정합니다 
          mapWalker.setPosition(newPos);
      }
    
      // mouseup 했을 때 호출되는 핸들러 입니다
      function onMouseUp(e) {
          // 등록된 mousemove 이벤트 핸들러를 제거합니다
          removeEventHandle(document, 'mousemove', onMouseMove);
          removeEventHandle(document, 'touchmove', onMouseMove);
          //이동한 마커 위치의 panoId를 가져올 수 있도록 toggleRoadview를 호출합니다.
          toggleRoadview(mapWalker.getPosition());
      }
    
      // 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);
          }
      }	(작성자에 의해 취소된 글입니다. 글이 신고된 것이 아닌 한 24 시간 뒤에 자동으로 삭제됩니다)
1개의 좋아요