2011-01-19 23 views
5

całość,SVG - rozmiaru prostokąta umieszczone pod kątem

mam prostokąt SVG w moim aplikacji, która może być rozciągnięta poziomo przez suwaka końca (po lewej & prawej) po obu stronach prostokąta. Prostokąta może być

(1) zmniejszone (przez rozciąganie jak powyżej)

(2) przeciągany

(3) & obracać.

Wszystko działa poprawnie, jednak jeden dziwne doświadczenie jest to, że kiedy obrócić prostokąt w stopniu zbliżonym do 90, & następnie spróbuj zmienić rozmiar prostokąta, zaczyna rozciągający się od przeciwległej granicy prostokąta zamiast pierwotnych granic . (Tutaj jest obraz):

rendition of functionality

Wydaje się być coraz mylić między lewo i prawo, kiedy korzystać z funkcji obracania.

Oto Aktualizowano HTML, JS & SVG:

<%@page contentType="text/html" pageEncoding="UTF-8"%> 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    "http://www.w3.org/TR/html4/loose.dtd"> 

<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
     <title>JSP Page</title> 
<!--  <script type="text/javascript" src="CPolyline.js"> 

     </script>--> 
    </head> 
    <body> 
     <object id="oo" data="rect2.svg" style="position:fixed;width: 800px;height:800px;bottom:-100px;right: 375px;"> 

    </object> 
     path: <input type="button" id="path" onclick="X()"> 
     path2: <input type="button" id="path2" onclick="Y()"> 
    <input type="button" value="Rotate" onclick="Rotate1()"> 


     <script type="text/javascript"> 
      var ob=document.getElementById("oo") 

      var svgDoc=null; 
      var svgRoot=null; 
      var MyGroupObjectsObj = null; 
      var svgNS = "http://www.w3.org/2000/svg"; 
      var dragTarget = null; 
      var rectTemplate = null; 
      var grabPoint = null; 
      var clientPoint = null; 
      var rectX = null; 
      var rectY = null; 
      var rectWidth = null; 
      var rectHeight = null; 
      var arr=new Array(); 
      var resizingLeft = false; 
      var resizingRight = false; 
      var rectrot=null 

      ob.addEventListener("load", function(){ 

       svgDoc=ob.contentDocument; 

       svgRoot=svgDoc.documentElement; 
       grabPoint = svgRoot.createSVGPoint(); 
       clientPoint = svgRoot.createSVGPoint(); 
       rectTemplate = svgDoc.getElementById('rectTemplate') 

     rectrot=svgDoc.getElementById("rect1") 



}, false) 



var angel=0 


function Rotate1() 
{ 

     angel=angel+10 
     //alert(rectrot) 

     var c=rectTemplate.getAttribute("transform"); 
     var widt=Number(rectTemplate.getAttribute("width"))/2; 

     var hie=Number(rectTemplate.getAttribute("height"))/2 
     var tran=c.match(/[\d\.]+/g); 
     var newxpo=Number(tran[0])+widt; 
     var newypo=Number(tran[1])+hie; 
     var r=Math.tan((newxpo)/(newypo)) 
     rectTemplate.parentNode.setAttribute("transform","translate("+newxpo+" "+newypo+")"+"rotate("+angel+") translate("+(newxpo*-1)+" "+(newypo*-1)+")"); 



} 


function MouseDown(evt) 
{ 

    var targetElement = evt.target; 
     var checkForResizeAttempt = false; 

     if (targetElement == rectTemplate) 
     { 
      //arr.push(cir ,cir1,rectTemplate) 

       dragTarget = targetElement; 
       checkForResizeAttempt = true; 

         var transMatrix = dragTarget.getCTM(); 


     grabPoint.x = evt.clientX - Number(transMatrix.e); 
     grabPoint.y = evt.clientY - Number(transMatrix.f); 

     } 

     var transMatrix = dragTarget.getCTM(); 



//var transMatrix = dragTarget.getCTM().inverse(); 

     grabPoint.x = evt.clientX - Number(transMatrix.e); 
     grabPoint.y = evt.clientY - Number(transMatrix.f); 

     if (window.console) console.log(grabPoint.x + " " + grabPoint.y); 
     if (window.console) console.log(evt.clientX + " " + evt.clientY); 

     if (checkForResizeAttempt) 
     { 
      clientPoint.x = evt.clientX; 
      clientPoint.y = evt.clientY; 
      rectX = Number(dragTarget.getAttributeNS(null, "x")); 
      rectY = Number(dragTarget.getAttributeNS(null, "y")); 
      rectWidth = Number(dragTarget.getAttributeNS(null, "width")); 
      rectHeight = Number(dragTarget.getAttributeNS(null, "height")); 

      if ((grabPoint.x - rectX) < 10) 
      { 
      resizingLeft = true; 
      } 
      else if (((rectX + rectWidth) - grabPoint.x) < 10) 
      { 
      resizingRight = true; 
      } 

      if (resizingLeft || resizingRight) 
      { 
      dragTarget.setAttributeNS(null,"stroke","green"); 
      } 
      else 
      { 
      dragTarget.setAttributeNS(null,"stroke","black"); 
      } 
     } 
     } 

