Search code examples
javascripthtmldrag-and-dropdraggable

javascript, moving a div, what is the smoothest implementation?


I am moving a div with the following code but while in jsfiddle it is smooth, in my code it is jumpy and the experience is not the best.

I am wondering if I am skipping something here, then the question about whether there is any particular way to code it. For example, can it be done only with css?

https://jsfiddle.net/59sxn1jy/2/

html

<div id="panel_log"></div>

css

#panel_log {
  position:absolute;
  width:100px;
  height:100px;
  border:1px solid #000;
  background-color:#fff;
  top:20px;
  left:20px;
  cursor:move;
}

javsacript

var spaceY;
var spaceX;

var move_start = function(e) {
  var panel_log = document.getElementById('panel_log');
  spaceY = parseInt(window.getComputedStyle(panel_log,null).getPropertyValue('top')) - parseInt(e.clientY);
  spaceX = parseInt(window.getComputedStyle(panel_log,null).getPropertyValue('left')) - parseInt(e.clientX);

  window.addEventListener('mousemove',moving,false);
  window.addEventListener('mouseup',finishing,false);
};

var moving = function(e) {
  var panel_log = document.getElementById('panel_log');
  panel_log.style.top = parseInt(e.clientY) + spaceY + 'px';
  panel_log.style.left = parseInt(e.clientX) + spaceX + 'px';
};

var finishing = function(e) {
  var panel_log = document.getElementById('panel_log');
  window.removeEventListener('mousemove', moving, false);
  window.removeEventListener('mouseup', finishing, false);
};
document.getElementById('panel_log').addEventListener('mousedown',move_start,false);

Solution

  • Try using css transform property instead of left and top https://jsfiddle.net/59sxn1jy/5/

    This should be faster because transform: translate3d() uses gpu , more info on that http://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/

    The problem with this approach is you can't easily get computed transform value, so you'll have to store position.

    Here's the code

    var spaceX, spaceY;
    
    var left = 20;
    var top = 20;
    
    var setPosition = function(elem, x, y) {
      elem.style.transform = 'translate3d(' + parseInt(x) + 'px, ' + parseInt(y) + 'px, ' + '0)';
      left = x;
      top = y;
    }
    
    setPosition(document.getElementById('panel_log'), left, top)
    
    var move_start = function(e) {
      var panel_log = document.getElementById('panel_log');
          
      spaceX = parseInt(left) - parseInt(e.clientX);
      spaceY = parseInt(top) - parseInt(e.clientY);
    
      window.addEventListener('mousemove', moving, false);
      window.addEventListener('mouseup', finishing, false);
    }
    
    var moving = function(e) {
      var panel_log = document.getElementById('panel_log');
      setPosition(panel_log, parseInt(e.clientX) + spaceX, parseInt(e.clientY) + spaceY)
    };
    
    var finishing = function(e) {
      var panel_log = document.getElementById('panel_log');
      window.removeEventListener('mousemove', moving, false);
      window.removeEventListener('mouseup', finishing, false);
    };
    
        document.getElementById('panel_log').addEventListener('mousedown', move_start, false);
    #panel_log {
      position: absolute;
      width: 100px;
      height: 100px;
      border: 1px solid #000;
      background-color: #fff;
      cursor: move;
    }
    <div id="panel_log"></div>