I have an image. for this i would like to get the touch events start, move and end. I need the exact image-pixel of the touch.
The Problem is that the actual image is smaller than the HTMLImageElement.
(css style object-fit: scale-down
)
I don't need the touch events for the HTMLImageElement but the actual image itself.
How do I archive this?
btw. I use React (if this helps) but I can (hopefully) adapt the answer myself.
Current Attempt:
<img ...
onTouchStart={(event) => {
const touch = event.changedTouches[0];
const rect = event.currentTarget.getBoundingClientRect();
const pxlX = touch.screenX - rect.left;
const pxlY = touch.screenY - rect.top;
// other stuff with (pxlX, pxlY)
}} />
My Solution in the end
import { useState } from "react";
import ImageSrc from "./assets/image.png";
export default function App() {
const [text, setText] = useState("undefined");
return <div className="w-screen h-screen overflow-hidden">
<img src={ImageSrc} alt="" className="object-scale-down w-full h-full" onMouseMove={(event) => {
const {x, y} = getXY(event);
setText(`${x}/${y}`);
}} />
<span className="fixed top-0 left-0 pointer-events-none">{text}</span>
</div>;
}
function getXY(event: React.MouseEvent<HTMLImageElement, MouseEvent>): {x: number, y: number} {
const img = event.currentTarget;
const [imgWidth, imgHeight] = [img.naturalWidth, img.naturalHeight];
const [boxWidth, boxHeight] = [img.width, img.height];
const imgRatio = imgWidth / imgHeight;
const boxRatio = boxWidth / boxHeight;
if (imgRatio < boxRatio) {
const x0 = (boxWidth - boxHeight * imgWidth/imgHeight) / 2;
const x = Math.round(event.nativeEvent.offsetX - x0);
return {x: x, y: event.nativeEvent.offsetY};
} else {
const y0 = (boxHeight - boxWidth * imgHeight/imgWidth) / 2;
const y = Math.round(event.nativeEvent.offsetY - y0);
return {x: event.nativeEvent.offsetX, y: y};
}
}