JSFiddle - React, Tailwind, and code Playground

by DOK_UA

HTML

<svg xmlns="http://www.w3.org/2000/svg"
     viewBox="0 0 30 20"
     onload="makeDraggable(evt)">
   
    
<circle id="rotateable" cx="150" cy="150" r="150" stroke="black" stroke-width="1" fill="url(#grad2)" />
<circle id="rotate" cx="150" cy="150" r="140" stroke="black" stroke-width="1" fill="blue" />
<circle id="joy" class="draggable confine" cx="150" cy="150" r="50" stroke="black" stroke-width="3" fill="green" /> 


</svg>

CSS

.static {
        cursor: not-allowed;
      }
      .draggable {
        cursor: move;
      }

JavaScript

function makeDraggable(evt) {
        var svg = evt.target;

        svg.addEventListener('mousedown', startDrag);
        svg.addEventListener('mousemove', drag);
        svg.addEventListener('mouseup', endDrag);
        svg.addEventListener('mouseleave', endDrag);
        svg.addEventListener('touchstart', startDrag);
        svg.addEventListener('touchmove', drag);
        svg.addEventListener('touchend', endDrag);
        svg.addEventListener('touchleave', endDrag);
        svg.addEventListener('touchcancel', endDrag);

        var selectedElement, offset, transform,
            bbox, minX, maxX, minY, maxY, confined;

        var boundaryX1 = 10.5;
        var boundaryX2 = 30;
        var boundaryY1 = 2.2;
        var boundaryY2 = 19.2;

        function getMousePosition(evt) {
          var CTM = svg.getScreenCTM();
          if (evt.touches) { evt = evt.touches[0]; }
          return {
            x: (evt.clientX - CTM.e) / CTM.a,
            y: (evt.clientY - CTM.f) / CTM.d
          };
        }

        function startDrag(evt) {
          if (evt.target.classList.contains('draggable')) {
            selectedElement = evt.target;
            offset = getMousePosition(evt);

            // Make sure the first transform on the element is a translate transform
            var transforms = selectedElement.transform.baseVal;

            if (transforms.length === 0 || transforms.getItem(0).type !== SVGTransform.SVG_TRANSFORM_TRANSLATE) {
              // Create an transform that translates by (0, 0)
              var translate = svg.createSVGTransform();
              translate.setTranslate(0, 0);
              selectedElement.transform.baseVal.insertItemBefore(translate, 0);
            }

            // Get initial translation
            transform = transforms.getItem(0);
            offset.x -= transform.matrix.e;
            offset.y -= transform.matrix.f;

            confined = evt.target.classList.contains('confine');
            if (confined) {
     ...