I have a web application that is basically a canvas you can draw on. I'm handling the drawing - either by mouse or by single finger touch - and it's working well.
The canvas is larger than the screen, and I need to implement my own zooming mechanism (because I only want to zoom the canvas, not the entire screen). I've added a handler to the wheel
event, and I process Control-Wheels properly. Now I need to handle pinch-zooms.
My canvas as a track-action: pinch-zoom
CSS settings. This enables two finger swipes for scrolling, which is excellent. I want to let the browser handle pinch-zooms, too, but I want to handle the zooming logic myself (like I do with the mouse wheel).
Is there any way to catch the pinch-zoom event and override the zooming behavior?
I'm using Chrome on Android, but this technique should also work with Safari on iOS.
Hold down Shift then click and move your mouse to emulate pinch zooming.
x.x, you can pinch zoom pressing 'Toggle Device toolbar' at dev tools and after hold SHIFT and click-drag your mouse. Save this answer.
Navigate to the URL chrome://flags/#enable-pinch in your browser and disable the feature.
Pinch to zoom in on content: In full screen mode, touch the video with two fingers. Move your fingers away from one another, while touching the video screen. Once you let go, the video will play at the new zoom level.
nice idea btw. i found something worth your time on codepen. also i stripped it down a little and inserted as snippet below. let me know if it helps you. additionally if you want to use library, you can try hammer.js or jgestures for pinch zooming gestures.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With