JSFiddle - React, Tailwind, and code Playground

by Jason Normandin

HTML

<?xml version='1.0' standalone='no'?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 20001102//EN'
  'http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd'>
<svg width='100%' height='100%' xmlns='http://www.w3.org/2000/svg'
   onload='Init(evt)'
   onmousedown='Grab(evt)'
   onmousemove='Drag(evt)'
   onmouseup='Drop(evt)'>

   <title>Drag And Drop</title>

   <desc>
      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.
   </desc> 


<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>

JavaScript

<script><![CDATA[
      var SVGDocument = null;
      var SVGRoot = null;

      var TrueCoords = null;
      var GrabPoint = null;
      var BackDrop = null;
      var DragTarget = 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 = SVGRoot.createSVGPoint();
         GrabPoint = SVGRoot.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;

            // 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',...