SVG BBox Testing

by Lorenzo Brutti

HTML

<div class="container">
<svg 
viewBox="0 0 500 400"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
         
 <ellipse id="blue-ellipse1"
        transform="translate(120 80) rotate(90) scale(2)" 
        rx="25" ry="10"
        fill="white" stroke="blue" stroke-width="2"  />

</svg>
</div>

CSS

.marker {
    position: absolute;
    width: 12px;
    height: 12px;
    text-align: center;
    color: white;
    background: black;
    font-family: sans-serif;
    font-size: 50%;
}

.container {
  width:300px;
  height: 300px;
}

JavaScript

var RAD2DEG = 180 / Math.PI,
    svg = $('svg')[0];

function makePlacementMarker(name, point) {
    // make a marker at a particular point
    $('<div class="marker"/>').css({
            left: point.x - 6,
            top: point.y - 6
        })
        .html(name)
        .appendTo('body');
}

function drawMarkers(selector) {
    // get the element
    var el = $(selector)[0],
        pt = svg.createSVGPoint();
    
    // get the bounding box and matrix
    var bbox = el.getBBox(),
        matrix = el.getScreenCTM(),
        halfWidth = bbox.width / 2,
        halfHeight = bbox.height / 2,
        placements = [],
        placementKeys = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];
    
    function pushPlacement() {
        placements.push(pt.matrixTransform(matrix));
    }
    
    // get bbox corners and midpoints
    pt.x = bbox.x;
    pt.y = bbox.y;
    pushPlacement();
    pt.x += halfWidth;
    pushPlacement();
    pt.x += halfWidth;
    pushPlacement();
    pt.y += halfHeight;
    pushPlacement();
    pt.y += halfHeight;
    pushPlacement();
    pt.x -= halfWidth;
    pushPlacement();
    pt.x -= halfWidth;
    pushPlacement();
    pt.y -= halfHeight;
    pushPlacement();
    
    // determine rotation
    var rotation, steps;
    if (placements[0].y != placements[1].y || placements[0].x != placements[7].x) {
        rotation = Math.atan2( matrix.b, matrix.a ) * RAD2DEG;
        steps = Math.ceil(((rotation % 360) - 22.5) / 45);
        if (steps < 1) steps += 8
        while (steps--) {
            placementKeys.push(placementKeys.shift());
        }
    }
    
    var placementMap = {},
        x;
    for (x=0; x<placements.length; x++) {
        placementMap[placementKeys[x]] = placements[x];
        makePlacementMarker(placementKeys[x], placements[x]);
   ...