williwaw
williwaw

Reputation: 83

Why doesn't fillRect command allow to create a hit region while a combination of rect and fill does?

I have stumbled upon this issue while working with CanvasRenderingContext2D.addHitRegion() and I am trying to undestand whether it's an expected behaviour and, if yes, what is the reasoning behind this.

Here is my working JSFIDDLE where I created a canvas with hit regions and can display the id of clicked region.

Here is how I added hit regions:

ctx.beginPath();
ctx.rect(0, i, canvasWidth, itemHeight);
ctx.fill();
ctx.addHitRegion({'id': count, 'cursor': 'pointer'});

And here is the same example with only one small change (and that's how I tried to do this initially - why use 2 commands when I can use one to do the same?)

ctx.fillRect(0, i, canvasWidth, itemHeight);
ctx.addHitRegion({'id': count, 'cursor': 'pointer'});

Unfortunately, it doesn't work, as shown in this JSFIDDLE

The console displays the following error:

Uncaught NotSupportedError: Failed to execute 'addHitRegion' on 'CanvasRenderingContext2D': The specified path has no pixels.

So it seems like in order to create hit region, you cannot use fillRect command - and I can't find any explanation to this behaviour.

Will be glad to hear any ideas!

Upvotes: 1

Views: 284

Answers (1)

GameAlchemist
GameAlchemist

Reputation: 19294

fillRect is one of the direct commands of the Context2D : it creates a path 'behind the scene' and fills it instantly.
Meaning it doesn't build a path like rect does, when the hit region requires a path.
Notice that you don't need to fill it, so do it only if you need to.

As a side remark, the browser support for hit region is not that good, as you can see here : https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/addHitRegion, it is still experimental, so check this out if you want/require a wide support.

As @MarkE quoted, a safe way to implement hit regions is to handle the mouse by yourself (getBoundingClientRect is your friend !), your path collection, and to check the coordinates using isPointInPath.
Mind, again, that isPointInPath expects a path, so it won't work for direct commands (fillXXX / strokeXXX / ImageData stuff).

Upvotes: 1

Related Questions