function MouseMove(evt) 
{ 
evt.stopPropagation(); 
if (dragTarget == null) 
     { 
     return; 
     } 
     if (resizingLeft) 
     { 
     if (window.console) console.log(evt.clientX + " " + evt.clientY); 
     deltaX = (clientPoint.x - evt.clientX); 
     if (window.console) console.log("deltaX = " + deltaX); 
     dragTarget.setAttributeNS(null,"width",rectWidth + deltaX); 
     dragTarget.setAttributeNS(null,"x",rectX - deltaX); 
     } 
     else if (resizingRight) 
     { 
     deltaX = (clientPoint.x - evt.clientX); 
     if (window.console) console.log("rectWidth = " + rectWidth + " deltaX = " + deltaX); 
     dragTarget.setAttributeNS(null,"width",rectWidth - deltaX); 


     } 
     else 
     { 


     var newXX = evt.clientX-grabPoint.x; 
     var newYX = evt.clientY-grabPoint.y; 


     dragTarget.setAttributeNS(null,'transform','translate(' + newXX + ',' + newYX + ')'); 
     } 

} 
function MouseUp(evt) 
{ 
    evt.stopPropagation(); 
    if (dragTarget == null) 
     { 
     return; 
     } 
     resizingLeft = false; 
     resizingRight = false; 
     resizingTop = false; 
     resizingBottom = false; 
    // var transMatrix = dragTarget.getCTM().inverse(); 
     dragTarget.setAttributeNS(null,"stroke","blue"); 
     dragTarget = null; 


} 


     </script> 
    </body> 
</html> 



-- 



=======SVG ==== 

<?xml version="1.0" standalone="no"?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" 
    x="0px" y="0px" width="612px" height="792px" xml:space="preserve" 
onmousedown="ecmascript:top.MouseDown(evt)" 
onmousemove="ecmascript:top.MouseMove(evt)" 
onmouseup="ecmascript:top.MouseUp(evt)"> 




<g id="rect1"> 
    <rect id="rectTemplate" x="0" y="0" stroke="blue" width="100" height="30" /> 

</g> 
+0

Naprawdę pomógłbyś, gdyby opublikowałeś niepełny, ale działający pełny przykład (np. Dołącz plik SVG). Ponadto wcięcia w kodzie wymagają poważnego formatowania w porównaniu do sposobu wklejenia. – Phrogz

+0

Dzięki Phrogz, zobaczę, czy mogę opublikować skróconą wersję kodu. – Kayote

+0

Zaktualizował kod, aby lepiej odwzorować bity wymagające uwagi. Best, – Kayote

Odpowiedz

1

Czy próbowałeś zmienić swój kod, aby obrócić kształt wokół środka kształtu?

Here is an excerpt Projektu W3C na transform:

rotate(<rotate-angle> [<cx> <cy>]), 
which specifies a rotation by <rotate-angle> degrees about a given point. 

If optional parameters <cx> and <cy> are not supplied, the rotate is about the origin of the current user coordinate system. 

The operation corresponds to the matrix [cos(a) sin(a) -sin(a) cos(a) 0 0]. 

If optional parameters <cx> and <cy> are supplied, the rotate is about the point (cx, cy). 

The operation represents the equivalent of the following specification: 
translate(<cx>, <cy>) rotate(<rotate-angle>) translate(-<cx>, -<cy>). 

Jeśli ustawisz cx i cy do centrum swojego wstążki, to może pomóc z jakim kontekście mogę odebrać z Twojego kodu.

+0

Robię to samo, aby się obracać, ale kiedy obracam prostokątem pięści, zmieniam jego współrzędne i nie zmieniam rozmiaru. .. –

+0

Dzięki Garet, w końcu miałem szansę wrócić do tego wydania. Przekazujemy "prostokąt w grupę", a następnie obracamy grupę od środka. Oto kod: rectTemplate.parentNode.setAttribute ("transform", "przetłumacz (" + newxpo + "" + newypo + ")" + "obróć (" + anioł + ") przetłumacz (" + (newxpo * -1) + "" + (newypo -1 -1) ")"); – Kayote

+0

Garet, Ive dodał do powyższego pierwotnego pytania, oprócz odpowiedzi na twój post i Phrogza. – Kayote

5

Pisałem próbkę przeciągając i zmiana rozmiaru zwerbowany prostokąty, SVG w moją odpowiedź tutaj:
SVG coordinates with transform matrix

można zobaczyć na przykładzie pracy na mojej stronie tutaj:
http://phrogz.net/svg/drag_under_transformation.xhtml

Kluczem jest :

  1. Po rozpoczęciu przeciągania (mousedown) zapisz położenie myszy (w przestrzeni globalnej SVG).
  2. Podczas przeciągania (mousemove) obliczyć przesunięcie (w przestrzeni globalnej SVG) dla przeciągnięcia, a następnie przekształcić przesunięcie z przestrzeni globalnej na przestrzeń lokalną obiektu i użyć go do poinformowania o wprowadzonych zmianach.

Działa to niezależnie od zastosowanej hierarchii transformacji (jak pokazano w moim przykładzie).

+0

THanx phrogz, moja zmiana rozmiaru jest myląca, ale kiedy obrócę prostokąt i chcę go ponownie zmienić, prostokąt przesuwa się w innym kierunku (przeciwnie do pozycji kursora), ponieważ jego współrzędne są przesunięte z pierwotnej lokalizacji ... pomóżcie mi po zmianie rozmiaru rotacji –

+0

@AbdulRauf Mój kod i przykład nie cierpią z powodu takiego problemu. Jeśli dostanę więcej czasu, przyjrzę się analizie twojego kodu, ale dostarczam kod działający. – Phrogz

+0

Dzięki Phrogz. Robimy to samo i osiągamy ten sam rezultat. Jednak w naszym scenariuszu, oprócz tego, że "użytkownik może przeciągać na końcach prostokąta i rozciągać go", może również obracać prostokąt. Problem wynika z obrotu, tj. Gdy obrócimy prostokąt do pewnego stopnia nawet nieco większego niż 20, cała funkcja zmiany rozmiaru włącza swoją głowę. – Kayote

Powiązane problemy