Drag test with transforms

Limiting drag handler plugin (not tested much yet)


var s = Snap("#svgout"); 
s.attr({ viewBox: "0 0 100 100" });
(function() {
 
  // Polyfill for getTransformToElement as Chrome 48 has deprecated it
  SVGElement.prototype.getTransformToElement = SVGElement.prototype.getTransformToElement || function(elem) {
    return elem.getScreenCTM().inverse().multiply(this.getScreenCTM());
  }; 

  Snap.plugin( function( Snap, Element, Paper, global ) {

        Element.prototype.globalToLocal = function( globalPoint ) {
                var globalToLocal = this.node.getTransformToElement( this.paper.node ).inverse();
                globalToLocal.e = globalToLocal.f = 0;
                return globalPoint.matrixTransform( globalToLocal );
        };

        Element.prototype.getCursorPoint = function( x, y ) {
                var pt = this.paper.node.createSVGPoint();      
                pt.x = x; pt.y = y;
                return pt.matrixTransform( this.paper.node.getScreenCTM().inverse()); 
        }

        Element.prototype.altDrag = function() {
                return this.drag( altMoveDrag, altStartDrag );
        };

        function altMoveDrag( xxdx, xxdy, ax, ay ) {
                var tdx, tdy;
                var cursorPoint = this.getCursorPoint( ax, ay );
                var pt = this.paper.node.createSVGPoint();

                pt.x = cursorPoint.x - this.data('op').x;
                pt.y = cursorPoint.y - this.data('op').y;

                var localPt = this.globalToLocal( pt );

                this.transform( this.data('ot').toTransformString() + "t" + [  localPt.x, localPt.y ] );

        };

        function altStartDrag( x, y, ev ) {
                this.data('ibb', this.getBBox());
                this.data('op', this.getCursorPoint( x, y ));
                this.data('ot', this.transform().localMatrix);
        };
  });
})();

var g = s.g().transform('r25');
var myCircle2 = s.circle(20,20,20).attr({ fill: 'blue' }).altDrag();
var myRect =   s.rect(0,0,30,30).attr({ fill: 'yellow' }).transform('r45').altDrag();
g.add( myRect );

   


        
The actual svg markup looks like this (when you've clicked on run)....