首页 > 解决方案 > 如何在形状的边缘/边框/描边部分进行鼠标点击测试

问题描述

在我的应用程序中,我需要在形状的边缘/边框/描边部分检测鼠标事件 - 但不是在填充部分。我还没有找到一种方法来做到这一点。

我不知道如何开始,但这里是我正在尝试做的伪代码。

shape.on('mousemove', function () {
          if (mouse on the edge of the shape) {
             // change the cursor to a star
          } else {
            // do nothing
          }
        });

标签: javascriptkonvajs

解决方案


要仅检测形状边缘的鼠标点击,请使用fillEnabled:false属性。这样做是告诉 Konva 忽略填充 - 这意味着形状的填充部分上的任何事件侦听都将被关闭。然而,强大的力量伴随着巨大的责任而来,而 fillEnabled 属性也会停止您可能想要出现的任何视觉填充。

综上所述,如果您只想对形状的笔划部分进行命中测试,则需要在可视形状顶部绘制另一个透明形状来检测鼠标事件。

作为奖励,您可以使用hitStrokeWidth属性使笔划的命中检测区域更宽 - 就好像您将笔划设置为“更粗”以用于鼠标检测一样。

下面的片段显示了这种在矩形和随机多边形上的方法。

// 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(),

  rect = new Konva.Rect({
    name: 'r1',
    x: 220,
    y: 20,
    width: 100,
    height: 40,
    stroke: 'cyan',
    fill: 'transparent',
    fillEnabled: false
  }),
  poly = new Konva.Line({
    points: [23, 20, 23, 160, 70, 93, 150, 109, 290, 139, 270, 93],
    fill: '#00D2FF',
    stroke: 'black',
    strokeWidth: 5,
    closed: true,
    fillEnabled: false,
    hitStrokeWidth: 10
  });


// Add the layer to the stage
stage.add(layer);
layer.add(rect, poly)

stage.draw();

rect.on('mouseover', function() {
  $('#info').html('Rect MouseEnter')
})

rect.on('mouseout', function() {
  $('#info').html('Rect mouseOut')
})

poly.on('mouseover', function() {
  $('#info').html('Poly MouseEnter')
})

poly.on('mouseout', function() {
  $('#info').html('Poly mouseOut')
})
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>Move mouse over the shapes </p>
<p id='info'>Events show here</p>
<div id="container"></div>

克隆形状以制作边缘事件检测版本很容易,并将克隆放置在原始形状上,以便您可以专门检测边缘事件。请参阅以下工作片段 - 启用控制台以查看事件序列。

// 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(),

  rect = new Konva.Rect({
    name: 'r1',
    x: 220,
    y: 20,
    width: 100,
    height: 40,
    stroke: 'cyan',
    fill: 'magenta'
  }),
  poly = new Konva.Line({
    points: [23, 20, 23, 160, 70, 93, 150, 109, 290, 139, 270, 93],
    fill: '#00D2FF',
    stroke: 'black',
    strokeWidth: 5,
    closed: true,
    hitStrokeWidth: 10
  }),

  // this is a clone of rect with fillEnabled set to false, placed 'above' rect in the z-order. 
  rect2 = rect.clone({
    fillEnabled: false
  }),
  poly2 = poly.clone({
    fillEnabled: false
  }),



  // Add the layer to the stage
  stage.add(layer);
layer.add(rect, rect2, poly, poly2)

stage.draw();

rect.on('mouseover', function() {
  showMsg('Rect MouseEnter');
})

rect2.on('mouseover', function() {
  showMsg('Rect2 Edge MouseEnter');
})

rect2.on('mouseout', function() {
  showMsg('Rect2 Edge mouseOut');
})

poly.on('mouseover', function() {
  showMsg('Poly MouseEnter');
})

poly.on('mouseout', function() {
  showMsg('Poly MouseOut');
})

poly2.on('mouseover', function() {
  showMsg('Poly2 Edge MouseEnter');
})

poly2.on('mouseout', function() {
  showMsg('Poly2 Edge MouseOut');
})

function showMsg(msg) {
  console.log(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>Move mouse over the shapes </p>
<p id='info'>Events show here</p>
<div id="container"></div>


推荐阅读