rotate html5 svg

html5 - rotate - SVG se coordina con la matriz de transformación



svg transform scale (2)

He creado un ejemplo de trabajo de lo que creo que estás describiendo en mi sitio aquí:
http://phrogz.net/svg/drag_under_transformation.xhtml

En general, convierte el cursor del mouse en el espacio local de un objeto al:

  1. Crear un controlador de eventos mousemove :

    var svg = document.getElementsByTagName(''svg'')[0]; document.documentElement.addEventListener(''mousemove'',function(evt){ ... },false);

  2. En ese controlador de eventos, convierta las coordenadas del mouse (en píxeles) en el espacio global de su documento SVG:

    var pt = svg.createSVGPoint(); pt.x = evt.clientX; pt.y = evt.clientY; var globalPoint = pt.matrixTransform(svg.getScreenCTM().inverse());

  3. Convierta el punto global en el espacio del objeto que está arrastrando:

    var globalToLocal = dragObject.getTransformToElement(svg).inverse(); var inObjectSpace = globalPoint.matrixTransform( globalToLocal );

Para la posteridad de Stack Overflow, esta es la fuente completa de mi demo de SVG + XHTML (en caso de que mi sitio esté inactivo):

<!DOCTYPE HTML> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head> <meta http-equiv="content-type" content="application/xhtml+xml;charset=utf-8"/> <title>Dragging Transformed SVG Elements</title> <style type="text/css" media="screen"> html, body { background:#eee; margin:0; user-select:none; -moz-user-select:none; -webkit-user-select:none; } p { margin:0.5em; text-align:center } svg { position:absolute; top:5%; left:5%; width:90%; height:90%; background:#fff; border:1px solid #ccc } svg rect { stroke:#333 } svg .drag { cursor:move } svg .sizer { opacity:0.3; fill:#ff0; stroke:#630;} #footer { position:absolute; bottom:0.5em; margin-bottom:0; width:40em; margin-left:-20em; left:50%; color:#666; font-style:italic; font-size:85% } #dragcatch { position:absolute; left:0; right:0; top:0; bottom:0; z-index:-1} </style> </head><body> <p>Showing how to drag points inside a transformation hierarchy.</p> <svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full"> <g transform="scale(1.2,0.8)"> <rect transform="translate(50,20) rotate(30)" class="drag resize" x="50" y="30" width="50" height="30" fill="#69c" /> <rect class="drag resize" x="5" y="5" width="90" height="50" fill="#c66" /> </g> </svg> <p id="footer"> Copyright © 2011 <a href="mailto:[email protected]">Gavin Kistner</a>. Comments/criticisms welcome. </p> <script type="text/javascript"><![CDATA[ var svg = document.getElementsByTagName(''svg'')[0]; var svgNS = svg.getAttribute(''xmlns''); var pt = svg.createSVGPoint(); function createOn(root,name,prop){ var el = document.createElementNS(svgNS,name); for (var a in prop) if (prop.hasOwnProperty(a)) el.setAttribute(a,prop[a]); return root.appendChild(el); } function rectCorner(rect){ pt.x = rect.x.animVal.value + rect.width.animVal.value; pt.y = rect.y.animVal.value + rect.height.animVal.value; return pt.matrixTransform(rect.getTransformToElement(svg)); } function pointIn(el,x,y){ pt.x = x; pt.y = y; return pt.matrixTransform(el.getTransformToElement(svg).inverse()); } function cursorPoint(evt){ pt.x = evt.clientX; pt.y = evt.clientY; return pt.matrixTransform(svg.getScreenCTM().inverse()); } // Make all rects resizable before drag, so the drag handles become drag for (var a=svg.querySelectorAll(''rect.resize''),i=0,len=a.length;i<len;++i){ (function(rect){ var dot = createOn(svg,''circle'',{''class'':''drag sizer'',cx:0,cy:0,r:5}); var moveDotToRect = function(){ var corner = rectCorner(rect); dot.setAttribute(''cx'',corner.x); dot.setAttribute(''cy'',corner.y); } moveDotToRect(); rect.addEventListener(''dragged'',moveDotToRect,false); dot.addEventListener(''dragged'',function(){ var rectXY = pointIn(rect,dot.cx.animVal.value,dot.cy.animVal.value); var w = Math.max( rectXY.x-rect.x.animVal.value, 1 ); var h = Math.max( rectXY.y-rect.y.animVal.value, 1 ); rect.setAttribute(''width'', w); rect.setAttribute(''height'',h); },false); })(a[i]); } for (var a=svg.querySelectorAll(''.drag''),i=0,len=a.length;i<len;++i){ (function(el){ var onmove; // make inner closure available for unregistration el.addEventListener(''mousedown'',function(e){ el.parentNode.appendChild(el); // move to top var x = el.tagName==''circle'' ? ''cx'' : ''x''; var y = el.tagName==''circle'' ? ''cy'' : ''y''; var mouseStart = cursorPoint(e); var elementStart = { x:el[x].animVal.value, y:el[y].animVal.value }; onmove = function(e){ var current = cursorPoint(e); pt.x = current.x - mouseStart.x; pt.y = current.y - mouseStart.y; var m = el.getTransformToElement(svg).inverse(); m.e = m.f = 0; pt = pt.matrixTransform(m); el.setAttribute(x,elementStart.x+pt.x); el.setAttribute(y,elementStart.y+pt.y); var dragEvent = document.createEvent("Event"); dragEvent.initEvent("dragged", true, true); el.dispatchEvent(dragEvent); }; document.body.addEventListener(''mousemove'',onmove,false); },false); document.body.addEventListener(''mouseup'',function(){ document.body.removeEventListener(''mousemove'',onmove,false); },false); })(a[i]); } ]]></script> <div id="dragcatch"></div> </body></html>

Quiero implementar la funcionalidad como svg-edit on rectangle element

  1. Girar rectángulo
  2. Cambio de tamaño
  3. Arrastrar

Al rotar el rectángulo SVG funciona bien, pero cuando quiero cambiar el tamaño del rectángulo, tiene un problema. Las coordenadas no funcionan bien; Utilizo la matriz de transformación para rotar targetelement.setAttribute(transform,rotate(45,cx,cy)) pero cuando el elemento ha sido rotado se mueven las coordenadas. También estoy usando la función inverse para invertir la matriz de transformación, resuelve el problema pero no funciona con la función de arrastre.


Para aquellos que usan Chrome, agreguen las siguientes líneas después

var pt = svg.createSVGPoint(); SVGElement.prototype.getTransformToElement = SVGElement.prototype.getTransformToElement || function(elem) { return elem.getScreenCTM().inverse().multiply(this.getScreenCTM()); };

Más información aquí: https://github.com/cpettitt/dagre-d3/issues/202