在浏览器中捕捉双指缩放
Catch pinch-zoom in browser
我有一个 Web 应用程序,基本上是一个 canvas 您可以利用的应用程序。我正在处理绘图 - 通过鼠标或单指触摸 - 效果很好。
canvas比屏幕大,我需要实现自己的缩放机制(因为我只想缩放canvas,而不是整个屏幕)。我已经向 wheel
事件添加了一个处理程序,并且我正确地处理了 Control-Wheels。现在我需要处理双指缩放。
我的 canvas 作为 track-action: pinch-zoom
CSS 设置。这样可以用两根手指滑动进行滚动,这非常好。我也想让浏览器处理双指缩放,但我想自己处理缩放逻辑(就像我使用鼠标滚轮一样)。
是否有任何方法可以捕获捏合缩放事件并覆盖缩放行为?
我在 Android 上使用 Chrome,但这种技术应该也适用于 iOS 上的 Safari。
不错的主意顺便说一句。
我在 codepen 上找到了值得你花时间的东西。我也将它剥离了一点并插入下面的片段。让我知道它是否对您有帮助。
另外,如果你想使用库,你可以尝试 hammer.js or jgestures 捏缩放手势。
var image_x = 0, image_y = 0;
var zoom = 0.5;
var mouse_x = 0, mouse_y = 0, finger_dist = 0;
var source_image_obj = new Image();
source_image_obj.addEventListener('load', function () {
reset_settings();
}, false); // Reset (x,y,zoom) when new image loads
function load_url() {
source_image_obj.src = document.getElementById("theurl").value; // load the image
}
function update_canvas() {
var mainCanvas = document.getElementById("mainCanvas");
var mainCanvasCTX = document.getElementById("mainCanvas").getContext("2d");
var canvas_w = mainCanvas.width, canvas_h = mainCanvas.height; // make things easier to read below
// Keep picture in bounds
if (image_x - (canvas_w * zoom / 2) > source_image_obj.width) image_x = source_image_obj.width + (canvas_w * zoom / 2);
if (image_y - (canvas_h * zoom / 2) > source_image_obj.height) image_y = source_image_obj.height + (canvas_h * zoom / 2);
if (image_x + (canvas_w * zoom / 2) < 0) image_x = 0 - (canvas_w * zoom / 2);
if (image_y + (canvas_h * zoom / 2) < 0) image_y = 0 - (canvas_h * zoom / 2);
// Draw the scaled image onto the canvas
mainCanvasCTX.clearRect(0, 0, canvas_w, canvas_h);
mainCanvasCTX.drawImage(source_image_obj, image_x - (canvas_w * zoom / 2), image_y - (canvas_h * zoom / 2), canvas_w * zoom, canvas_h * zoom, 0, 0, canvas_w, canvas_h);
}
function reset_settings() {
image_x = source_image_obj.width / 2;
image_y = source_image_obj.height / 2;
zoom = 1;
update_canvas(); // Draw the image in its new position
}
document.addEventListener('wheel', function (e) {
if (e.deltaY < 0) {
zoom = zoom * 1.5;
} else {
zoom = zoom / 1.5;
}
update_canvas();
}, false);
document.addEventListener('mousemove', function (e) {
if (e.buttons > 0) {
window.getSelection().empty();
image_x = image_x + zoom * (mouse_x - e.clientX);
image_y = image_y + zoom * (mouse_y - e.clientY);
}
mouse_x = e.clientX;
mouse_y = e.clientY; // Save for next time
update_canvas(); // draw the image in its new position
}, false);
function get_distance(e) {
var diffX = e.touches[0].clientX - e.touches[1].clientX;
var diffY = e.touches[0].clientY - e.touches[1].clientY;
return Math.sqrt(diffX * diffX + diffY * diffY); // Pythagorean theorem
}
document.addEventListener('touchstart', function (e) {
if (e.touches.length > 1) { // if multiple touches (pinch zooming)
finger_dist = get_distance(e); // Save current finger distance
} // Else just moving around
mouse_x = e.touches[0].clientX; // Save finger position
mouse_y = e.touches[0].clientY; //
}, false);
document.addEventListener('touchmove', function (e) {
e.preventDefault(); // Stop the window from moving
if (e.touches.length > 1) { // If pinch-zooming
var new_finger_dist = get_distance(e); // Get current distance between fingers
zoom = zoom * Math.abs(finger_dist / new_finger_dist); // Zoom is proportional to change
finger_dist = new_finger_dist; // Save current distance for next time
} else { // Else just moving around
image_x = image_x + (zoom * (mouse_x - e.touches[0].clientX)); // Move the image
image_y = image_y + (zoom * (mouse_y - e.touches[0].clientY)); //
mouse_x = e.touches[0].clientX; // Save finger position for next time
mouse_y = e.touches[0].clientY; //
}
update_canvas(); // draw the new position
}, false);
document.addEventListener('touchend', function (e) {
mouse_x = e.touches[0].clientX;
mouse_y = e.touches[0].clientY; // could be down to 1 finger, back to moving image
}, false);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
canvas {
background: #e74c3c;
border: 4px solid black;
}
.box-photo {
border: 1px dashed black;
}
.box-photo img {
width: 100%;
}
<html>
<head>
<meta charset="utf-8" />
<body onload="load_url();">
<div class="box">
<div class="box-photo">
<canvas id="mainCanvas" width="500" height="600">
<input id="theurl" value="https://mlb-s1-p.mlstatic.com/relogio-mondaine-classico-78527-original-a-prova-dagua-202101-MLB20273713546_042015-F.jpg">
Your browser does not support the HTML5 canvas tag.
</canvas>
</div>
</div>
</body>
</html>
我有一个 Web 应用程序,基本上是一个 canvas 您可以利用的应用程序。我正在处理绘图 - 通过鼠标或单指触摸 - 效果很好。
canvas比屏幕大,我需要实现自己的缩放机制(因为我只想缩放canvas,而不是整个屏幕)。我已经向 wheel
事件添加了一个处理程序,并且我正确地处理了 Control-Wheels。现在我需要处理双指缩放。
我的 canvas 作为 track-action: pinch-zoom
CSS 设置。这样可以用两根手指滑动进行滚动,这非常好。我也想让浏览器处理双指缩放,但我想自己处理缩放逻辑(就像我使用鼠标滚轮一样)。
是否有任何方法可以捕获捏合缩放事件并覆盖缩放行为?
我在 Android 上使用 Chrome,但这种技术应该也适用于 iOS 上的 Safari。
不错的主意顺便说一句。 我在 codepen 上找到了值得你花时间的东西。我也将它剥离了一点并插入下面的片段。让我知道它是否对您有帮助。 另外,如果你想使用库,你可以尝试 hammer.js or jgestures 捏缩放手势。
var image_x = 0, image_y = 0;
var zoom = 0.5;
var mouse_x = 0, mouse_y = 0, finger_dist = 0;
var source_image_obj = new Image();
source_image_obj.addEventListener('load', function () {
reset_settings();
}, false); // Reset (x,y,zoom) when new image loads
function load_url() {
source_image_obj.src = document.getElementById("theurl").value; // load the image
}
function update_canvas() {
var mainCanvas = document.getElementById("mainCanvas");
var mainCanvasCTX = document.getElementById("mainCanvas").getContext("2d");
var canvas_w = mainCanvas.width, canvas_h = mainCanvas.height; // make things easier to read below
// Keep picture in bounds
if (image_x - (canvas_w * zoom / 2) > source_image_obj.width) image_x = source_image_obj.width + (canvas_w * zoom / 2);
if (image_y - (canvas_h * zoom / 2) > source_image_obj.height) image_y = source_image_obj.height + (canvas_h * zoom / 2);
if (image_x + (canvas_w * zoom / 2) < 0) image_x = 0 - (canvas_w * zoom / 2);
if (image_y + (canvas_h * zoom / 2) < 0) image_y = 0 - (canvas_h * zoom / 2);
// Draw the scaled image onto the canvas
mainCanvasCTX.clearRect(0, 0, canvas_w, canvas_h);
mainCanvasCTX.drawImage(source_image_obj, image_x - (canvas_w * zoom / 2), image_y - (canvas_h * zoom / 2), canvas_w * zoom, canvas_h * zoom, 0, 0, canvas_w, canvas_h);
}
function reset_settings() {
image_x = source_image_obj.width / 2;
image_y = source_image_obj.height / 2;
zoom = 1;
update_canvas(); // Draw the image in its new position
}
document.addEventListener('wheel', function (e) {
if (e.deltaY < 0) {
zoom = zoom * 1.5;
} else {
zoom = zoom / 1.5;
}
update_canvas();
}, false);
document.addEventListener('mousemove', function (e) {
if (e.buttons > 0) {
window.getSelection().empty();
image_x = image_x + zoom * (mouse_x - e.clientX);
image_y = image_y + zoom * (mouse_y - e.clientY);
}
mouse_x = e.clientX;
mouse_y = e.clientY; // Save for next time
update_canvas(); // draw the image in its new position
}, false);
function get_distance(e) {
var diffX = e.touches[0].clientX - e.touches[1].clientX;
var diffY = e.touches[0].clientY - e.touches[1].clientY;
return Math.sqrt(diffX * diffX + diffY * diffY); // Pythagorean theorem
}
document.addEventListener('touchstart', function (e) {
if (e.touches.length > 1) { // if multiple touches (pinch zooming)
finger_dist = get_distance(e); // Save current finger distance
} // Else just moving around
mouse_x = e.touches[0].clientX; // Save finger position
mouse_y = e.touches[0].clientY; //
}, false);
document.addEventListener('touchmove', function (e) {
e.preventDefault(); // Stop the window from moving
if (e.touches.length > 1) { // If pinch-zooming
var new_finger_dist = get_distance(e); // Get current distance between fingers
zoom = zoom * Math.abs(finger_dist / new_finger_dist); // Zoom is proportional to change
finger_dist = new_finger_dist; // Save current distance for next time
} else { // Else just moving around
image_x = image_x + (zoom * (mouse_x - e.touches[0].clientX)); // Move the image
image_y = image_y + (zoom * (mouse_y - e.touches[0].clientY)); //
mouse_x = e.touches[0].clientX; // Save finger position for next time
mouse_y = e.touches[0].clientY; //
}
update_canvas(); // draw the new position
}, false);
document.addEventListener('touchend', function (e) {
mouse_x = e.touches[0].clientX;
mouse_y = e.touches[0].clientY; // could be down to 1 finger, back to moving image
}, false);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
canvas {
background: #e74c3c;
border: 4px solid black;
}
.box-photo {
border: 1px dashed black;
}
.box-photo img {
width: 100%;
}
<html>
<head>
<meta charset="utf-8" />
<body onload="load_url();">
<div class="box">
<div class="box-photo">
<canvas id="mainCanvas" width="500" height="600">
<input id="theurl" value="https://mlb-s1-p.mlstatic.com/relogio-mondaine-classico-78527-original-a-prova-dagua-202101-MLB20273713546_042015-F.jpg">
Your browser does not support the HTML5 canvas tag.
</canvas>
</div>
</div>
</body>
</html>