试验AngularJS和D3我试图弄清楚如何拖动和放大将svg元素从一个svg拖放到另一个svg。您对如何做到有任何提示或经验吗?
此致 岸堤
答案 0 :(得分:0)
我用javaxcript完成了这个。也许你可以使用它的一些功能。它适用于IE和Chrome。 FF正在实施所需的交叉列表方法。
下面的示例显示拖动元素并将它们放入各种viewPorts(SVG根)。 使用矩阵变换。它可以无缝拖放先前已转换的元素,并将其保存在不同的viewPorts中。它使用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>