I'm trying to do somewhat of a "zoom"-funktion (loads bigger images) in jQuery while being able to drag around in the images (.draggable) in a smaller div. But I've hit a slight problem.
When I reach to the maximum zoom (lets say third image, which is around 300px+ in height and 1600px+ in width than the first) and then place myself in the bottom right corner and then start to zoom out: I'm then stuck in that corner while I see the image itself turns smaller and giving me a white empty space, and the image is after that undraggable (so to speak).
But if I then add .css({'left': '0px', 'top': '0px'}) to the images I'm replacing I fly back to top-left and I can drag around all I want. But clearly I want to stay at the place that I want to zoom into.
If I change (code lower in post) "containment: [data]" to "containment: "parent" I'm able to "stay" in the certain area I've zoomed in and zoomed out from, but I still get the white empty area when I'm down into a corner (but I'm able to drag in the picture again) and with the cost that it's not the smooth panorama-feeling anymore, more like it snaps to the edges.
Is there some kind of easy way to go around this? And is this a good solution to my kind of problem anyways, or is there better ways to achieve this kind of stuff. I've tried using .animate() and make one picture larger, but in the end I get the same problem.
<div id="map"> // 900px in width and 300px in height and Overflow: hidden in css to keep larger images inside
<img id="map-image" src="images/hogf_zoom0.jpg" /> // same as #map until zoom1.jpg wich is slightly larger
</div>
<div id="zoomPanel">
<a href="#" class="zoomIn">+</a>
<a href="#" class="zoomOut">-</a>
</div>
-
var zoom = 0;
var maxZoom = 3;
$('.zoomIn').click(function() {
if (zoom >= 0 && zoom < maxZoom) {
zoom++;
$("#map-image").attr("src", "images/hogf_zoom" + zoom + ".jpg").css({'top': '-0px','left': '0px'});
if (zoom > 0) { $("#zoomPanel .zoomOut").show(); }
}
});
$('.zoomOut').click(function() {
if (zoom <= maxZoom && zoom > 0) {
zoom--;
$("#map-image").attr("src", "images/hogf_zoom" + zoom + ".jpg").css({'top': '-0px','left': '0px'});
if (zoom == 0) { $("#zoomPanel .zoomOut").hide(); }
}
});
$('#map img').load(function() {
var mapWidth = $("#map").width();
var mapHeight = $("#map").height();
var imgPos = $("#map-image").offset();
var mapPos = $("#map").offset();
var imgWidth = $("#map-image").width();
var imgHeight = $("#map-image").height();
var x1 = ((1 + mapWidth) - imgWidth) + mapPos.left;
var y1 = (11 + mapHeight) - imgHeight;
var x2 = imgPos.left;
var y2 = imgPos.top;
$("#map img").draggable({
containment: [x1,y1,x2,y2],
cursor: 'move'
});
});
Thanks for any kind of input.
As ordered, a demo: http://miyao.eu/zoomzoom/
It took me a bit, but if you save the center position of the image and translate that to the next image you get a relatively good result. I had to also check the resulting position to make sure it's inside the view port.
I changed the zoom links into buttons to make it easier to click.
Here is a demo.
$(document).ready(function() {
var zoom = 0,
maxZoom = 2,
last = [],
$img = $('#map-image'),
$map = $('#map'),
map = [$map.offset().left, $map.offset().top, $map.width(), $map.height()],
getDim = function() {
var w = $img.width(),
h = $img.height(),
x = $img.offset().left - map[0],
y = $img.offset().top - map[1];
// save dimensions & calculate % image middle
return [x, y, w, h, -(x - map[2] / 2) / w, -(y - map[3] / 2) / h];
};
$('.zoomIn').click(function(){
if (zoom >= 0 && zoom < maxZoom) {
zoom++;
last = getDim();
$("#map-image").attr("src", "zoom" + zoom + ".jpg");
if (zoom > 0) {
$("#zoomPanel .zoomOut").removeAttr('disabled');
}
if (zoom === maxZoom) {
$('#zoomPanel .zoomIn').attr('disabled', 'disabled');
}
}
});
$('.zoomOut').click(function(){
if (zoom <= maxZoom && zoom > 0) {
zoom--;
last = getDim();
$("#map-image").attr("src", "zoom" + zoom + ".jpg");
if (zoom === 0) {
$("#zoomPanel .zoomOut").attr('disabled', 'disabled');
}
}
$('#zoomPanel .zoomIn').removeAttr('disabled');
});
// Load image and make it panoramable
$img.load(function(){
var size = getDim(),
// calculate new postion from previous center
x = Math.round(-size[2] * last[4] + map[2] / 2),
y = Math.round(-size[3] * last[5] + map[3] / 2);
$img
.css({
left: (-x + map[2] > size[2]) ? map[2] - size[2] : (x > 0) ? 0 : x, // check ranges
top: (-y + map[3] > size[3]) ? map[3] - size[3] : (y > 0) ? 0 : y
})
.draggable({
containment: [map[0] + map[2] - size[2], map[1] + map[3] - size[3], map[0], map[1]],
cursor: 'move'
});
});
});