10

I'm creating quite a cool image viewer but am stuck in one particular part: panning the image when zoomed in. It seems a trivial problem and I've tried out pretty much all answers to similar questions on SO, but each time, something isn't working right. I need a fresh pair of eyes.

I've temporarily opened a URL on my dev server. Have a look at this page:

[URL closed]

Next, move up your mouse wheel to trigger the zoom. Here we are. Once zoomed in, click and drag to try and pan the image. It is panning alright, but something isn't right. This is currently the code used for the panning:

var clicking = false;
var previousX;
var previousY;

$("#bigimage").mousedown(function(e) {

    e.preventDefault();
    previousX = e.clientX;
    previousY = e.clientY;
    clicking = true;
});

$(document).mouseup(function() {
    clicking = false;
});

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

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

The solution I'm looking for has these characteristics:

  • Correct direction of panning over the X and Y axis
  • It should not be possible to pan outside the edges of the image
  • Reasonably fluent panning
  • Nice to have: window resize should not cause any issues

Although I appreciate any help I can get, please don't point me to a generic plugin, I've tried too many of them that I am in search of an answer that works for my specific scenario. I'm so desperate I'll even set a money bounty for the perfect solution that meets the characteristic above.

PS: Please try the link in Firefox or a Webkit browser

Community
  • 1
  • 1
Fer
  • 4,116
  • 16
  • 59
  • 102
  • Could you describe what's not working, and provide a fiddle? Without zooming, the image has already some issues with panning, according to me. I have previously created a background panning script, by just moving the mouse, see [this answer](http://stackoverflow.com/questions/7776843/mouse-on-left-of-screen-move-image-to-left-same-when-mouse-on-right-of-screen/7777153#7777153) for inspiration. – Rob W Nov 10 '11 at 11:01
  • @RobW Thanks, but the approach with the background image would be a major overhaul of the whole thing, too many dependencies, I'm thinking of dropping this feature alltogether. I was hoping it could be fixed using the scrolling method. – Fer Nov 10 '11 at 22:27
  • As you can see in my fiddle, panning is not hard, and can be done efficiently. Your problem is probably caused by writing code without thinking how to efficiently implement it beforehand. Zooming can be done easily by using proper logic and the `background-size` CSS property. I have already implemented panning. Adding both together results in the desired functionality. If you offer some relevant code, I might consider having a look at it. – Rob W Nov 10 '11 at 22:44
  • Could you post your html/css. Your url is now closed and without html and css I would just be guessing. Much appreciated! – Keith.Abramo Nov 10 '11 at 22:47

2 Answers2

19

I have put together a jsFiddle which does what I think you want it to do.

http://jsfiddle.net/CqcHD/2/

It satisfies all 4 of your criteria. Let me know if I have misinterpreted your expected result

Keith.Abramo
  • 6,952
  • 2
  • 32
  • 46
  • Thanks so much. Sorry for the delay. I used your code and even deployed it in production: http://www.jungledragon.com/image/2638/caiman_in_camouflage.html/zoom It works reasonably but there is still an issue with the panning: when zoomed in, it seems I cannot pan to the outer edges of the image, it seems cropped. Any ideas? – Fer Nov 12 '11 at 15:01
  • I can't see your javascript since it is all minified so this is complete speculation, but it looks like in the act of zooming you are pushing the left part of the image out of the left boundaries of the document and it doesn't seem to want to pan past of the left boundary of the document viewport – Keith.Abramo Nov 12 '11 at 16:05
  • Ah, forgot about the minify. Here's the raw js: http://www.jungledragon.com/js/slidedragon_001.js – Fer Nov 12 '11 at 17:13
  • It looks like your css3 transformation is not playing nice with your panning algorithm. Try using jquery.animate to scale the width and height instead if possible – Keith.Abramo Nov 12 '11 at 20:42
  • thanks for thinking along. The reason I am using transitions is that they are smooth and do not pile up when giving the scrollwheel a jam. Furthermore, it respects existing layout. It looks like I pushed myself in a corner a little. – Fer Nov 12 '11 at 23:39
  • @Keith.Abramo: Can we do some sort of similar thing like in google maps where there is a circle with directions , for top , down, left, right and still move image with it? – noobie-php Sep 02 '14 at 11:43
  • @noobie-php Sure. Check out this code: http://jsfiddle.net/CqcHD/172/ Right now I just have some primitive divs for the directions but you can style the #directions container to either use one image that looks like a compass and an image map with events triggers via the image map, or take that one image and cut it into 4 images in photoshop or something and stitch it back together in the html and attach the events to each image. Hope this helps! – Keith.Abramo Sep 02 '14 at 14:27
  • @Keith.Abramo: excellent. I just wanna know what set interval does? as i cannot understand that easily, would you mind if you explain that a bit? – noobie-php Sep 02 '14 at 15:11
  • 1
    @noobie-php setInterval executes a given function continuously at an delay interval specified as the second parameter (in milliseconds). It returns an intervalID which you can use to stop the interval execution by calling clearInterval(intervalId). In the code I created it executes a function which scrolls the div every 50 miliseconds when the mousedown even fires and it clears the interval when the mouseup event fires. More info can be found here. https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers.setInterval – Keith.Abramo Sep 02 '14 at 15:39
  • This is great. is there anyway to allow this to be swipable on a smartphone. As of now it doesn't swipe, although works on a desktop. – Omar Aug 31 '16 at 19:13
  • Great, but how can I make it work in touch devices?? – Jay Patel Aug 24 '20 at 03:31
1

i have some alternative plugins for your work . try among these jquery plugins.

http://kvcodes.com/2014/02/jquery-plugins-for-containerdiv-zoom/

akelya
  • 21
  • 1