HTML5 Canvas Custom Hit Detection Function Tutorial

There are two ways to change hit region of the shape: hitFunc and hitStrokeWidth properties.

1. What is hitFunc?

To create a custom hit draw function for a shape with Konva, we can set
the hitFunc property. A hit draw function is the function that Konva
will use to draw a region used for hit detection. Using a custom draw hit
function can have several benefits, such as making the hit region larger
so that it’s easier for users to interact with a shape, making some portions
of a shape detectable and others not, or simplifying the hit draw function
in order to improve rendering performance.

Also take a look into some best practices of writing custom sceneFunc that can be used for hitFunc too.

hitFunc is a function with two arguments: Konva.Context renderer and a shape instance.

With hitFunc you have full control over drawing.

2. What is hitStrokeWidth?

For some shapes, like Konva.Line it is too hard to overwrite hitFunc. In some cases you just want to make it thicker for events. In this case it is better to use hitStrokeWidth property with a large value.

Instructions: Mouseover, mouseout, mousedown, and mouseup over the star and
observe that the hit region is an over sized circle encompassing the shape. Also try the same for a a line.
Also you can toggle hit canvas too see how it looks. It may be useful for debugging.

Konva Custom_Hit_Region Demoview raw
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/[email protected]/konva.min.js"></script>
<meta charset="utf-8" />
<title>Konva Custom Hit Function Demo</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f0f0f0;
}
button {
position: absolute;
top: 5px;
left: 5px;
z-index: 2;
}
</style>
</head>

<body>
<button id="toggle">Toggle hit canvas</button>
<div id="container"></div>
<script>
function writeMessage(message) {
text.text(message);
}

var stage = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight,
});

var layer = new Konva.Layer();
stage.add(layer);

var text = new Konva.Text({
x: 10,
y: 30,
fontSize: 24,
fill: 'black',
});
layer.add(text);

var star = new Konva.Star({
x: stage.width() / 2,
y: stage.height() / 2,
numPoints: 7,
innerRadius: 50,
outerRadius: 70,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
hitFunc: function (context) {
context.beginPath();
context.arc(0, 0, this.outerRadius() + 10, 0, Math.PI * 2, true);
context.closePath();
context.fillStrokeShape(this);
},
});
layer.add(star);

var line = new Konva.Line({
x: 50,
y: 100,
points: [0, 0, 50, 0, 50, 100, 0, 100],
tension: 1,
strokeWidth: 1,
hitStrokeWidth: 20,
stroke: 'black',
});
layer.add(line);

star.on('mouseover', function () {
writeMessage('Mouseover star');
});
star.on('mouseout', function () {
writeMessage('Mouseout star');
});
star.on('mousedown', function () {
writeMessage('Mousedown star');
});
star.on('mouseup', function () {
writeMessage('Mouseup star');
});

line.on('mouseover', function () {
writeMessage('Mouseover line');
});
line.on('mouseout', function () {
writeMessage('Mouseout line');
});
line.on('mousedown', function () {
writeMessage('Mousedown line');
});
line.on('mouseup', function () {
writeMessage('Mouseup line');
});

document.getElementById('toggle').addEventListener('click', function () {
layer.toggleHitCanvas();
});
</script>
</body>
</html>
Enjoying Konva? Please consider to support the project.