HTML5 Canvas 自定义命中检测函数教程

有两种方式可以改变形状的命中区域:hitFunchitStrokeWidth 属性。

1. 什么是 hitFunc

为了为 Konva 中的形状创建自定义的命中绘制函数,我们可以设置 hitFunc 属性。命中绘制函数是 Konva 用于绘制用于命中检测的区域的函数。使用自定义绘制命中函数可以带来几个好处,例如使命中区域更大,以便用户更容易与形状交互,使形状的某些部分可检测而其他部分不可检测,或简化命中绘制函数以提高渲染性能。

同时,也可以查看一些 最佳实践,编写可以用于 hitFunc 的自定义 sceneFunc

hitFunc 是一个具有两个参数的函数:Konva.Context 渲染器和形状实例。

使用 hitFunc 您可以完全控制绘制过程。

2. 什么是 hitStrokeWidth

对于某些形状,例如 Konva.Line,覆盖 hitFunc 是非常困难的。在某些情况下,您只是想使其在事件中变得更厚。在这种情况下,最好使用大值的 hitStrokeWidth 属性。

说明:将鼠标移到星形上、移出、按下和抬起鼠标,并观察命中区域是一个超大圆形,包围着形状。对于一条线,也尝试同样的操作。
您还可以切换命中画布,以查看其外观。这可能对调试很有用。

Konva Custom_Hit_Region Demoview raw
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/konva@9.3.18/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>