JSFiddle - React, Tailwind, and code Playground

by mamounothman

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.15.0/d3.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/interactjs@latest/dist/interact.min.js"></script>

CSS

svg {
  width: 100%;
  height: 100%;
  background-color: #2e9;
  
  -ms-touch-action: none;
      touch-action: none;
}
body { margin: 0; }

JavaScript

var svg = d3.select("body")
  .append("svg")
  .attr("width", 500)
  .attr("height", 300);
  
var g = svg.append('g')
  .attr('class', 'the_group');

g.append('rect')
  .attr('stroke', 'blue')
  .attr('x', 20)
  .attr('y', 20)
  .attr("width", 120)
  .attr("height", 120)
  .attr('stroke-width', 2)
  .attr('stroke', 'white')
  .attr('fill', 'grey');

g.append('text')
  .attr('x', 30)
  .attr('y', 50)
  .text('Some text');

var dx = 0, dy = 0;

interact('.the_group')
    .resizable({
      edges: {
        left: true,
        right: true,
        bottom: true,
        top: true
      }
    })

    .draggable({
      modifiers: [
        interact.modifiers.restrict({
          restriction: 'svg',
          endOnly: true
        })
      ]
    })

/*     .on('resizestart', function(event) {
      dx = (parseFloat(event.target.getAttribute('dx')) || 0);
      dy = (parseFloat(event.target.getAttribute('dy')) || 0);
    }) */

    .on('resizemove', function(event) {

      var target = event.target;
      var rect = target.childNodes[0];
      var text = target.childNodes[1];
      dx = (parseFloat(event.target.getAttribute('dx')) || 0);
      dy = (parseFloat(event.target.getAttribute('dy')) || 0);

      if (event.deltaRect.left != 0 || event.deltaRect.right != 0) 
            rect.setAttribute('width', event.rect.width + 'px');
                
      if (event.deltaRect.top != 0 || event.deltaRect.bottom != 0)
            rect.setAttribute('height', event.rect.height + 'px');

      // the user may move the top/left borders
      dx += event.deltaRect.left;
      dy += event.deltaRect.top;
      rect.setAttribute('transform',
        'translate(' + dx + ', ' + dy + ')')

      event.target.setAttribute('dx', dx);
      event.target.setAttribute('dy', dy);

    })

/* .on('dragstart', function(event) {
    
      dx = (parseFloat(event.target.getAttribute('dx')) || 0);
      dy = (parseFloat(event.target.getAttribute('dy')) || 0);
    }) */
    
    .on('dragmove',...