I have an HTML canvas with some content. This content needs to be draw translated to the canvas. That is working. But now I need to detect which object is clicked, so I need to search in the coordinates of the objects to find an matching one. But since the objects are drawn at a different x, y position then known I don't know how to match them.
I have created this fiddle with the situation. I want to highlight the correct object when clicked. One thing to keep in mind is that this canvas is used in an environment (HMI screen connected with PLC) where I don't have the full functions which are normally available in a browser. That means also that I only get an x and y coordinate on the 'onClick' function.
https://jsfiddle.net/gkho89wd/
This code is not the cleanest but I use this to try some things. Quick explanation of this code:
I have an array with some objects (boxes)
const rawPositions = [];
every position has some properties including x and y, width and length. Those are used to draw some rects on the canvas. I also calculate an 'ratioX' and 'ratioY' to scale everything. Those x and y are used to actually draw.
Before I draw the rects, I'm doing an 'setTransform' to horizontally flip the canvas:
ctx.setTransform(1, 0, 0, 1, 0, ctx.height);
How can I translate the coordinates from the click event to the 'original' ones?
You can update the findShape function to take into account the transformation applied to the canvas. You should flip the y coordinate back and then use that to search for the clicked object.
async function findShape(oX, oY) {
console.log('findShape', oX, oY)
// Flip the y coordinate back to match the transformed canvas
const flippedY = ctx.height - oY;
const clickedBox = placedCarton.findIndex(b => {
return (b.ratioX <= oX) && (b.ratioX + b.width >= oX) &&
(b.ratioY <= flippedY) && (b.ratioY + b.length >= flippedY);
});
moveArrows = [];
positions = [];
if (clickedBox >= 0) {
placedCarton.forEach(b => b.active = false);
placedCarton[clickedBox].active = true;
activeBox = clickedBox;
updateCartonCanvas();
const box = placedCarton[clickedBox];
await window.savePositions();
const prePos = window.prePos;
const postPos = window.postPos;
} else {
console.log('no box found');
}
}
This modification takes into account the fact that the canvas is flipped vertically. By flipping the y coordinate back (using ctx.height - oY), you can now correctly detect which object is clicked.