D3JS或SNAPSVG拖放仅限于加载的svg形状区域

时间:2016-02-09 13:30:18

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

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

因此,例如,如果我想围绕导入的adobe illustrator svg填充形状拖动一个圆形,这个形状远比矩形复杂(例如德州的状态)。

我估计的工作流程是:

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

由于

d

1 个答案:

答案 0 :(得分: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);
}