How to make selection box in Canvas to select any object it touches not only objects it embraces?

北城以北 提交于 2019-12-09 19:25:54

问题


There is a great tutorial Selecting Multiple Objects with KineticJS that teaches you how to create a selection box in HTML Canvas in order to select multiple objects, but the author Michelle Higgins wrote his code to select object that embraced by the selection box.

The following JavaScript code expresses the algorithm:

var pos = rectSel.getAbsolutePosition();

//get the extents of the selection box
var selRecXStart = parseInt(pos.x);
var selRecXEnd = parseInt(pos.x) + parseInt(rectSel.attrs.width);
var selRecYStart = parseInt(pos.y);
var selRecYEnd = parseInt(pos.y) + parseInt(rectSel.attrs.height);

//get the extents of the group to compare to
var grpXStart = parseInt(grp.attrs.x);
var grpXEnd = parseInt(grp.attrs.x) + parseInt(grp.attrs.width);
var grpYStart = parseInt(grp.attrs.y);
var grpYEnd = parseInt(grp.attrs.y) + parseInt(grp.attrs.height);

//Are we inside the selction area?
if ((selRecXStart <= grpXStart && selRecXEnd >= grpXEnd) && 
    (selRecYStart <= grpYStart && selRecYEnd >= grpYEnd))
{
  if (arSelected.indexOf(grp.getName()) < 0)
  {
    arSelected.push(grp.getName());

    var tmpX = parseInt(grp.attrs.x);
    var tmpY = parseInt(grp.attrs.y);

    var rectHighlight = new Kinetic.Rect({
      x: tmpX,
      y: tmpY,
      height: grp.attrs.height,
      width: grp.attrs.width,
      fill: 'transparent',
      name: 'highlightBlock',
      stroke: '#41d6f3',
      strokeWidth: 3
    });

    layer.add(rectHighlight);
  }
}

The question is: How to make selection box to select any object it touches not only objects it embraces?

P.S: Here is a working jsbin.


回答1:


The current approach checks whether an object is completely contained in the selection rectangle. An interval obj is completely contained in another interval sel when:

    sel.start <= obj.start && obj.end <= sel.end

When you just want the objects to overlap, test:

    sel.start <= obj.end && obj.start <= sel.end

By interval, I mean a single dimension. You must, of course, test the condition for both x and y. Note the the second condition is the first one with their right-hand side swapped.

For your example, change the hit test from:

        //Are we inside the selction area?
        if (selRecXStart <= grpXStart
         && selRecXEnd >= grpXEnd
         && selRecYStart <= grpYStart
         && selRecYEnd >= grpYEnd)
        { ...

to:

        //Are we inside the selction area?
        if (selRecXStart <= grpXEnd
         && selRecXEnd >= grpXStart
         && selRecYStart <= grpYEnd
         && selRecYEnd >= grpYStart)
        { ...


来源:https://stackoverflow.com/questions/35316667/how-to-make-selection-box-in-canvas-to-select-any-object-it-touches-not-only-obj

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!