2014-02-28 63 views
1

嘗試使用AngularJS和D3我試圖找出如何將一個svg拖放到另一個svg的&。你有什麼提示或經驗如何做到這一點?使用D3和AngularJS拖放SVG圖形

問候, 安迪

Example將是從右邊方框拖到一個圓,它拖放到左方。示例源位於github

+1

[這裏](http://bl.ocks.org/thudfactor/6611441)是一個用HTML和SVG演示的例子。一般來說,如果這是您的選擇,在單個SVG中拖放會更容易。 –

回答

0

我用javaxcript完成了這個工作。也許你可以使用它的一些功能。它適用於IE和Chrome。 FF正在推行所需的交集列表方法。

下面的這個例子顯示了拖動元素並將它們拖放到不同的viewPort(SVG根)中。 使用矩陣變換。它可以無縫地拖放之前被轉換的元素,並將其放置在不同的viewPort中。它使用getScreenCTM,createSVGTransform並將元素綁定到變換List 每個視口目標由使用SVGRect對象確定並使用checkIntersection。

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title>Drag and Drop Into Viewports</title> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> 
</head> 
<body style='padding:10px;font-family:arial'> 
<center> 
<h4> Drag and Drop Into Viewports</h4> 
<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:6px;'> 
This example shows dragging elements and dropping them into the various viewPorts(SVG roots). 
Uses matrix transforms. It can seamlessly drag/drop elements that have previously been transformed and reside it different viewPorts. It employs <b>getScreenCTM</b>, <b>createSVGTransform</b> and binds the element to a <b>transform List</b> 
Each viewport target is determined by using an <b>SVGRect</b> object and employes <b>checkIntersection</b>. 
</div> 
<table> 
<tr><td align=left> 
<b>Scenerio:</b><br /> 
A The parent SVG root(mySVG) with viewBox=0 0 400 400.<br /> 
It contains the the draggable red circles. The white circles are inside the rect viewPorts<br /> 
1.) The blue rect element is contained in, and fills, its own svg root<br /> 
3.) The maroon rect element is contained in, and fills, its own svg root.<br /> 
4.) The orange rect element is contained in, and fills, its own svg root<br /> with viewPort=10 10 50 50.<br /> 
<br /> 
(View the SVG Source to verify where the circles are being dropped.) 
</td> 
<td align=left> 
<div id="svgDiv" style='background-color:lightgreen;width:400px;height:400px;'> 
<svg id="mySVG" width="100%" height="100%" viewBox="0 0 400 400"> 
<svg overflow="visible" width="100" height="100" x="20" y="60" pointer-events="all" id="blueSVG" > 
<rect id="blueRect" x="0" y="0" width="100" height="100" fill="blue" stroke="black" stroke-width="2" /> 
<circle onmousedown=startDrag(evt) onmousemove=drag(evt) onmouseup=endDrag(evt) fill="white" cx="20" cy="20" r="15" /> 
</svg> 
<svg overflow="visible" width="100" height="100" x="280" y="60" pointer-events="all" id="maroonSVG" > 
<rect id="maroonRect" x="0" y="0" width="100" height="100" fill="maroon" stroke="black" stroke-width="2" /> 
<circle onmousedown=startDrag(evt) onmousemove=drag(evt) onmouseup=endDrag(evt) fill="white" cx="20" cy="20" r="15" /> 
<circle onmousedown=startDrag(evt) onmousemove=drag(evt) onmouseup=endDrag(evt) fill="white" cx="60" cy="20" r="15" /> 
</svg> 
<svg overflow="visible" width="100" height="100" x="120" y="200" viewBox="10 10 50 50" pointer-events="all" id="orangeSVG" > 
<rect id="orangeRect" x="0" y="0" width="100" height="100" fill="orange" stroke="black" stroke-width="2" /> 
<circle onmousedown=startDrag(evt) onmousemove=drag(evt) onmouseup=endDrag(evt) fill="white" cx="20" cy="20" r="15" /> 
</svg> 
<svg id="WrapperSVG" /> 
<circle onmousedown=startDrag(evt) onmousemove=drag(evt) onmouseup=endDrag(evt) fill="red" cx="40" cy="30" r="15" /> 
<circle onmousedown=startDrag(evt) onmousemove=drag(evt) onmouseup=endDrag(evt) fill="red" cx="80" cy="30" r="15" /> 
<circle onmousedown=startDrag(evt) onmousemove=drag(evt) onmouseup=endDrag(evt) fill="red" cx="120" cy="30" r="15" /> 
<circle onmousedown=startDrag(evt) onmousemove=drag(evt) onmouseup=endDrag(evt) fill="red" cx="160" cy="30" r="15" /> 
<circle onmousedown=startDrag(evt) onmousemove=drag(evt) onmouseup=endDrag(evt) fill="red" cx="200" cy="30" r="15" /> 
<circle onmousedown=startDrag(evt) onmousemove=drag(evt) onmouseup=endDrag(evt) fill="red" cx="240" cy="30" r="15" /> 
<circle onmousedown=startDrag(evt) onmousemove=drag(evt) onmouseup=endDrag(evt) fill="red" cx="280" cy="30" r="15" /> 
<circle onmousedown=startDrag(evt) onmousemove=drag(evt) onmouseup=endDrag(evt) fill="red" cx="320" cy="30" r="15" /> 
<circle onmousedown=startDrag(evt) onmousemove=drag(evt) onmouseup=endDrag(evt) fill="red" cx="360" cy="30" r="15" /> 
</svg> 
</div> 
</td> 
</tr></table> 
<br />SVG Source:<br /> 
<textarea id=svgSourceValue style='font-size:110%;font-family:lucida console;width:90%;height:400px'></textarea> 
<br />Javascript:<br /> 
<textarea id=jsValue style='border-radius:26px;font-size:110%;font-weight:bold;color:midnightblue;padding:16px;background-color:beige;border-width:0px;font-size:100%;font-family:lucida console;width:90%;height:400px'></textarea> 
</center> 
<script id=myScript> 
var TransformRequestObj 
var TransList 
var DragTarget=null; 
var Dragging = false; 
var OffsetX = 0; 
var OffsetY = 0; 
//---mouse down over element--- 
function startDrag(evt) 
{ 
    if(!Dragging) //---prevents dragging conflicts on other draggable elements--- 
    { 
     DragTarget = evt.target; 
     //---bring this viewPort to top--- 
     if(DragTarget.ownerSVGElement!=mySVG) 
      mySVG.appendChild(DragTarget.ownerSVGElement) 
     //---bring this element to top--- 
     DragTarget.ownerSVGElement.appendChild(DragTarget) 

     //---reference point to its respective viewport-- 
     var pnt = DragTarget.ownerSVGElement.createSVGPoint(); 
     pnt.x = evt.clientX; 
     pnt.y = evt.clientY; 
     //---elements transformed and/or in different(svg) viewports--- 
     var sCTM = DragTarget.getScreenCTM(); 
     var Pnt = pnt.matrixTransform(sCTM.inverse()); 

     TransformRequestObj = DragTarget.ownerSVGElement.createSVGTransform() 
     //---attach new or existing transform to element, init its transform list--- 
     var myTransListAnim=DragTarget.transform 
     TransList=myTransListAnim.baseVal 

     OffsetX = Pnt.x 
     OffsetY = Pnt.y 

     Dragging=true; 
    } 
} 
//---mouse move--- 
function drag(evt) 
{ 
    if(Dragging) 
    { 
     var pnt = DragTarget.ownerSVGElement.createSVGPoint(); 
     pnt.x = evt.clientX; 
     pnt.y = evt.clientY; 
     //---elements in different(svg) viewports, and/or transformed --- 
     var sCTM = DragTarget.getScreenCTM(); 
     var Pnt = pnt.matrixTransform(sCTM.inverse()); 
     Pnt.x -= OffsetX; 
     Pnt.y -= OffsetY; 

     TransformRequestObj.setTranslate(Pnt.x,Pnt.y) 
     TransList.appendItem(TransformRequestObj) 
     TransList.consolidate() 
    } 
} 
var ViewPortTarget 
//--mouse up--- 
function endDrag(evt) 
{ 
    Dragging = false; 
    //--which viewPort is the element over ?--- 
    var isBlueSVG = mySVG.checkIntersection(DragTarget, BlueObjRect) 
    var isOrangeSVG = mySVG.checkIntersection(DragTarget, OrangeObjRect) 
    var isMaroonSVG = mySVG.checkIntersection(DragTarget, MaroonObjRect) 

    if(isBlueSVG) 
     ViewPortTarget=blueSVG 
    else if(isOrangeSVG) 
     ViewPortTarget=orangeSVG 
    else if(isMaroonSVG) 
     ViewPortTarget=maroonSVG 
    else 
     ViewPortTarget=mySVG 

    ViewPortTarget.appendChild(DragTarget) 
    var pnt = DragTarget.ownerSVGElement.createSVGPoint(); 
    pnt.x = evt.clientX; 
    pnt.y = evt.clientY; 
    //---elements in different(svg) viewports, and/or transformed --- 
    var sCTM = DragTarget.getScreenCTM(); 
    var Pnt = pnt.matrixTransform(sCTM.inverse()); 
    Pnt.x -= OffsetX; 
    Pnt.y -= OffsetY; 

    TransformRequestObj.setTranslate(Pnt.x,Pnt.y) 
    TransList.appendItem(TransformRequestObj) 
    TransList.consolidate() 

    svgSourceValue.value=svgDiv.innerHTML 
} 
//---build the viewPort intersect rect obj--- 
var BlueObjRect 
var OrangeObjRect 
var MaroonObjRect 
function setViewportRect() 
{ 
    WrapperSVG.appendChild(blueSVG) 
    var bb=WrapperSVG.getBBox() 
    var bbx=bb.x 
    var bby=bb.y 
    var bbw=bb.width 
    var bbh=bb.height 
    BlueObjRect=mySVG.createSVGRect() 

    BlueObjRect.x=bbx 
    BlueObjRect.y=bby 
    BlueObjRect.width=bbw 
    BlueObjRect.height=bbh 
    mySVG.insertBefore(blueSVG,WrapperSVG) 

    WrapperSVG.appendChild(orangeSVG) 
    var bb=WrapperSVG.getBBox() 
    var bbx=bb.x 
    var bby=bb.y 
    var bbw=bb.width 
    var bbh=bb.height 
    OrangeObjRect=mySVG.createSVGRect() 

    OrangeObjRect.x=bbx 
    OrangeObjRect.y=bby 
    OrangeObjRect.width=bbw 
    OrangeObjRect.height=bbh 
    mySVG.insertBefore(orangeSVG,WrapperSVG) 

    WrapperSVG.appendChild(maroonSVG) 
    var bb=WrapperSVG.getBBox() 
    var bbx=bb.x 
    var bby=bb.y 
    var bbw=bb.width 
    var bbh=bb.height 

    MaroonObjRect=mySVG.createSVGRect() 
    MaroonObjRect.x=bbx 
    MaroonObjRect.y=bby 
    MaroonObjRect.width=bbw 
    MaroonObjRect.height=bbh 
    mySVG.appendChild(maroonSVG) 
    mySVG.insertBefore(maroonSVG,WrapperSVG) 
} 
</script> 
<script> 
document.addEventListener("onload",init(),false) 
function init() 
{ 
    setViewportRect() 
    svgSourceValue.value=svgDiv.innerHTML 
    jsValue.value=myScript.text 
} 
</script> 

</body> 

</html>