3

出于特定原因,我必须进行组翻译(SVG)。我不知道为什么我不能正确完成它,因为翻译完成后,在另一个单击组上,它将重置翻译到开始位置,并使我的傻瓜在SVG画布上跑来跑去。 我写的准系统例如在链接:http://www.atarado.com/en/stripboard-layout-software/group-translation-problem.svg,这里是代码:SVG组翻译问题

<svg xmlns="http://www.w3.org/2000/svg" 
xmlns:xlink="http://www.w3.org/1999/xlink"> 
<script><![CDATA[ 
function startMove(evt){ 
x1=evt.clientX; 
y1=evt.clientY; 
group=evt.target.parentNode; 
group.setAttribute("onmousemove","moveIt(evt)"); 
} 
function moveIt(evt){ 
dx=evt.clientX-x1; 
dy=evt.clientY-y1; 
group.setAttributeNS(null,"transform","translate("+ dx + ", " + dy +")"); 
} 
function drop(){ 
group.setAttributeNS(null, "onmousemove",null); 
} 
]]></script> 
<rect x="0" y="0" width="100%" height="100%" fill="dodgerblue"/> 

<g id="BC" transform="translate(0, 0)" onmousedown="startMove(evt)" onmouseup="drop()"><circle id="C" cx="60" cy="60" r="22" fill="lightgrey" stroke="black" stroke-width="8"/><circle id="B" cx="120" cy="60" r="22" fill="orange" stroke="black" stroke-width="8" /></g> 
</svg> 

任何人都愿意帮助是值得欢迎的。

+2

你可能会对这个例子感兴趣:http://phrogz.net/SVG/drag_under_transformation.xhtml – Phrogz

+0

谢谢你的例子,它很有教育意义。 – Alex

回答

5

组的原因位置上的第二招重置是你设置的转换翻译与(dx, dy)等于位置移动之间的差异开始(x1, y1)和当前位置(evt.clientX, evt.clientY)。这意味着当你第二次点击并且他们稍微移动鼠标时,dx和dy是小数字。然后用它们将变换设置为稍微偏离初始位置的东西。请记住,在任何时候,应用于该组的变换都必须描述从组的起始位置开始的变换

解决此问题的一种方法是,将迄今为止应用于该组的所有移动的总增量存储起来,并使用此累积的(dx, dy)来构建转换。例如:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 
<script><![CDATA[ 
function startMove(evt){ 
    group=evt.target.parentNode; 
    x1=evt.clientX - group.$x; 
    y1=evt.clientY - group.$y; 
    group.setAttribute("onmousemove","moveIt(evt)"); 
} 
function moveIt(evt){ 
    dx=evt.clientX-x1; 
    dy=evt.clientY-y1; 
    group.setAttributeNS(null,"transform","translate("+ dx + ", " + dy +")"); 
    group.$x = dx; 
    group.$y = dy; 
} 
function drop(){ 
    group.setAttributeNS(null, "onmousemove",null); 
} 
]]></script> 
<rect x="0" y="0" width="100%" height="100%" fill="dodgerblue"/> 
<g id="BC" transform="translate(0, 0)" onmousedown="startMove(evt)" onmouseup="drop()"> 
    <circle id="C" cx="60" cy="60" r="22" fill="lightgrey" stroke="black" stroke-width="8"/> 
    <circle id="B" cx="120" cy="60" r="22" fill="orange" stroke="black" stroke-width="8" /> 
</g> 
<script><![CDATA[ 
var group=document.getElementById("BC"); 
group.$x = 0; 
group.$y = 0; 
]]></script> 
</svg> 

我们增加了两个属性到组elememt:$x$y存储元件从所有移动当前位置(或累计增量到目前为止,这取决于你看的方式它)。在定义ID为“BC”的元素之后,它们被初始化为零。它们在moveIt()中更新并在startMove()中消耗。由于我们从(x1, y1)中减去($x, $y),startMove(),因此我们在moveIt()之后有效地将这些新增值添加到(dx, dy)。这确保了(dx, dy)为目前的举措以及迄今为止的所有举措。

+0

你说得很清楚。而已。非常感谢你。 – Alex