DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

DragLibrary //Java Script Object

09.09.2005
| 5927 views |
  • submit to reddit
        <a href="http://www.jsfromhell.com/dhtml/drag-library">

[UPDATED CODE AND HELP CAN BE FOUND HERE]
</a>

@REQUIRES <a href="http://www.jsfromhell.com/geral/event-listener">Event-Listener</a>


Code

<script type="text/javascript">
//Requires http://www.jsfromhell.com/geral/event-listener

//+ Jonas Raoni Soares Silva
//@ http://jsfromhell.com/dhtml/drag-library [v1.0]

DragLibrary = {
	e: null,
	diff: { x: 0, y: 0 },
	lineLength: function( x, y, x0, y0 ){
		return Math.sqrt( ( x -= x0 ) * x + ( y -= y0 ) * y );
	},
	dotLineLength: function( x, y, x0, y0, x1, y1, o ){
		if( o && !( o = function( x, y, x0, y0, x1, y1 ){
			if( !( x1 - x0 ) ) return { x: x0, y: y };
			else if( !( y1 - y0 ) ) return { x: x, y: y0 };
			var left, tg = -1 / ( ( y1 - y0 ) / ( x1 - x0 ) );
			return { x: left = ( x1 * ( x * tg - y + y0 ) + x0 * ( x * - tg + y - y1 ) ) / ( tg * ( x1 - x0 ) + y0 - y1 ), y: tg * left - tg * x + y };
		}( x, y, x0, y0, x1, y1 ), o.x >= Math.min( x0, x1 ) && o.x <= Math.max( x0, x1 ) && o.y >= Math.min( y0, y1 ) && o.y <= Math.max( y0, y1 ) ) ){
			var l1 = this.lineLength( x, y, x0, y0 ), l2 = this.lineLength( x, y, x1, y1 );
			return l1 > l2 ? l2 : l1;
		}
		else {
			var a = y0 - y1, b = x1 - x0, c = x0 * y1 - y0 * x1;
			return Math.abs( a * x + b * y + c ) / Math.sqrt( a * a + b * b );
		}
	},
	beginDrag: function ( e ){
		var dL = DragLibrary, o = dL.e = e.target;
		dL.diff = { x: o.offsetLeft - e.clientX, y: o.offsetTop - e.clientY };
		addEventListener( document, "mousemove", dL.drag );
		addEventListener( document, "mouseup", dL.endDrag );
	},
	drag: function( e ){
		var dL = DragLibrary, pt = dL.e.dragHandler.call( dL.e.dragHandler.data, e.clientX, e.clientY );
		dL.e.style.left = ( pt.x += dL.diff.x ) + "px";
		dL.e.style.top = ( pt.y += dL.diff.y ) + "px";
		dL.e.ondrag instanceof Function && dL.e.ondrag( e, pt.x, pt.y );
	},
	endDrag: function(){
		removeEventListener( document, "mouseup", DragLibrary.endDrag );
		removeEventListener( document, "mousemove", DragLibrary.drag );
	},
	setHandler: function( e, data, handler ){
		( e.dragHandler = handler ).data = data;
		e.style.position = "absolute";
		addEventListener( e, "mousedown", this.beginDrag );
	},
	freeDrag: function( e ){
		this.setHandler( e, null, function( x, y ){
			return { x: x, y: y };
		} );
	},
	squareDrag: function( e, x, y, width, height ){
		this.setHandler( e, { x: x, y: y, w: width, h: height }, function( x, y ){
			var o = this;
			return { x: x < o.x ? o.x : x > o.x + o.w ? o.x + o.w : x, y: y < o.y ? o.y : y > o.y + o.h ? o.y + o.h : y };
		});
	},
	circleDrag: function( e, x, y, ray ){
		this.setHandler( e, { x: x + ray, y: y + ray, ray: ray }, function( x, y ){
			var o = this, tg;
			return DragLibrary.lineLength( x, y, o.x, o.y ) > o.ray ?
				{ x: Math.cos( tg = Math.atan2( y - o.y, x - o.x ) ) * o.ray + o.x, y: Math.sin( tg ) * o.ray + o.y }
				: { x: x, y: y };
		} );
	},
	freeLineDrag: function( e, x, y, angle ){
		this.setHandler( e, { x: x, y: y, angle: angle }, function( x, y ){
			var o = this, tg = ( ( o.angle %= 360 ) < 0 && ( o.angle += 180 ), Math.tan( -o.angle * Math.PI / 180 ) );
			return o.angle < 45 || o.angle > 135 ? { x: x, y: ( x - o.x ) * tg + o.y } : { x: ( y - o.y ) / tg + o.x, y: y };
		} );
	},
	polylineDrag: function( e, x0, y0, x1, y1, etc, etc, etc ){
		for( var args = [].slice.call( arguments, 0 ), lines = []; args.length > 4; lines[lines.length] = { y1: args.pop(), x1: args.pop(), y0: args.pop(), x0: args.pop() } );
		this.setHandler( e, lines, function( x, y ){
			if( !this.length )
				return { x: x, y: y };
			var l, dL = DragLibrary, o = this[0], lower = { i: 0, l: dL.dotLineLength( x, y, o.x0, o.y0, o.x1, o.y1, 1 ) };
			for( var i in this )
				lower.l > ( l = dL.dotLineLength( x, y, ( o = this[i] ).x0, o.y0, o.x1, o.y1, 1 ) ) && ( lower = { i: i, l: l } );
			y = y < Math.min( ( o = this[lower.i] ).y0, o.y1 ) ? Math.min( o.y0, o.y1 ) : y > Math.max( o.y0, o.y1 ) ? Math.max( o.y0, o.y1 ) : y;
			x = x < Math.min( o.x0, o.x1 ) ? Math.min( o.x0, o.x1 ) : x > Math.max( o.x0, o.x1 ) ? Math.max( o.x0, o.x1 ) : x;
			return Math.abs( o.x0 - o.x1 ) < Math.abs( o.y0 - o.y1 ) ? { x: ( y * ( o.x0 - o.x1 ) - o.x0 * o.y1 + o.y0 * o.x1 ) / ( o.y0 - o.y1 ), y: y }
			: { x: x, y: ( x * ( o.y0 - o.y1 ) - o.y0 * o.x1 + o.x0 * o.y1 ) / ( o.x0 - o.x1 ) };
		} );
	}
};


Example

<style type="text/css">
.box{
	position: absolute;
	border: 1px solid #000;
	width: 50px;
	height: 50px;
	font: 12px monospace;
	font-weight: bold;
}
#circle{ background-color: #fee; }
#square{ background-color: #ccc; left: 50px; }
#freeLine{ background-color: #eff; left: 100px; }
#polyLine{ background-color: #efe; left: 150px; }
#free{ background-color: #eef; left: 200px; }
</style>


<script type="text/javascript">
//<![CDATA[

function newBox( id ){
	var r = document.body.appendChild( document.createElement( "div" ) ).appendChild( document.createTextNode( "kind: " + id ) ).parentNode;
	return ( r.setAttribute( "id", id ), r.setAttribute( "class", "box" ),	r.className = "box", r );
}

DragLibrary.freeDrag( newBox( "free" ) );
DragLibrary.polylineDrag( newBox( "polyLine" ), 0, 0, 200, 200, 200, 200, 400, 200, 400, 200, 600, 0 );
DragLibrary.freeLineDrag( newBox( "freeLine" ), 200, 400, 60 );
DragLibrary.squareDrag( newBox( "square" ), 200, 200, 400, 200 );
DragLibrary.circleDrag( newBox( "circle" ), 100, 100, 100 );

//]]>
</script>