Snap Docs  More SVG Dabbles

Drag limiter

Limiting drag handler plugin (not tested much yet)


var s = Snap("#svgout"); 
s.attr({ viewBox: "0 0 100 100" });
(function() {

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

	Element.prototype.getInversePoint = 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 );
		this.data('x', params.x); this.data('y', params.y);
		this.drag( limitMoveDrag, limitStartDrag );
		this.data('ot', this.transform().localMatrix);
		return this;	
	};

	function limitMoveDrag( xxdx, xxdy, ax, ay ) {
		var tdx, tdy;
		var params = this.data('dragParams');
		var pt = this.getInversePoint( ax, ay );
		var dx = pt.x - this.data('op').x;
		var dy = pt.y - this.data('op').y;

		var ibb = this.data('ibb');
		if( ibb.x + ibb.width + +dx > params.maxx ) 
			{ dx = params.maxx - (ibb.x + ibb.width) };

		if( ibb.y + ibb.height + +dy > params.maxy ) 
			{ dy = params.maxy - (ibb.y + ibb.height)  };
		if( ibb.x + +dx < params.minx ) { dx = params.minx - ibb.x; };
        	if( ibb.y + +dy < params.miny ) { dy = params.miny - ibb.y; };

		this.transform(  "t" + [  dx, dy ] +   this.data('ot').toTransformString());
	};

	function limitStartDrag( x, y, ev ) {
		var pt = this.getInversePoint( x, y );
		this.data('ibb', this.getBBox());
		this.data('op', pt);
		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);

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