使用 Konvajs,我需要拖动另一个对象下方的对象而不将底部对象带到顶部,顶部对象不可拖动。
将不胜感激任何帮助,谢谢。
需要检测堆叠对象中的点击是一项常见要求。幸运的是,Konva 让这一切变得简单。默认情况下,每个形状都会“监听”事件。因此,我们可以使用鼠标悬停、鼠标退出、单击、双击以及它们的触摸对应物(请参阅文档)。
在您的情况下,您需要使堆栈上方的形状停止收听,以便更下方的形状可以听到它。
在下面的示例中,我使用了 shape.listening(value) 属性,该属性控制形状是否正在侦听事件(真值)(假值)。
查看代码片段,如果我们点击绿色点(矩形重叠的地方),上面的形状设置监听(假)事件通过它传递到堆栈中的下一个形状,我们被告知点击是在下面的形状上. 使用上部形状监听(真)上部形状接收并吃掉事件。
我还使用了一种有效的事件检测方法,即侦听图层上的事件,而不是为每个形状设置侦听器。在图层上有几个形状的情况下,每个形状使用事件侦听器不会成为问题,但是当图层上有数百个形状时,它会影响性能。
当然,将侦听器委托给图层需要识别单击了哪个形状。为此,我可以使用逻辑来匹配形状名称。
// when the user starts to drag shape...
layer.on('click', function(evt) {
if (evt.target.hasName('upperRect')) {
alert('Click on upperRect');
}
if (evt.target.hasName('lowerRect')) {
alert('Click on upperRect');
}
...
})
但由于我在这里需要做的就是显示点击形状的名称,所以我选择简单地使用
// when the user starts to drag shape...
layer.on('click', function(evt) {
showEvent('Click on ' + evt.target.name());
})
最后值得注意的是,获取单击形状的另一种方法是使用layer.getIntersection()方法,该方法需要一个点参数,并将返回该点上图层上的第一个形状(不是形状列表!) .
layer.on("click", function() { var target = layer.getIntersection(stage.getPointerPosition()); if (target) { alert('clicked on ' + target.name()); } });
额外说明: layer.on('click') 不会检测对图层空白部分的点击。
// Set up a stage
stage = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight
}),
// add a layer to draw on
layer = new Konva.Layer(),
// make the lower rect
rectLower = new Konva.Rect({
name: 'Lower rect',
x: 40,
y: 20,
width: 100,
height: 40,
stroke: 'cyan',
fill: 'cyan',
fillEnabled: true
}),
// Make the upper rect
rectUpper = rectLower.clone({
name: 'Upper rect',
stroke: 'magenta',
fill: 'magenta',
x: 0,
y: 0
}),
// add a click target for user
spot = new Konva.Circle({
x: 80,
y: 30,
fill: 'lime',
radius: 10,
listening: false
});
// Add the layer to the stage and shapes to layer
stage.add(layer);
layer.add(rectLower, rectUpper, spot)
// when the user clicks a shape...
layer.on('click', function(evt) {
showEvent('Click on ' + evt.target.name());
})
// Start / stop listening for events on to rect when checkbox changes.
$('#upperListening').on('change', function(){
switch ($(this).is(':checked')){
case true:
rectUpper.listening(true);
showEvent('Upper rect <b>is</b> listening...');
break;
case false:
rectUpper.listening(false);
showEvent('Upper rect <b>is not</b> listening...');
break;
}
// Important - if we change lsitening shapes we have to refresh hit checking list.
layer.drawHit();
})
stage.draw();
function showEvent(msg){
$('#info').html(msg)
}
body {
margin: 10;
padding: 10;
overflow: hidden;
background-color: #f0f0f0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://unpkg.com/konva@^3/konva.min.js"></script>
<p>Click the green dot. Watch the events. Click the tickbox to stop upper rect catching events.</p>
<p><input type='checkbox' id='upperListening' checked='checked' ><label for='upperListening'>Upper is listening</label>
<p id='info'>Events show here</p>
<div id="container"></div>