我想在平移时限制图像的边界,因此,从左向右平移时图像的左侧不应超出容器的左边缘,并且图像的右边缘不应超出容器的右侧从右向左平移时的容器。在较小的规模下,代码中的边界条件有效,但在较大的规模下,边界条件不起作用,我无法弄清楚问题出在哪里。
// ------------------- Zoom and pan the image ------------------------------
var scale = 1,
panning = false,
pointX = 0,
pointY = 0,
mid_x = 0,
mid_y = 0,
start = { x: 0, y: 0 },
zoommap = document.getElementById("immagine");
let newPointX, newPointY;
// Mouse down || touchstart
((zoommap, event_names, zoom_start) => {
event_names.forEach( (event_name) => {
zoommap.addEventListener(event_name, zoom_start)
})
})(zoommap, ['mousedown', 'touchstart'], (e) => {
e.preventDefault();
panning = true;
if (e.type == 'mousedown'){
start = { x: e.clientX - pointX, y: e.clientY - pointY };
}
else if (e.type == 'touchstart'){
if (e.touches.length === 1){
start = { x: e.touches[0].clientX - pointX, y: e.touches[0].clientY - pointY};
} else if (e.touches.length === 2){
start = { x: (e.touches[0].clientX + e.touches[1].clientX) / 2 - pointX,
y: (e.touches[0].clientY + e.touches[1].clientY) / 2 - pointY,
dist: Math.hypot(e.touches[0].clientX - e.touches[1].clientX, e.touches[0].clientY - e.touches[1].clientY)
};
}
}
});
// Mouse up || touchend
((zoommap, event_names, zoom_end) => {
event_names.forEach( (event_name) => {
zoommap.addEventListener(event_name, zoom_end)
})
})(zoommap, ['mouseup', 'touchend', 'touchcancel'], (e) => {
panning = false;
});
// Mouse move || touchmove || Panning the image
((zoommap, event_names, zoom_end) => {
event_names.forEach( (event_name) => {
zoommap.addEventListener(event_name, zoom_end)
})
})(zoommap, ['mousemove', 'touchmove'], (e) => {
e.preventDefault();
if (!panning || scale === 1) {
return;
}
if (e.type == 'mousemove'){
newPointY = (e.clientY - start.y);
newPointX = (e.clientX - start.x);
} else if (e.type == 'touchmove'){
if (e.touches.length === 1){
newPointX = (e.touches[0].clientX - start.x);
newPointY = (e.touches[0].clientY - start.y);
}
}
var mapimg_div = document.getElementById("mapimg");
const map_dim = mapimg_div.getBoundingClientRect();
const img_dim = zoommap.getBoundingClientRect();
console.log(scale)
// Calculate the maximum allowed positions
const maxX = map_dim.left + (img_dim.width * scale - map_dim.width)/scale - map_dim.right;
const maxY = map_dim.top + (img_dim.height * scale - map_dim.bottom)/scale - map_dim.height;
const minX = map_dim.right - img_dim.width*scale - map_dim.left + map_dim.width; // Adjusted to allow intersection
const minY = map_dim.bottom - img_dim.height*scale - map_dim.top + map_dim.height; // Adjusted to allow intersection
// Clamp the new positions to stay within the boundaries
if (newPointX > maxX) {
newPointX = maxX;
} else if (newPointX < minX) {
newPointX = minX;
}
if (newPointY > maxY) {
newPointY = maxY;
} else if (newPointY < minY) {
newPointY = minY;
}
// Update pointX and pointY with the new values
pointX = newPointX;
pointY = newPointY;
zoommap.style.transform = "translate(" + pointX + "px, " + pointY + "px) scale(" + scale + ")";
});
//Zooming functionality
((zoommap, event_names, zoom_move) => {
event_names.forEach( (event_name) => {
zoommap.addEventListener(event_name, zoom_move)
})
})(zoommap, ['mousewheel', 'touchmove'], (e) => {
e.preventDefault();
zoommap.style.transform = "none";
var img_dim = zoommap.getBoundingClientRect();
if (e.type == 'mousewheel'){
var x = ((img_dim.width - (img_dim.right- e.clientX ))/img_dim.width) * 100; //x position within the img element
var y = ((img_dim.height - (img_dim.bottom- e.clientY))/img_dim.height) * 100; //y position within the img element
zoommap.style.transformOrigin = x + "% " + y + "%";
var delta = (e.wheelDelta ? e.wheelDelta : -e.deltaY);
(delta > 0) ? (scale *= 1.2) : (scale /= 1.2);
} else if (e.type == 'touchmove'){
if (e.touches.length == 2){
if (e.scale) {
scale = e.scale;
} else {
var move_dist = Math.hypot(e.touches[0].clientX - e.touches[1].clientX, e.touches[0].clientY - e.touches[1].clientY);
(move_dist > start.dist) ? (scale *= 1.01) : (scale /= 1.01);
}
// Calculate how much the fingers have moved on the X and Y axis
var x = ((img_dim.width - (img_dim.right- mid_x ))/img_dim.width) * 100;
var y = ((img_dim.height - (img_dim.bottom- mid_y))/img_dim.height) * 100;
zoommap.style.transformOrigin = x + "% " + y + "%";
mid_x = ( + e.touches[1].clientX) / 2
mid_y = (e.touches[0].clientY + e.touches[1].clientY) / 2
pointX = (mid_x - start.x);
pointY = (mid_y - start.y);
}
}
scale = Math.min(Math.max(1, scale), 20);
pointX = 0;
pointY = 0;
zoommap.style.transform = "scale(" + scale + ") translate(" + pointX + "px, " + pointY + "px)";
});
试试这个代码:
((zoommap, event_names, zoom_move) => {
event_names.forEach((event_name) => {
zoommap.addEventListener(event_name, zoom_move)
})
})(zoommap, ['mousemove', 'touchmove'], (e) => {
e.preventDefault();
if (!panning || scale === 1) {
return;
}
if (e.type == 'mousemove') {
newPointY = (e.clientY - start.y);
newPointX = (e.clientX - start.x);
} else if (e.type == 'touchmove') {
if (e.touches.length === 1) {
newPointX = (e.touches[0].clientX - start.x);
newPointY = (e.touches[0].clientY - start.y);
}
}
var mapimg_div = document.getElementById("mapimg");
const map_dim = mapimg_div.getBoundingClientRect();
const img_dim = zoommap.getBoundingClientRect();
const maxX = map_dim.left;
const maxY = map_dim.top;
const minX = map_dim.right - img_dim.width * scale;
const minY = map_dim.bottom - img_dim.height * scale;
if (newPointX > maxX) {
newPointX = maxX;
} else if (newPointX < minX) {
newPointX = minX;
}
if (newPointY > maxY) {
newPointY = maxY;
} else if (newPointY < minY) {
newPointY = minY;
}
// Update pointX and pointY with the new values
pointX = newPointX;
pointY = newPointY;
zoommap.style.transform = "translate(" + pointX + "px, " + pointY + "px) scale(" + scale + ")";
});
现在试试这个
var scale = 1,
panning = false,
pointX = 0,
pointY = 0,
mid_x = 0,
mid_y = 0,
start = { x: 0, y: 0 },
zoommap = document.getElementById("immagine");
let newPointX, newPointY;
((zoommap, event_names, zoom_start) => {
event_names.forEach((event_name) => {
zoommap.addEventListener(event_name, zoom_start);
});
})(zoommap, ['mousedown', 'touchstart'], (e) => {
e.preventDefault();
panning = true;
if (e.type == 'mousedown') {
start = { x: e.clientX - pointX, y: e.clientY - pointY };
} else if (e.type == 'touchstart') {
if (e.touches.length === 1) {
start = { x: e.touches[0].clientX - pointX, y: e.touches[0].clientY - pointY };
} else if (e.touches.length === 2) {
start = {
x: (e.touches[0].clientX + e.touches[1].clientX) / 2 - pointX,
y: (e.touches[0].clientY + e.touches[1].clientY) / 2 - pointY,
dist: Math.hypot(e.touches[0].clientX - e.touches[1].clientX, e.touches[0].clientY - e.touches[1].clientY)
};
}
}
});
((zoommap, event_names, zoom_end) => {
event_names.forEach((event_name) => {
zoommap.addEventListener(event_name, zoom_end);
});
})(zoommap, ['mouseup', 'touchend', 'touchcancel'], (e) => {
panning = false;
});
((zoommap, event_names, zoom_end) => {
event_names.forEach((event_name) => {
zoommap.addEventListener(event_name, zoom_end);
});
})(zoommap, ['mousemove', 'touchmove'], (e) => {
e.preventDefault();
if (!panning || scale === 1) {
return;
}
if (e.type == 'mousemove') {
newPointY = (e.clientY - start.y);
newPointX = (e.clientX - start.x);
} else if (e.type == 'touchmove') {
if (e.touches.length === 1) {
newPointX = (e.touches[0].clientX - start.x);
newPointY = (e.touches[0].clientY - start.y);
}
}
var mapimg_div = document.getElementById("mapimg");
const map_dim = mapimg_div.getBoundingClientRect();
const img_dim = zoommap.getBoundingClientRect();
const maxX = map_dim.left;
const maxY = map_dim.top;
const minX = map_dim.right - img_dim.width * scale;
const minY = map_dim.bottom - img_dim.height * scale;
if (newPointX > maxX) {
newPointX = maxX;
} else if (newPointX < minX) {
newPointX = minX;
}
if (newPointY > maxY) {
newPointY = maxY;
} else if (newPointY < minY) {
newPointY = minY;
}
pointX = newPointX;
pointY = newPointY;
zoommap.style.transform = "translate(" + pointX + "px, " + pointY + "px) scale(" + scale + ")";
});
((zoommap, event_names, zoom_move) => {
event_names.forEach((event_name) => {
zoommap.addEventListener(event_name, zoom_move);
});
})(zoommap, ['mousewheel', 'touchmove'], (e) => {
e.preventDefault();
zoommap.style.transform = "none";
var img_dim = zoommap.getBoundingClientRect();
if (e.type == 'mousewheel') {
var x = ((img_dim.width - (img_dim.right - e.clientX)) / img_dim.width) * 100;
var y = ((img_dim.height - (img_dim.bottom - e.clientY)) / img_dim.height) * 100;
zoommap.style.transformOrigin = x + "% " + y + "%";
var delta = (e.wheelDelta ? e.wheelDelta : -e.deltaY);
(delta > 0) ? (scale *= 1.2) : (scale /= 1.2);
} else if (e.type == 'touchmove') {
if (e.touches.length == 2) {
if (e.scale) {
scale = e.scale;
} else {
var move_dist = Math.hypot(e.touches[0].clientX - e.touches[1].clientX, e.touches[0].clientY - e.touches[1].clientY);
(move_dist > start.dist) ? (scale *= 1.01) : (scale /= 1.01);
}
var x = ((img_dim.width - (img_dim.right - mid_x)) / img_dim.width) * 100;
var y = ((img_dim.height - (img_dim.bottom - mid_y)) / img_dim.height) * 100;
zoommap.style.transformOrigin = x + "% " + y + "%";
mid_x = (e.touches[0].clientX + e.touches[1].clientX) / 2;
mid_y = (e.touches[0].clientY + e.touches[1].clientY) / 2;
pointX = (mid_x - start.x);
pointY = (mid_y - start.y);
}
}
scale = Math.min(Math.max(1, scale), 20);
pointX = pointX * scale;
pointY = pointY * scale;
zoommap.style.transform = "scale(" + scale + ") translate(" + pointX + "px, " + pointY + "px)";
});