JSFiddle - React, Tailwind, and code Playground

by dfmx123

HTML

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150">
  <g id="grid">
    <path d="M0,50 L150,50 M0,100 L150,100 M50,0 L50,150 M100,0 L100,150" />
    <path d="M0,25 L150,25 M0,75 L150,75 M0,125 L150,125
             M25,0 L25,150 M75,0 L75,150 M125,0 L125,150" style="opacity:0.4" />
  </g>
  <circle cx="100" cy="100" r="12.5" />
  <rect width="50" height="50" transform="translate(75,75) rotate(45) translate(-25,-25) " />
</svg>

CSS

svg { display:block; margin:1em auto; width:400px; height:400px; border:1px solid #ccc }
* { stroke:black; fill:white; opacity:0.8; vector-effect:non-scaling-stroke }
rect,circle { stroke:red; fill:yellow }
.bounding-box { stroke:blue; fill:rgba(0,0,200,0.3) }

JavaScript

var r = document.querySelector('rect'),
    c = document.querySelector('circle');

var g = document.querySelector('g');
showTransformedBox(c);
showTransformedBox(r);

function showTransformedBox(el) {
  var bb  = el.getBBox(),
      svg = el.ownerSVGElement,
      r   = document.createElementNS(svg.namespaceURI,'rect'),
      svgRoot = document.querySelector('svg');
    var g = el.ParentNode;
    var m = el.getTransformToElement(svgRoot.querySelector('g'));
    console.debug(m);
    var p = svgRoot.createSVGPoint();
    var p2, maxX, maxY, minX, minY;
    p.x = bb.x;
    p.y = bb.y;
    p2 = p.matrixTransform(m);
    minX = maxX = p2.x;
    minY = maxY = p2.y;
    
    p.x = bb.x + bb.width;
    p.y = bb.y;
    p2 = p.matrixTransform(m);
    minX = minX > p2.x ? p2.x : minX; 
    maxX = maxX < p2.x ? p2.x : maxX;
    minY = minY > p2.y ? p2.y : minY; 
    maxY = maxY < p2.y ? p2.y : maxY;

    p.x = bb.x;
    p.y = bb.y + bb.height;
    p2 = p.matrixTransform(m);
    minX = minX > p2.x ? p2.x : minX; 
    maxX = maxX < p2.x ? p2.x : maxX;
    minY = minY > p2.y ? p2.y : minY; 
    maxY = maxY < p2.y ? p2.y : maxY;

    p.x = bb.x + bb.width;
    p.y = bb.y + bb.height;
    p2 = p.matrixTransform(m);
    minX = minX > p2.x ? p2.x : minX; 
    maxX = maxX < p2.x ? p2.x : maxX;
    minY = minY > p2.y ? p2.y : minY; 
    maxY = maxY < p2.y ? p2.y : maxY;

    r.setAttribute('x',      minX );
    r.setAttribute('y',      minY );
    r.setAttribute('width',  maxX - minX );
    r.setAttribute('height', maxY - minY );
    r.setAttribute('class','bounding-box');
    svg.appendChild(r);    
}