Move (drag/pan) and zoom object (image or div) in pure js

sangrila B picture sangrila B · Feb 7, 2016 · Viewed 27.2k times · Source

I'm working on a little script that makes an object (div or img) moveable and zoomable within a given frame.

However I came across a few problems I'm not really sure of, because I'm a javascript beginner - so explanation of why those problems occure would be appreciated.

Problems:

  1. Calling the functions start_drag(), while_drag() and stop_drag() returns undefined - why is that? What should be returned?
  2. The dragging and moving of the image does not work correctly - instead of clicking the mousebutton down and starting to move the image around, I have to click once and then start moving. Although I bound the mousedown event to the image. What did I do wrong?
  3. Why is the moving part not working on mobile (the zooming works!)?

Please see my fiddle: https://jsfiddle.net/pow4ngbw/15/

Answer

Bug picture Bug · Feb 7, 2016

Working fine now, was mainly the image css but found several errors (see the new img attribute), also added a few tweaks to make the dragging smoother.

<!DOCTYPE html>
<html>
<body>
<div id="container">
  <img ondragstart="return false" id="drag-img" src="http://www.patsoy.com/p/2015/09/geometric-patterns-f03phtdx.jpg" />
</div>
<input type="button" id="zoomout" class="button" value="Zoom out">
<input type="button" id="zoomin" class="button" value="Zoom in">
</body>
</html>
<script>

var img_ele = null,
  x_cursor = 0,
  y_cursor = 0,
  x_img_ele = 0,
  y_img_ele = 0;

function zoom(zoomincrement) {
  img_ele = document.getElementById('drag-img');
  var pre_width = img_ele.getBoundingClientRect().width, pre_height = img_ele.getBoundingClientRect().height;
  img_ele.style.width = (pre_width * zoomincrement) + 'px';
  img_ele.style.height = (pre_height * zoomincrement) + 'px';
  img_ele = null;
}

document.getElementById('zoomout').addEventListener('click', function() {
  zoom(0.5);
});
document.getElementById('zoomin').addEventListener('click', function() {
  zoom(1.5);
});

function start_drag() {
  img_ele = this;
  x_img_ele = window.event.clientX - document.getElementById('drag-img').offsetLeft;
  y_img_ele = window.event.clientY - document.getElementById('drag-img').offsetTop;

}

function stop_drag() {
  img_ele = null;
}

function while_drag() {
  var x_cursor = window.event.clientX;
  var y_cursor = window.event.clientY;
  if (img_ele !== null) {
    img_ele.style.left = (x_cursor - x_img_ele) + 'px';
    img_ele.style.top = ( window.event.clientY - y_img_ele) + 'px';

      console.log(img_ele.style.left+' - '+img_ele.style.top);

  }
}

document.getElementById('drag-img').addEventListener('mousedown', start_drag);
document.getElementById('container').addEventListener('mousemove', while_drag);
document.getElementById('container').addEventListener('mouseup', stop_drag);
</script>

<style>
#drag-img {
  cursor: move;
  position: relative;
  width: 500px;
  height: 500px;
}

#container {
  overflow: hidden;
  background: red;
  height: 500px;
  width: 500px;
}

.button {
  width: 200px;
  height: 50px;
}
</style>