4

I'm using the code posted in the answer here to pan a large image using mousedown, positioned in a div underneath another image with transparency. There is no need for zooming. The code works fine for me, except that the pan begins from the top left corner of the large image, and I want it to begin from the centre point, and then pan in all directions. I don't know enough about the calculations involved to do it, so would really appreciate some pointers on how to work it out, or alternatively what I need to do to specify a starting point.

The jQuery is:

var clicking = false;
var previousX;
var previousY;

$("#scroll").mousedown(function(e) {
    e.preventDefault();
    previousX = e.clientX;
    previousY = e.clientY;
    clicking = true;
});

$(document).mouseup(function() {

    clicking = false;
});

$("#scroll").mousemove(function(e) {

    if (clicking) {
        e.preventDefault();
        var directionX = (previousX - e.clientX) > 0 ? 1 : -1;
        var directionY = (previousY - e.clientY) > 0 ? 1 : -1;
        $("#scroll").scrollLeft($("#scroll").scrollLeft() + (previousX - e.clientX));
        $("#scroll").scrollTop($("#scroll").scrollTop() + (previousY - e.clientY));
        previousX = e.clientX;
        previousY = e.clientY;
    }
});

$("#scroll").mouseleave(function(e) {
    clicking = false;
});

The html is:

<div id="scroll">
  <img src="sampleimg.jpg" class="background" />
</div>
<img src="sampleoverlay.png" class="overlay" />

The css is:

#scroll {
  width: 580px;
  height: 620px;
  overflow: hidden;
}

.background {
  width: 100%;
  height: 100%;
}

.overlay {
  width: 100%; 
  height: 100%;
  position: absolute;
  pointer-events: none;
}

Apologies if this is really obvious - I couldn't find anything that would answer my question, but may not have been searching for the right thing.

Community
  • 1
  • 1
Sarah
  • 145
  • 1
  • 2
  • 8

2 Answers2

4

Since the answer that you referenced uses scrolling on a div with overflow:hidden, you simply need to scroll the div to the correct starting place. You can calculate this by subtracting the width of the image from the width of the div. This gives you the margin space on both sides of the div, so we need to divide that by two.

calculations

Do the same with the heights to find the top margin, then simply scroll your div to that position using jQuery's scrollTop() and scrollLeft().

jsFiddle

RustyTheBoyRobot
  • 5,891
  • 4
  • 36
  • 55
  • Ah, except it won't now work on a tablet, even with touch-punch implemented. Do you have any advice for getting it working? I tried changing all the mouse events to touch events as well. – Sarah Oct 16 '13 at 16:14
  • Sorry, I've never dealt with that. I know that jQuery has a [mobile library](http://jquerymobile.com/), but I've never used it. – RustyTheBoyRobot Oct 16 '13 at 16:54
2

I believe you can make this work for mobile by using touch events. I am not sure if touchend and an equivalent to mouseleave are needed, but it would be something like this:

$(document).ready(function(){
var $container = $("#scroll");
var $img = $("#scroll img");
var cHeight = $container.height();
var cWidth = $container.width();
var iHeight = $img.height();
var iWidth = $img.width();

var top = (iHeight - cHeight) / 2;
var left = (iWidth - cWidth) / 2;

$container.scrollLeft(left);
$container.scrollTop(top);
});

var clicking = false;
var previousX;
var previousY;

$("#scroll").bind('touchstart', function(e) {
  e.preventDefault();
  previousX = e.touches[0].clientX;
  previousY = e.touches[0].clientY;
  clicking = true;
});

/* $(document).bind('touchend', function() {

    clicking = false;
}); */

$("#scroll").bind('touchmove', function(e) {
  if (clicking) {
    e.preventDefault();
    var directionX = (previousX - e.touches[0].clientX) > 0 ? 1 : -1;
    var directionY = (previousY - e.touches[0].clientY) > 0 ? 1 : -1;

    container.scrollLeft(container.scrollLeft() + (previousX - e.touches[0].clientX));
    container.scrollTop(container.scrollTop() + (previousY - e.touches[0].clientY));

    previousX = e.touches[0].clientX;
    previousY = e.touches[0].clientY;
  }
});

jsFiddle (the fiddle doesn't work unless you can somehow make it mimic mobile - I am not sure how)

hmoore
  • 155
  • 1
  • 3
  • 13