Вопрос перевода группы SVG - PullRequest
       34

Вопрос перевода группы SVG

3 голосов
/ 02 ноября 2011

Я должен сделать групповой перевод (SVG) по определенной причине.Я не знаю, почему я не могу сделать это правильно, потому что после того, как перевод сделан, при другом щелчке по группе он сбрасывает перевод в начальную позицию и заставляет меня дурачиться, бегая по холсту SVG.Я пишу простой пример по ссылке: http://www.atarado.com/en/stripboard-layout-software/group-translation-problem.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>

Добро пожаловать всем, кто хочет помочь.

1 Ответ

5 голосов
/ 03 ноября 2011

Причина, по которой позиция группы сбрасывается на втором ходу, состоит в том, что вы устанавливаете преобразование для перевода с (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 для хранения текущей позиции элемента (или накопленных дельт от всех ходов до сих пор, в зависимости отна то, как ты на это смотришь).Они инициализируются нулем в скрипте, расположенном после определения элемента с идентификатором «BC».Они обновляются в moveIt() и потребляются в startMove().Поскольку мы вычитаем наши новые дельты ($x, $y) из (x1, y1) в startMove(), эти новые дельты фактически добавляются к (dx, dy) позже в moveIt().Это гарантирует, что (dx, dy) учитывает как все ходы, так и текущий ход.

...