0

使用 Konvajs,我需要拖动另一个对象下方的对象而不将底部对象带到顶部,顶部对象不可拖动。

将不胜感激任何帮助,谢谢。

4

1 回答 1

0

需要检测堆叠对象中的点击是一项常见要求。幸运的是,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>

于 2020-12-19T14:25:36.960 回答