我正在开发一个项目,可以在水平线上上下移动svg文件的元素。我想跟踪移动元素相对于固定线的位置。这两个元素都在同一个svg中。我尝试使用
getBoundingClientRect().top
但是,由于getBoundingClientRect()函数生成的坐标会根据视口的大小,位置和缩放而发生变化,因此无法提供良好的解决方案。在每种情况下,每台设备都不一样。我需要能够知道特定路径何时在固定线的上方或下方一定距离。我在包含组上使用setAttribute('transform','translate())来移动项目中的一组对象。我需要知道我的组中单个对象相对于不在我组中的固定行的位置。
<svg version="1.1" id="ex1-3rds-quarter-s" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" width="323.333px" height="55.333px" viewBox="0 0 323.333 55.333" enable-background="new 0 0 323.333 55.333"
xml:space="preserve">
<g id="ledgerlines">
<line id="MidCLine1" fill="none" stroke="#000000" stroke-width="0.75" stroke-miterlimit="10" x1="48.09" y1="41.694" x2="57.924" y2="41.694"/>
</g>
<g id="note1">
<path class="root" d="M54.113,38.945c1.116,0,2.172,0.578,2.172,1.813c0,1.435-1.116,2.411-2.052,2.969c-0.717,0.418-1.514,0.717-2.331,0.717
c-1.116,0-2.172-0.578-2.172-1.813c0-1.435,1.116-2.411,2.052-2.969C52.499,39.244,53.296,38.945,54.113,38.945z"/>
<path d="M54.113,33.963c1.116,0,2.172,0.578,2.172,1.813c0,1.435-1.116,2.411-2.052,2.969c-0.717,0.418-1.514,0.717-2.331,0.717
c-1.116,0-2.172-0.578-2.172-1.813c0-1.435,1.116-2.411,2.052-2.969C52.499,34.262,53.296,33.963,54.113,33.963z"/>
</g>
</svg>
有没有办法在不使用getBoundingClientRect()函数的情况下跟踪路径的位置?
谢谢, --christopher
答案 0 :(得分:1)
尝试将路径放在svg'wrapper / empty'元素中。然后使用getBBox()
作为包装器。这将提供用于设置/读取路径翻译的x,y值。
编辑:我在下面列出了一个可以在参考线之间移动rects的示例。即使先前已经转换了矩形,这也可以工作。这使用单个SVG Wrapper。注意:如果您只是一次转换元素,那么您不必对bbx,bby值使用矩阵变换。它们可以直接使用。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>SVG Wrapper</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body style='font-family:arial'>
<center>
<h4>SVG Wrapper</h4>
<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:6px;'>
Translate rects to line via SVG Wrapper. Can translate between lines
</div>
<div id="svgDiv" style='background-color:gainsboro;width:400px;height:400px;'>
<svg id="mySVG" width="400" height="400">
<line id=refLine1 stroke='blue' stroke-width='2' x1=20 y1=40 x2=380 y2=40 />
<line id=refLine2 stroke='maroon' stroke-width='2' x1=20 y1=100 x2=380 y2=100 />
<g id=rectG>
<rect id=redRect fill=red x=60 y=200 width=100 height=50 />
<rect id=greenRect fill=lime x=260 y=320 width=100 height=50 />
</g>
<svg id=Wrapper />
</svg>
</div>
<center>
<button onClick=moveToLine(refLine1,redRect)>Move Red Rect to <span style=color:blue>Line 1</span></button>
<button onClick=moveToLine(refLine1,greenRect)>Move Green Rect to <span style=color:blue>Line 1</span></button>
<br />
<button onClick=moveToLine(refLine2,redRect)>Move Red Rect to <span style=color:maroon>Line 2</span></button>
<button onClick=moveToLine(refLine2,greenRect)>Move Green Rect to <span style=color:maroon>Line 2</span></button>
</center>
<br />SVG Source:<br />
<textarea id=svgSourceValue style='font-size:110%;font-family:lucida console;width:90%;height:200px'></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>
<div id='browserDiv' style='padding:5px;position:absolute;top:5px;left:5px;background-color:gainsboro;'>OK in:IE11/CH32/FF28<br /></div>
<script id=myScript>
function moveToLine(refLine,rect)
{
//---move rect to this location at line---
var targetY=refLine.y1.baseVal.value
var targetX=rect.x.baseVal.value
Wrapper.appendChild(rect)
var bb=Wrapper.getBBox()
//---return rect to its <g>---
rectG.appendChild(rect)
var bbx=bb.x
var bby=bb.y
//---bind wrapper x,y to rect's current transform--
var pnt = mySVG.createSVGPoint();
pnt.x = bbx;
pnt.y = bby;
var sCTM = rect.getCTM();
PNT = pnt.matrixTransform(sCTM.inverse());
//---translate rect's x,y to target---
var transX=targetX-PNT.x
var transY=targetY-PNT.y
rect.setAttribute("transform","translate("+transX+" "+transY+")")
svgSourceValue.value=svgDiv.innerHTML
}
</script>
<script>
document.addEventListener("onload",init(),false)
function init()
{
svgSourceValue.value=svgDiv.innerHTML
jsValue.value=myScript.text
}
</script>
</body>
</html>