SVG - Drag'n Drop

Exemplo de como se habilitar o drag'n drop em elementos SVG no HTML

by DOK_UA

HTML

<div class="position">
    <div>mouse client position <span id="clientPosition"></span></div>
    <div>mouse svg position <span id="svgPosition"></span></div>
    <div>center svg position <span id="svgCenter"></span></div>
</div>

<svg id="testSVG" preserveAspectRatio="none" version="1.1" viewBox="0 0 300 300" width="300" height="300">
    
<svg id="ProblematicSvgElement" viewBox="100 100 300 300">
    
    <g id='ellipseGroup' transform="translate(100,100)">
        <svg overflow="visible" type='stub' width='300' height='300'
            viewBox='0 0 300 300'>
            <g>
                <ellipse cx='150' cy='150' rx='30' ry='30' stroke='black'
                    fill='black' stroke-width='1px' />
       
            </g>
        </svg>
    </g>
    
    <circle id="mouse" fill="white" stroke="black" r="5" cx="100" cy="100"/>
    <circle id="center" fill="red" stroke="crimson" r="5" cx="100" cy="100"/>
</svg>
</svg>

CSS

.position {
    overflow: hidden;
    margin: 10px;
    margin-bottom: 0;
}

.position div {
    float: left;
    border: 1px solid #ddd;
    margin-right: 10px;
    padding: 2px 5px;
    width: 350px;
    position: relative;
    font-style: italic;
    color: #666;
}

.position span {
    position: absolute;
    top: 0;
    right: 0;
    padding: 2px 5px;
    color: #000;
    font-style: normal;
}

svg {
    border: 1px solid #ddd;
    margin: 10px;
}

JavaScript

// This demonstrates an SVG issue that first appeared in FF v13 and continues in
// FF14 plus the FF nightly build (http://nightly.mozilla.org/), as of 8/2/2012.  
// This demonstration works as expected on FF versions prior to v13, as well as
// current released versions of Chrome and IE.
//
// Expected Operation:  As you mouse-drag the ellipse the red circle should track
// the center of the svg group, over the “g” of the ellipse text, “Drag Me.”
//
// Actual operation (starting w/ FF v13): The red circle doesn’t track the center
// of the svg group.
//
// Adapted from Christoph Werner - http://jsfiddle.net/gonsfx/9mKCt/ for
// FF v13 bug: https://bugzilla.mozilla.org/show_bug.cgi?id=764738
// Uses techniques described on http://phrogz.net/svg/drag_under_transformation.xhtml
var svgElement = document.getElementById('testSVG'),
    followRectElement = document.getElementById('mouse'),
    clientPositionElement = document.getElementById('clientPosition'),
    svgPositionElement = document.getElementById('svgPosition'),
    ellipseGroup = document.getElementById('ellipseGroup'),
    center = document.getElementById('center'),
    svgCenter= document.getElementById('svgCenter');

var dragStart, mouseStart;

function cursorPoint(evt) {
    var pt = svgElement.createSVGPoint();
    pt.x = evt.clientX;
    pt.y = evt.clientY;
    return pt;
}

function getCenter(ele) {
    var Bbox = ele.getBBox();
    var transPoint = svgElement.createSVGPoint(); // Determine center of Group
    transPoint.x = Bbox.x + Bbox.width / 2;
    transPoint.y = Bbox.y + Bbox.height / 2;
    transPoint = transPoint.matrixTransform(ele.getScreenCTM()); // Map point to screen
    return transPoint.matrixTransform(ele.parentNode.getScreenCTM().inverse()); // Map point to parent element
}

function drag(evt) {

    // Get the mouse x/y position
    var current = cursorPoint(evt);

    // Determine mouse x/y change since the mousedown event
    var pt = svgElement.createSVGPoint();
    pt.x =...