已翻译元素的位置

Position of translated elements

本文关键字:位置 元素 翻译      更新时间:2023-09-26

我目前正在开发一个支持使用此代码进行拖放的应用程序。 问题是我需要相应地移动连接的线,并且我无法弄清楚如何获取 X 和 Y 坐标来更改 x1/y1 对或 x2/y2 对以更新线。

我已经尝试使用其边界框询问元素的位置,并且数字与拖放后的实际位置不匹配。

任何想法如何实现?(给定代码中计算的信息,上面链接)

您可以将元素插入到 SVG"包装器"中,然后获取该元素的 bbox,而不是转换后的元素的 BBox。

我已经重新设计了您的示例并添加到 HTML5 文档中。我包含一个 svg 包装器元素,三行连接每个圆圈的中心。当它被拖动时,线条会跟随。如下所示。(注意:Chrome 挂在文本元素上)

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Drag And Drop</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body style='padding:10px;font-family:arial'>
<center>
<h4>Drag And Drop</h4>
<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:6px;'>
     A nice little demo of drag-and-drop functionality in SVG,
      written by Doug Schepers on February 16, 2004.
      Use or misuse this code however you wish.</div>
<table><tr>
<td>
<div id="svgDiv" style='background-color:lightgreen;width:600px;height:300px;'>
<svg width='100%' height='100%' xmlns='http://www.w3.org/2000/svg' id="mySVG"
   onload='Init(evt)'
   onmousedown='Grab(evt)'
   onmousemove='Drag(evt)'
   onmouseup='Drop(evt)'>
   <rect id='BackDrop' x='-10%' y='-10%' width='110%' height='110%' fill='none' pointer-events='all' />
   <circle id='BlueCircle' cx='25' cy='25' r='20' style='fill:blue; '/>
   <circle id='RedCircle' cx='125' cy='25' r='20' style='fill:red; '/>
   <circle id='OrangeCircle' cx='225' cy='25' r='20' style='fill:orange; '/>
   <text id='DraggableText' x='20' y='200' style='fill:red; font-size:18px; font-weight:bold;'>Draggable Text</text>

   <rect id='GreenRectangle' x='50' y='70' width='100' height='100' style='fill:green; '/>
   <g id='Folder'>
      <rect id='FolderRectangle' x='300' y='100' width='200' height='150' style='fill:tan; stroke:brown; stroke-width:3;'/>
   </g>
   <svg id="Wrapper" />
<line id=blueLine stroke=blue stroke=3 x1=25 y1=25 x2=25 y2=25 />
<line id=redLine stroke=red stroke=3 x1=125 y1=25  x2=125 y2=25 />
<line id=orangeLine stroke=orange stroke=3 x1=225 y1=25  x2=225 y2=25 />
</svg>
</div>
</td>
</tr></table>
  <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/FF23...*CH hangs<br /></div>
