Reputation: 3784
I have an HTML file with the following responsive definition:
<html>
<head>
<meta name="viewport" content="width=device-width, user-scalable=no">
</head>
<body>
<img class="img"
src="https://stmed.net/sites/default/files/cube-wallpapers-25187-9698686.jpg" />
</body>
</html>
With this CSS:
body {
margin: 0;
padding: 0;
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column
}
.img {
width: 80vw;
margin: 10px auto;
}
Full working example in: jsfiddle.
In my scenario the user cannot apply zoom to my page, which is good.
However, I want to allow the user to use a "pinch zoom" only in my image tag.
To be clear, I want that the size of the box of the image stays the same but the image get zoom. Of course part of the image will be hidden by the box (like overflow auto does).
Can I achieve that with only HTML and CSS (preferably without js)?
Upvotes: 4
Views: 1613
Reputation: 96596
This is impossible without Javascript. Even with Javascript it's pretty hard to figure out how to do it! If you google "pinch zoom mdn" it will take you to Pinch Zoom Gestures which tries to use pointerdown
, pointermove
and pointerup
to implement pinch to zoom itself in Javascript. Their example is here and if you have a play with it you will find that it doesn't work at all.
The issue is that it tries to implement pinch to zoom itself, rather than having the browser/OS do it properly, and send the zoom result to the web page, which is obviously the sane way to do it.
In the end I couldn't find any answers about people doing this at all, so I looked at how Google Maps does it - they simply use the wheel
event!
It turns out when browsers detect a two finger pan they send it as a wheel
event (with deltaX
and deltaY
). And if they detect a pinch zoom they send a wheel
event with event.ctrlKey
and deltaY
set.
Here's an example (I know this isn't exactly what you're looking for but if I ask a different question it will just get closed as a duplicate of this one, sorry).
let x = 250;
let y = 250;
let s = 10;
function redraw() {
const c = document.getElementById("can");
const ctx = c.getContext("2d");
ctx.fillStyle = 'grey';
ctx.fillRect(0, 0, c.width, c.height);
ctx.fillStyle = 'red';
ctx.fillRect(x-s, y-s, 2*s, 2*s);
}
function init() {
const c = document.getElementById("can");
c.addEventListener("wheel", (event) => {
// preventDefault() is necessary to stop the browser zooming.
event.preventDefault();
if (event.ctrlKey) {
s -= event.deltaY;
s = Math.min(Math.max(s, 5), 100);
} else {
x += event.deltaX;
y += event.deltaY;
x = Math.min(Math.max(x, 10), 490);
y = Math.min(Math.max(y, 10), 490);
}
redraw();
});
redraw();
}
init();
<canvas width="500" height="500" id="can"></canvas>
Upvotes: 3