我有以下代码用于拖动SVG对象。
$('#svg-drag')
.draggable()
.bind('mousedown', function(event, ui){
// bring target to front
$(event.target.parentElement).append( event.target );
})
.bind('drag', function(event, ui){
// update coordinates manually, since top/left style props don't work on SVG
event.target.setAttribute('x', ui.position.left);
event.target.setAttribute('y', ui.position.top);
});
但是当我开始拖动对象时,它总是从角落开始。与0,0 xy坐标。我想开始从其原始坐标中拖动。如果我有100,300 XY坐标,我想开始从100 x坐标和300 y坐标拖动。
预先感谢!
启动拖动时,即鼠标向下,您必须访问其当前x,y翻译值。在下面的示例
中显示为OffsetX,Offsety值此示例使用JavaScript。我猜这个示例可能比您目前要求的要多...但是希望将来它会为您提供拖动/删除SVG元素的服务。
无论其先前的变换和/或视口如何,它都会解决任何SVG元素的拖放/下降。它使用svgpoint作为拖放引用,因此无需访问元素的位置属性。我称其为 SVG通用拖动/drop ;)
另外,它不需要将元素移至顶部。除非将其返回在阻力端。
,这可能与所需的布局相抵触。此示例使用SVG矩阵变换,带有对象方法,而不是转换字符串。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>SVG Universal Drag/Drop</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body style='padding:10px;font-family:arial'>
<center>
<h4>SVG Universal Drag/Drop</h4>
<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:6px;'>
This example uses matrix transforms, with object methods, not strings. 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 attaches the element to a <b>transform List</b>
</div>
<div id="svgDiv" style='background-color:lightgreen;width:400px;height:400px;'>
<svg id="mySVG" width="400" height="400" onmousedown=startDrag(evt) onmousemove=drag(evt) onmouseup=endDrag()>
<circle id="redCircle" cx="120" cy="180" r="40" fill="red" stroke="black" stroke-width="2" />
<circle id="orangeCircle" cx="200" cy="200" r="40" fill="orange" stroke="black" stroke-width="2" />
<svg viewBox="0 100 800 800">
<rect id="maroonRect" x="220" y="250" width="60" height="60" fill="maroon" stroke="black" stroke-width="2" />
</svg>
<g id="myG" >
<rect id="blueRect" x="220" y="250" width="60" height="60" fill="blue" stroke="black" stroke-width="2" />
</g>
</svg>
</div>
</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;
//---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()
}
}
//--mouse up---
function endDrag()
{
Dragging = false;
}
document.addEventListener("onload",initTransforms(),false)
//---onload---
function initTransforms()
{
//---place some transforms on the elements---
//--- transform orange circle---
var transformRequestObj=mySVG.createSVGTransform()
var animTransformList=orangeCircle.transform
var transformList=animTransformList.baseVal
//---translate---
transformRequestObj.setTranslate(180,-260)
transformList.appendItem(transformRequestObj)
transformList.consolidate()
//----scale---
transformRequestObj.setScale(.5,.9)
transformList.appendItem(transformRequestObj)
transformList.consolidate()
//----skewY---
transformRequestObj.setSkewY(52)
transformList.appendItem(transformRequestObj)
transformList.consolidate()
//--init Transform on myG---
var transformRequestObj=mySVG.createSVGTransform()
var animTransformList=myG.transform
var transformList=animTransformList.baseVal
//---translate---
transformRequestObj.setTranslate(-50,-80)
transformList.appendItem(transformRequestObj)
transformList.consolidate()
//----skewX---
transformRequestObj.setSkewX(15)
transformList.appendItem(transformRequestObj)
transformList.consolidate()
//----skewY---
transformRequestObj.setSkewY(20)
transformList.appendItem(transformRequestObj)
transformList.consolidate()
//---rotate---
transformRequestObj.setRotate(30,200,200)
transformList.appendItem(transformRequestObj)
transformList.consolidate()
}
</script>
</body>
</html>
在这里尝试此示例,
<div id="containment-wrapper" class="wrap">
<svg id="svg-drag" width="100" height="100">
<circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
Sorry, your browser does not support inline SVG.
</svg>
</div>
jQuery:
$('#svg-drag')
.draggable()
.bind('mousedown', function(event, ui){
// bring target to front
$(event.target.parentElement).append( event.target );
})
.bind('drag', function(event, ui){
// update coordinates manually, since top/left style props don't work on SVG
event.target.setAttribute('x', ui.position.left);
event.target.setAttribute('y', ui.position.top);
});
演示小提琴
如果已转换一条路径,以下内容将更新其D属性并删除转换。Thiis在所有SVG路径类型上都可以使用,除了弧。
//---except arc paths---
function screenPath(path)
{
var sCTM = path.getCTM()
var svgRoot = path.ownerSVGElement
var segList=path.pathSegList
var segs=segList.numberOfItems
//---change segObj values
for(var k=0;k<segs;k++)
{
var segObj=segList.getItem(k)
if(segObj.x && segObj.y )
{
var mySVGPoint = svgRoot.createSVGPoint();
mySVGPoint.x = segObj.x
mySVGPoint.y = segObj.y
mySVGPointTrans = mySVGPoint.matrixTransform(sCTM)
segObj.x=mySVGPointTrans.x
segObj.y=mySVGPointTrans.y
}
if(segObj.x1 && segObj.y1)
{
var mySVGPoint1 = svgRoot.createSVGPoint();
mySVGPoint1.x = segObj.x1
mySVGPoint1.y = segObj.y1
mySVGPointTrans1 = mySVGPoint1.matrixTransform(sCTM)
segObj.x1=mySVGPointTrans1.x
segObj.y1=mySVGPointTrans1.y
}
if(segObj.x2 && segObj.y2)
{
var mySVGPoint2 = svgRoot.createSVGPoint();
mySVGPoint2.x = segObj.x2
mySVGPoint2.y = segObj.y2
mySVGPointTrans2 = mySVGPoint2.matrixTransform(sCTM)
segObj.x2=mySVGPointTrans2.x
segObj.y2=mySVGPointTrans2.y
}
}
//---force removal of transform--
path.setAttribute("transform","")
path.removeAttribute("transform")
}