Ching Ching Ching Ching - 4 months ago 92
HTML Question

Javascript move element with mousemove event 60 FPS requestAnimationFrame

there! i have a problem for getting

#drag
element moving smoothly.

i look at this article : http://www.html5rocks.com/en/tutorials/speed/animations/#debouncing-mouse-events

it said that : "the problem with
mousemove
event when moving element was mousemove event fired too much

so, i try to used their method : using
requestAnimationFrame
+
boolean checking
.

look at this fiddle for live action : https://jsfiddle.net/5f181w9t/

HTML :

<div id="drag">this is draggable</div>


CSS :

#drag {width:100px; height:50px; background-color:red; transform:translate3d(0, 0, 0); }


JS :

var el = document.getElementById("drag"),
startPosition = 0, // start position mousedown event
currentPosition = 0, // count current translateX value
distancePosition = 0, // count distance between "down" & "move" event
isMouseDown = false; // check if mouse is down or not

function mouseDown(e) {
e.preventDefault(); // reset default behavior
isMouseDown = true;
startPosition = e.pageX; // get position X
currentPosition = getTranslateX(); // get current translateX value
requestAnimationFrame(update); // request 60fps animation
}

function mouseMove(e) {
e.preventDefault();
distancePosition = (e.pageX - startPosition) + currentPosition; // count it!
}

function mouseUp(e) {
e.preventDefault();
isMouseDown = false; // reset mouse is down boolean
}

function getTranslateX() {
var translateX = parseInt(getComputedStyle(el, null).getPropertyValue("transform").split(",")[4]);

return translateX; // get translateX value

}

function update() {
if (isMouseDown) { // check if mouse is down
requestAnimationFrame(update); // request 60 fps animation
}
el.style.transform = "translate3d(" + distancePosition + "px, 0, 0)";
// move it!
}

el.addEventListener("mousedown", mouseDown);
document.addEventListener("mousemove", mouseMove);
document.addEventListener("mouseup", mouseUp);


is this the correct way to accompolished it?

what's wrong with my code?

thanks

Answer

The problem is that you are using requestAnimationFrame() in the mouseDown event listener. You should do all you updates in the mouseMove event listener because you want to update your display when the mouse moves not when mouse clicks. Accordingly you should update all your variables under the isMouseDown conditional in the update function. i would suggest correcting the code as follows.

HTML

<div id="drag">this is draggable</div>

CSS

#drag {
width:100px;
height:50px;
background-color:red;
transform:translateX(0);
}

JS

var el               = drag,
    startPosition    = 0, // start position mousedown event
    currentPosition  = 0, // count current translateX value
    distancePosition = 0, // count distance between "down" & "move" event
    isMouseDown      = false; // check if mouse is down or not 

function mouseDown(e) {
  e.preventDefault(); // reset default behavior
  isMouseDown     = true;
  currentPosition = getTranslateX(); // get current translateX value
  startPosition   = e.clientX; // get position X
}    

function mouseMove(e) {
  e.preventDefault();
  distancePosition = (e.clientX - startPosition) + currentPosition; // count it!  
  requestAnimationFrame(update); // request 60fps animation
}

function mouseUp(e) {
  e.preventDefault();
  isMouseDown = false; // reset mouse is down boolean
}

function getTranslateX() {
  var translateX = parseInt(getComputedStyle(el, null).getPropertyValue("transform").split(",")[4]);
  return translateX; // get translateX value
}

function update() {
  if (isMouseDown) { // check if mouse is down
  el.style.transform = "translateX(" + distancePosition + "px)";// move it!
  }   
}

el.addEventListener("mousedown", mouseDown);
document.addEventListener("mousemove", mouseMove);
document.addEventListener("mouseup", mouseUp);

check it up here