javascript - 你将如何创建一个 JQuery/svg 单击拖动选择轮廓效果?

标签 javascript jquery svg frontend

不确定确切地调用它是什么,但我正在寻找一种方法来通过 javascript/svg 创建虚线轮廓/选择框效果,当您单击并拖动到一个区域上时,然后在 mouseUp 上消失(可能是如果不是原始部件,则添加)。

如果有 jQuery 库就好了。我环顾四周,但没有找到我要找的东西。
我想理论应该是从第一次点击开始获取坐标,跟踪鼠标坐标时刻并相应地调整框。

但不从头开始编写它会很好。

最佳答案

这是我专为您制作的演示 :)

演示(静态):http://jsfiddle.net/HNH2f/1/

演示(动画):http://jsfiddle.net/HNH2f/2/

您可以使用 CSS 来控制选取框的视觉样式。 您可以将一个或两个函数传递给 trackMarquee方法;两者都将使用四个参数调用:选取框的 x1、y1、x2、y2 边界。第一个函数将在选取框被释放时被调用。每次选取框移动时都会调用第二个函数(如果存在)(例如,这样您就可以计算该边界框内有哪些项目)。

当您开始拖动 SVG 文档(或您选择跟踪的任何元素)时,它将创建一个 <rect class="marquee" /> ;在拖动过程中,它会调整矩形的大小。使用 CSS(如演示中所示)根据需要设置此矩形的样式。我正在使用 stroke-dasharray 属性使边框点缀。

对于 Stack Overflow 后代,这里是代码(如果 JSFiddle 出现故障):

(function createMarquee(global){
  var svgNS = 'http://www.w3.org/2000/svg',
      svg   = document.createElementNS(svgNS,'svg'),
      pt    = svg.createSVGPoint();

  // Usage: trackMarquee( mySVG, function(x1,y1,x2,y2){}, function(x1,y1,x2,y2){} );
  // The first function (if present) will be called when the marquee is released
  // The second function (if present) will be called as the marquee is changed
  // Use the CSS selector `rect.marquee` to select the marquee for visual styling
  global.trackMarquee = function(forElement,onRelease,onDrag){
    forElement.addEventListener('mousedown',function(evt){
      var point0 = getLocalCoordinatesFromMouseEvent(forElement,evt);
      var marquee = document.createElementNS(svgNS,'rect');
      marquee.setAttribute('class','marquee');
      updateMarquee(marquee,point0,point0);
      forElement.appendChild(marquee);
      document.documentElement.addEventListener('mousemove',trackMouseMove,false);
      document.documentElement.addEventListener('mouseup',stopTrackingMove,false);
      function trackMouseMove(evt){
        var point1 = getLocalCoordinatesFromMouseEvent(forElement,evt);
        updateMarquee(marquee,point0,point1);
        if (onDrag) callWithBBox(onDrag,marquee);
      }
      function stopTrackingMove(){
        document.documentElement.removeEventListener('mousemove',trackMouseMove,false);
        document.documentElement.removeEventListener('mouseup',stopTrackingMove,false);
        forElement.removeChild(marquee);
        if (onRelease) callWithBBox(onRelease,marquee);
      }
    },false);
  };

  function callWithBBox(func,rect){
    var x = rect.getAttribute('x')*1,
        y = rect.getAttribute('y')*1,
        w = rect.getAttribute('width')*1,
        h = rect.getAttribute('height')*1;
    func(x,y,x+w,y+h);
  }

  function updateMarquee(rect,p0,p1){
    var xs = [p0.x,p1.x].sort(sortByNumber),
        ys = [p0.y,p1.y].sort(sortByNumber);
    rect.setAttribute('x',xs[0]);
    rect.setAttribute('y',ys[0]);
    rect.setAttribute('width', xs[1]-xs[0]);
    rect.setAttribute('height',ys[1]-ys[0]);
  }

  function getLocalCoordinatesFromMouseEvent(el,evt){
    pt.x = evt.clientX; pt.y = evt.clientY;
    return pt.matrixTransform(el.getScreenCTM().inverse());
  }

  function sortByNumber(a,b){ return a-b }
})(window);

关于javascript - 你将如何创建一个 JQuery/svg 单击拖动选择轮廓效果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11673591/

相关文章:

javascript - 将鼠标悬停在 div 上会触发 div,如果悬停在该 div 上,该 div 将保留

javascript - 如何将 Angular JS 添加到现有的 Node.js 应用程序?

javascript - 如何将VML路径转换为SVG路径?

css - 溢出:在 SVG 上可见

jquery - 使段落中的所有行具有相同的宽度,无论字符数如何

javascript - 用字母数字字符标记轴

javascript - 如何在 Mongoose 聚合中找到平均值

javascript - Angular 8 从外部库中检索值

jquery - 使用 jQuery 从 iFrame 中的元素获取值

javascript - jQuery Reel 插件动态加载卷轴图像