0

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);
GWorking
  • 4,011
  • 10
  • 49
  • 90

3 Answers3

2

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>
berrtech
  • 328
  • 1
  • 9
  • I've updated your code (after understanding it, thanks a lot) in https://jsfiddle.net/59sxn1jy/6/ and adapted as well to my code, I like to think it goes a little bit better but the truth is that the experience is still meh (but perhaps that's the best I can get) – GWorking Sep 12 '16 at 21:44
  • What else you could do is try to fiddle with div's transition property, say, set it to `transition: transform 0.1s linear;` and adjust duration to find balance between div move speed and smoother experience – berrtech Sep 13 '16 at 06:42
1

Try jQuery UI : https://jqueryui.com/draggable/

Much smoother and with cross-platform support. Try the following:

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
<script>
  $(document).ready(function() {
    $("#panel_log").draggable();
  });
</script>
Ted
  • 3,985
  • 1
  • 20
  • 33
1

function drag_start(event) {
    var style = window.getComputedStyle(event.target);
    event.dataTransfer.setData("text/plain",
    (parseInt(style.getPropertyValue("left"),10) - event.clientX) + ',' + (parseInt(style.getPropertyValue("top"),10) - event.clientY));
} 
function drag_over(event) { 
    event.preventDefault(); 
    return false; 
} 
function drop(event) { 
    var offset = event.dataTransfer.getData("text/plain").split(',');
    var dm = document.getElementById('dragme');
    dm.style.left = (event.clientX + parseInt(offset[0],10)) + 'px';
    dm.style.top = (event.clientY + parseInt(offset[1],10)) + 'px';
    event.preventDefault();
    return false;
} 
var dm = document.getElementById('dragme'); 
dm.addEventListener('dragstart',drag_start,false); 
document.body.addEventListener('dragover',drag_over,false); 
document.body.addEventListener('drop',drop,false); 
#dragme {
  width: 100px;
  height: 100px;
  border: 1px solid #000;
  background-color:#fff;
  cursor: move;
  left: 0;
  top: 0;
  position: absolute;
}

body {
  width: 100vw;
  height: 100vh;
}
<div id="dragme" draggable="true"></div>

Taken from this answer. Unfortunately, I do not believe that this can be done without JavaScript.

StardustGogeta
  • 3,331
  • 2
  • 18
  • 32
  • Your code snippet doesn't seem to work. Thanks for the link, honestly however I see that code much more obfuscated, unless somebody tells me that performance is improved in that implementation I'll stay with the above solution – GWorking Sep 12 '16 at 21:53