Drag limiter
Limiting drag handler plugin (not tested much yet)
SVGElement.prototype.getTransformToElement = SVGElement.prototype.getTransformToElement || function(elem) {
return elem.getScreenCTM().inverse().multiply(this.getScreenCTM());
};
var s = Snap("#svgout");
s.attr({ viewBox: "0 0 100 100" });
(function() {
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.limitDrag = function( params ) {
this.data('dragParams', params );
return this.drag( limitMoveDrag, limitStartDrag );
};
function limitMoveDrag( dx, dy, ax, ay ) {
var params = this.data('dragParams');
var cursorPoint = this.getCursorPoint( ax, ay );
var pt = this.paper.node.createSVGPoint();
var ibb = this.data('ibb');
pt.x = cursorPoint.x - this.data('op').x;
pt.y = cursorPoint.y - this.data('op').y;
if( ibb.x2 + pt.x > params.maxx ) { pt.x = params.maxx - ibb.x2; }
if( ibb.y2 + pt.y > params.maxy ) { pt.y = params.maxy - ibb.y2; }
if( ibb.x + pt.x < params.minx ) { pt.x = params.minx - ibb.x; }
if( ibb.y + pt.y < params.miny ) { pt.y = params.miny - ibb.y; }
var localPt = this.globalToLocal( pt );
this.transform( this.data('ot').toTransformString() + "t" + [ localPt.x, localPt.y ] );
};
function limitStartDrag( x, y, ev ) {
this.data('ibb', this.getBBox());
this.data('op', this.getCursorPoint( x, y ));
this.data('ot', this.transform().localMatrix);
};
});
})();
var myCircle2 = s.circle(20,20,20).attr({ fill: 'blue' }).limitDrag({ x: 0, y: 0, minx: 0, miny: 0, maxx: 100, maxy: 100 });
var myRect = s.rect(0,0,30,30).attr({ fill: 'yellow' })
.limitDrag({ x: 0, y: 0, minx: 0, miny: 0, maxx: 100, maxy: 100 })
.transform('r45');
var corner1 = s.circle(0,0,2);
var corner2 = s.circle(100,100,2);