-1

I am trying to change my canvas by transforming it. I turn it upside down using scale(-1,-1). But the clickable areas inside the canvas are not affected by this transform. There are no answers to this problem by Google. I think its really weird. Could someone explain why? And possibly give a workaround to this issue.

Here is a fiddle. I came across this one while researching my issue. Try transforming it with a CSS rule like transform:scale(-1,-1);. The clickable areas get screwed up even though the code clearly picks the pixel (being clicked on) from the canvas.

Bharath
  • 96
  • 6
  • 1
    Clickable areas on canvas are programmed, if you change your canvas but don't apply the same effect to the code that manages the clickable areas, don't expect CSS to do the work for you, they are separate things. – Bardo Nov 04 '16 at 08:59

1 Answers1

1

If it is only scale then just transform the mouse by the same.

mouse.x = ?
mouse.y = ?
var scalex = -1;
var scaley = -1;
mouse.tx = mouse.x * scalex;
mouse.ty = mouse.y * scaley;

But I am guessing you also move the image you are drawing so you can see it.

So you may have done something like

var drawImage(image,-200,-200); // move image back onto the canvas

You will have to do the same to the mouse (scale and translate). When you do the reverse of a transform you do it reverse direction. So when you scale then translate, you invert it by translating, then scale.

var box = {  // a hit region in normal screen coordinates.
    x : 20,
    y : 20,
    w : 60,
    h : 60,
}
// the mouse 
mouse.x = ?
mouse.y = ?
// the scale on translations so you can see the box
var scalex = -1;
var scaley = -1;
var originx = -200;
var originy = -200;

// transform the mouse screen coords into transformed canvas space
mouse.tx = mouse.x + orginx;  // translate first
mouse.ty = mouse.y + orginy;
mouse.tx *= scalex;   // then scale
mouse.ty *= scaley;

// draw the transformed image/box/whatever
ctx.scale(scalex,scaley);
ctx.translate(originx,originy);
ctx.strokeRect(box.x,box.y,box.w,box.h);  // draw the back to front box

// is the mouse over the hit region and hence the box
if(mouse.tx > box.x && mouse.tx < box.x + box.w && mouse.ty > box.y && mouse.ty < box.y + box.h){
    ctx.fillStyle = "red"
    ctx.fillRect(box.x,box.y,box.w,box.h);
}

That is the simple version that only has scale and translate and will work for all scales and translations as long as you do not rotate it. If you rotate you need to do the full inversion. You can find how to do that at this question HTML Canvas, mouse position after scale and translate

Community
  • 1
  • 1
Blindman67
  • 51,134
  • 11
  • 73
  • 136
  • Could you use the fiddle I've linked above and implement this? I would try myself, but I've no clue how to get/set `tx` and `ty`. Thanks. – Bharath Nov 04 '16 at 20:28
  • @Bharath The fiddle you linked uses the canvas pixel alpha value to workout if the land is clicked or not. It will work no matter how you transform the image. The `mouse.` is just an arbitrary object to hold the mouse coordinates. Just remove `mouse.` and set `x`, `y` to the mouse coordinate you get in your mousemove event and set `tx`,`ty` as shown in answer. Without the actual code you have the problem with we are really only guessing at a solution – Blindman67 Nov 04 '16 at 23:08