【问题标题】:D3JS or SNAPSVG drag and drop limited to loaded svg shape areaD3JS 或 SNAPSVG 拖放仅限于加载的 svg 形状区域
【发布时间】:2016-05-19 12:24:11
【问题描述】:

任何人都获得了使用 D3JS 或 SNAPSVG 将拖动对象捕捉到加载的 SVG 范围内的任何示例或指针。

例如,如果我想在导入的 adobe illustrator svg 填充形状周围拖动一个圆,该形状比矩形复杂得多(例如德克萨斯州)。

我估计的工作流程是:

  • 加载usa.svg的地图
  • 在 usa.svg 上加载 texas.svg 覆盖
  • 用户点击 texas.svg 中的任意位置,会出现一个 cricle,然后我可以拖动它,但只能在 texas.svg 路径的范围内。

谢谢

D

【问题讨论】:

    标签: javascript html d3.js svg snap.svg


    【解决方案1】:

    根据所需的整体解决方案,您可以在其中一个 SVG 元素上放置一个处理程序,以便它只触发或检查它是否是正确的目标。

    因此,当您单击它时选择一个状态,并将处理程序放在该状态而不是圆圈上(您可以使用指针事件禁用:无)。

    所以你是在“拖动”状态,但在移动圆圈。我们为此编写了自己的自定义处理程序。

    这不是一个完整的解决方案,它需要一些进一步的边缘案例测试,例如拖动到新状态,或者不拖动/单击地图之外。它只是一种可能的方式的想法,通过使用事件本身来限制其拖动。

    jsfiddle

    Snap.load( "https://upload.wikimedia.org/wikipedia/commons/3/32/Blank_US_Map.svg", onSVGLoaded )
    
    function onSVGLoaded( frag ) {
      s.append( frag );
      s.click( addCircle )
    }
    
    function addCircle(ev, x, y) {
      var t = Snap(ev.target)
      if(( t.data('dragEl') == undefined ) && ( dragging == false ) ) { // We only want one circle on a state
        var c = s.circle( x-10, y-10, 10)
                 .attr({ style: 'pointer-events: none; opacity: 0.5' });  
        t.drag( dragMove, dragStart, dragStop ).data('dragEl', c)
      }
    }
    
    function dragStart( x, y, ev ) {
      this.data('targetState', ev.target.id );
    }
    
    function dragMove(dx,dy,x,y,ev) {
      if( ev.target.id != this.data('targetState')) { return }    // Check the event isn't coming from a different state
      this.data('dragEl').attr({ cx: x-10, cy: y-10 })
      dragging = true;
    }
    
    function dragStop() {  // prevent dragend causing new click
      setTimeout( function(){ dragging = false; }, 300);
    }
    

    【讨论】:

    • 有趣,谢谢你的想法,我会研究一下。
    猜你喜欢
    • 1970-01-01
    • 2013-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多