Draggable div moving 2px even though it's snapped to 10px

247 Views Asked by At

The following code creates a draggable 40px rectangle inside a 400px grid (using Interact.js):

HTML:

<div id="app">
  <div class="live-demo">
    <div id="grid-snap"></div>
  </div>
</div>

JS:

var element = document.getElementById('grid-snap')
var x = 0
var y = 0

interact(element)
  .draggable({
    snap: {
      targets: [
        interact.createSnapGrid({ x: 10, y: 10 })
      ],
      range: Infinity,
      relativePoints: [ { x: 0, y: 0 } ]
    },
    restrict: {
      restriction: element.parentNode,
      elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
    }
  })
  .on('dragmove', function (event) {
    x += event.dx;
    y += event.dy;

    event.target.style.webkitTransform =
    event.target.style.transform =
        'translate(' + x + 'px, ' + y + 'px)';
  });

CSS:

.live-demo {
  display: inline-block;
  vertical-align: top;
  width: 400px;
  height: 400px;
  background-color: #e8e9e8;
}

#grid-snap {
  width: 40px;
  height: 40px;
  background-color: #29e;
  color: #fff;
}

For some reason, the square moves an initial 2px when it's dragged for the first time. This doesn't happen when createSnapGrid() is set to 30px for x and y.

Not sure if this is a coding or math problem. How to modify the code (or CSS) to eliminate that initial 2px movement?

JSFiddle: https://jsfiddle.net/nq5zz27j/4/

1

There are 1 best solutions below

0
Shawn Gavett On

It is something to do with the math. When you set the relativePoint, it is defining where the grid will snap to. So choosing x: 0, Y: 0 will use the top left corner of your object. As to why x: .8 and y: .8 is the answer. I don't have a scientific answer as to why this is (still working on that part).

But if you change

relativePoints: [ { x: 0, y: 0 } ]

to

relativePoints: [ { x: .8, y: .8 } ]

It will do what you are looking for I believe. Let me know if that is what you meant.

jfiddle: https://jsfiddle.net/nq5zz27j/5/