<script id=myScript>
      //var SVGDocument = null;
      //var SVGRoot = null;
      var TrueCoords = null;
      var GrabPoint = null;
      var BackDrop = null;
      var DragTarget = null;
      var DragLine = null;
      function Init(evt)
      {
         //SVGDocument = evt.target.ownerDocument;
         //SVGRoot = SVGDocument.documentElement;
         // these svg points hold x and y values...
         //    very handy, but they do not display on the screen (just so you know)
         TrueCoords = mySVG.createSVGPoint();
         GrabPoint = mySVG.createSVGPoint();
         // this will serve as the canvas over which items are dragged.
         //    having the drag events occur on the mousemove over a backdrop
         //    (instead of the dragged element) prevents the dragged element
         //    from being inadvertantly dropped when the mouse is moved rapidly
        // BackDrop = SVGDocument.getElementById('BackDrop');
      }
      function Grab(evt)
      {
         // find out which element we moused down on
         var targetElement = evt.target;
         // you cannot drag the background itself, so ignore any attempts to mouse down on it
         if ( BackDrop != targetElement )
         {
            //set the item moused down on as the element to be dragged
            DragTarget = targetElement;
            Wrapper.appendChild(DragTarget)
            if(DragTarget.id=="BlueCircle")
            DragLine=blueLine
            if(DragTarget.id=="RedCircle")
            DragLine=redLine
            if(DragTarget.id=="OrangeCircle")
            DragLine=orangeLine
            // move this element to the "top" of the display, so it is (almost)
            //    always over other elements (exception: in this case, elements that are
            //    "in the folder" (children of the folder group) with only maintain
            //    hierarchy within that group
            DragTarget.parentNode.appendChild( DragTarget );
            // turn off all pointer events to the dragged element, this does 2 things:
            //    1) allows us to drag text elements without selecting the text
            //    2) allows us to find out where the dragged element is dropped (see Drop)
            DragTarget.setAttributeNS(null, 'pointer-events', 'none');
            // we need to find the current position and translation of the grabbed element,
            //    so that we only apply the differential between the current location
            //    and the new location
            var transMatrix = DragTarget.getCTM();
            GrabPoint.x = TrueCoords.x - Number(transMatrix.e);
            GrabPoint.y = TrueCoords.y - Number(transMatrix.f);
         }
      };

      function Drag(evt)
      {
         // account for zooming and panning
         GetTrueCoords(evt);
         // if we don't currently have an element in tow, don't do anything
         if (DragTarget)
         {
            // account for the offset between the element's origin and the
            //    exact place we grabbed it... this way, the drag will look more natural
            var newX = TrueCoords.x - GrabPoint.x;
            var newY = TrueCoords.y - GrabPoint.y;
                BB=Wrapper.getBBox()
            var bbx=BB.x
            var bby=BB.y
            var bbw=BB.width
            var bbh=BB.height
            Cx=bbx+.5*bbw
            Cy=bby+.5*bbh
            DragLine.x2.baseVal.value=Cx
            DragLine.y2.baseVal.value=Cy
            // apply a new tranform translation to the dragged element, to display
            //    it in its new location
            DragTarget.setAttributeNS(null, 'transform', 'translate(' + newX + ',' + newY + ')');
         }
      };

      function Drop(evt)
      {
         // if we aren't currently dragging an element, don't do anything
         if ( DragTarget )
         {     mySVG.appendChild(DragTarget) //--remove from Wrapper---
            // since the element currently being dragged has its pointer-events turned off,
            //    we are afforded the opportunity to find out the element it's being dropped on
            var targetElement = evt.target;
            // turn the pointer-events back on, so we can grab this item later
            DragTarget.setAttributeNS(null, 'pointer-events', 'all');
            if ( 'Folder' == targetElement.parentNode.id )
            {
               // if the dragged element is dropped on an element that is a child
               //    of the folder group, it is inserted as a child of that group
               targetElement.parentNode.appendChild( DragTarget );
               //alert(DragTarget.id + ' has been dropped into a folder, and has been inserted as a child of the containing group.');
            }
            else
            {
               // for this example, you cannot drag an item out of the folder once it's in there;
               //    however, you could just as easily do so here
               //alert(DragTarget.id + ' has been dropped on top of ' + targetElement.id);
            }
            // set the global variable to null, so nothing will be dragged until we
            //    grab the next element
            DragTarget = null;
         }

            svgSourceValue.value=svgDiv.innerHTML
      };

      function GetTrueCoords(evt)
      {
         // find the current zoom level and pan setting, and adjust the reported
         //    mouse position accordingly
         var newScale = mySVG.currentScale;
         var translation = mySVG.currentTranslate;
         TrueCoords.x = (evt.clientX - translation.x)/newScale;
         TrueCoords.y = (evt.clientY - translation.y)/newScale;
      };

</script>
<script>
document.addEventListener("onload",init(),false)
function init()
{
    svgSourceValue.value=svgDiv.innerHTML
    jsValue.value=myScript.text
}
</script>
</body>
</html>