javascript를 이용해서 그림을 마우스로 끌어서 옮기는 방법

마우스로 그림을 끌어 옮기는 것은 다음 세가지 이벤트가 순서대로 일어나는 것이다.

mouse down --> mouse move --> mouse up



Mouse down에서는
  • drag가 시작되었다고 표시하고
  • 마우스가 클릭된 위치를 기억하고 (sx, sy)
  • 마우스가 드래그된 거리를 초기화시키고 (dx, dy)
  • 당시의 그림의 위치를 기억한다. (ix, iy)

Mouse move에서는
  • dx와 dy를 계산하고,
  • 그림의 첫 위치인 (ix, iy)에 (dx, dy)만큼 이동시킨 위치로 그림을 이동시킨다

Mouse up에서는
  • drag가 종료되었다고 표시하고
  • dx와 dy를 최종적으로 계산하고
  • 그림의 첫 위치인 (ix, iy)에 (dx, dy)만큼 이동시킨 위치로 그림을 이동시킨다



<!DOCTYPE html>
<html>
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script>
    $(function() {
      var debug = $('#debug');
      var o = $('#my_ball');
      var sx, sy, dx, dy, ix, iy;
      var dragging = false;
      $('#my_ball').on('mousedown', function(e) {
        e.preventDefault();
        sx = e.pageX;
        sy = e.pageY;
        ix = $(o).offset().left;
        iy = $(o).offset().top;
        dx=dy=0;
        dragging = true;
        console.log("mousedown - s:",sx,sy,"/i:",ix,iy);
      }).on('mousemove', function(e) {
        if(dragging) {
          dx = e.pageX - sx;
          dy = e.pageY - sy;
          $(o).offset({left: ix + dx, top: iy + dy});
          $(debug).text(dx + "," + dy);
        }
      }).on('mouseup', function(e){
        dx = e.pageX - sx;
        dy = e.pageY - sy;
        $(o).offset({left: ix + dx, top: iy + dy});
        dragging = false;
        console.log("mouseup - d:",dx,dy,"/i:",ix,iy);
      });
    });
    </script>
  </head>
  <body>
    <img id="my_ball" src="ball.png" style="position:absolute">
    <h1 style="text-align:right;" id="debug"> </h2>
  </body>
</html>




잘 동작한다. 그런데 빠른 속도로 그림을 끌면 그림을 놓치게 된다.
빠른 속도로 그림을 끌때는 마우스가 <img>를 벗어나서 <html> 영역에 들어가 있기때문에, 이것을 개선시키려면 <html>에 mousemove 이벤트 핸들러를 등록시켜야 한다.