201 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
		
			
		
	
	
			201 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
|  | /* | ||
|  | jQuery grab  | ||
|  | https://github.com/jussi-kalliokoski/jQuery.grab
 | ||
|  | Ported from Jin.js::gestures    | ||
|  | https://github.com/jussi-kalliokoski/jin.js/
 | ||
|  | Created by Jussi Kalliokoski | ||
|  | Licensed under MIT License.  | ||
|  | 
 | ||
|  | Includes fix for IE | ||
|  | */ | ||
|  | 
 | ||
|  | 
 | ||
|  | (function($){ | ||
|  | 	var	extend		= $.extend, | ||
|  | 		mousedown	= 'mousedown', | ||
|  | 		mousemove	= 'mousemove', | ||
|  | 		mouseup		= 'mouseup', | ||
|  | 		touchstart	= 'touchstart', | ||
|  | 		touchmove	= 'touchmove', | ||
|  | 		touchend	= 'touchend', | ||
|  | 		touchcancel	= 'touchcancel'; | ||
|  | 
 | ||
|  | 	function unbind(elem, type, func){ | ||
|  | 		if (type.substr(0,5) !== 'touch'){ // A temporary fix for IE8 data passing problem in Jin.
 | ||
|  | 			return $(elem).unbind(type, func); | ||
|  | 		} | ||
|  | 		var fnc, i; | ||
|  | 		for (i=0; i<bind._binds.length; i++){ | ||
|  | 			if (bind._binds[i].elem === elem && bind._binds[i].type === type && bind._binds[i].func === func){ | ||
|  | 				if (document.addEventListener){ | ||
|  | 					elem.removeEventListener(type, bind._binds[i].fnc, false); | ||
|  | 				} else { | ||
|  | 					elem.detachEvent('on'+type, bind._binds[i].fnc); | ||
|  | 				} | ||
|  | 				bind._binds.splice(i--, 1); | ||
|  | 			} | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	function bind(elem, type, func, pass){ | ||
|  | 		if (type.substr(0,5) !== 'touch'){ // A temporary fix for IE8 data passing problem in Jin.
 | ||
|  | 			return $(elem).bind(type, pass, func); | ||
|  | 		} | ||
|  | 		var fnc, i; | ||
|  | 		if (bind[type]){ | ||
|  | 			return bind[type].bind(elem, type, func, pass); | ||
|  | 		} | ||
|  | 		fnc = function(e){ | ||
|  | 			if (!e){ // Fix some ie bugs...
 | ||
|  | 				e = window.event; | ||
|  | 			} | ||
|  | 			if (!e.stopPropagation){ | ||
|  | 				e.stopPropagation = function(){ this.cancelBubble = true; }; | ||
|  | 			} | ||
|  | 			e.data = pass; | ||
|  | 			func.call(elem, e); | ||
|  | 		}; | ||
|  | 		if (document.addEventListener){ | ||
|  | 			elem.addEventListener(type, fnc, false); | ||
|  | 		} else { | ||
|  | 			elem.attachEvent('on' + type, fnc); | ||
|  | 		} | ||
|  | 		bind._binds.push({elem: elem, type: type, func: func, fnc: fnc}); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	function grab(elem, options) | ||
|  | 	{ | ||
|  | 		var data = { | ||
|  | 			move: {x: 0, y: 0}, | ||
|  | 			offset: {x: 0, y: 0}, | ||
|  | 			position: {x: 0, y: 0}, | ||
|  | 			start: {x: 0, y: 0}, | ||
|  | 			affects: document.documentElement, | ||
|  | 			stopPropagation: false, | ||
|  | 			preventDefault: true, | ||
|  | 			touch: true // Implementation unfinished, and doesn't support multitouch
 | ||
|  | 		}; | ||
|  | 		extend(data, options); | ||
|  | 		data.element = elem; | ||
|  | 		bind(elem, mousedown, mouseDown, data); | ||
|  | 		if (data.touch){ | ||
|  | 			bind(elem, touchstart, touchStart, data); | ||
|  | 		} | ||
|  | 	} | ||
|  | 	function ungrab(elem){ | ||
|  | 		unbind(elem, mousedown, mousedown); | ||
|  | 	} | ||
|  | 	function mouseDown(e){ | ||
|  | 		e.data.position.x = e.pageX; | ||
|  | 		e.data.position.y = e.pageY; | ||
|  | 		e.data.start.x = e.pageX; | ||
|  | 		e.data.start.y = e.pageY; | ||
|  | 		e.data.event = e; | ||
|  | 		if (e.data.onstart && e.data.onstart.call(e.data.element, e.data)){ | ||
|  | 			return; | ||
|  | 		} | ||
|  | 		if (e.preventDefault && e.data.preventDefault){ | ||
|  | 			e.preventDefault(); | ||
|  | 		} | ||
|  | 		if (e.stopPropagation && e.data.stopPropagation){ | ||
|  | 			e.stopPropagation(); | ||
|  | 		} | ||
|  | 		bind(e.data.affects, mousemove, mouseMove, e.data); | ||
|  | 		bind(e.data.affects, mouseup, mouseUp, e.data); | ||
|  | 	} | ||
|  | 	function mouseMove(e){ | ||
|  | 		if (e.preventDefault && e.data.preventDefault){ | ||
|  | 			e.preventDefault(); | ||
|  | 		} | ||
|  | 		if (e.stopPropagation && e.data.preventDefault){ | ||
|  | 			e.stopPropagation(); | ||
|  | 		} | ||
|  | 		e.data.move.x = e.pageX - e.data.position.x; | ||
|  | 		e.data.move.y = e.pageY - e.data.position.y; | ||
|  | 		e.data.position.x = e.pageX; | ||
|  | 		e.data.position.y = e.pageY; | ||
|  | 		e.data.offset.x = e.pageX - e.data.start.x; | ||
|  | 		e.data.offset.y = e.pageY - e.data.start.y; | ||
|  | 		e.data.event = e; | ||
|  | 		if (e.data.onmove){ | ||
|  | 			e.data.onmove.call(e.data.element, e.data); | ||
|  | 		} | ||
|  | 	} | ||
|  | 	function mouseUp(e){ | ||
|  | 		if (e.preventDefault && e.data.preventDefault){ | ||
|  | 			e.preventDefault(); | ||
|  | 		} | ||
|  | 		if (e.stopPropagation && e.data.stopPropagation){ | ||
|  | 			e.stopPropagation(); | ||
|  | 		} | ||
|  | 		unbind(e.data.affects, mousemove, mouseMove); | ||
|  | 		unbind(e.data.affects, mouseup, mouseUp); | ||
|  | 		e.data.event = e; | ||
|  | 		if (e.data.onfinish){ | ||
|  | 			e.data.onfinish.call(e.data.element, e.data); | ||
|  | 		} | ||
|  | 	} | ||
|  | 	function touchStart(e){ | ||
|  | 		e.data.position.x = e.touches[0].pageX; | ||
|  | 		e.data.position.y = e.touches[0].pageY; | ||
|  | 		e.data.start.x = e.touches[0].pageX; | ||
|  | 		e.data.start.y = e.touches[0].pageY; | ||
|  | 		e.data.event = e; | ||
|  | 		if (e.data.onstart && e.data.onstart.call(e.data.element, e.data)){ | ||
|  | 			return; | ||
|  | 		} | ||
|  | 		if (e.preventDefault && e.data.preventDefault){ | ||
|  | 			e.preventDefault(); | ||
|  | 		} | ||
|  | 		if (e.stopPropagation && e.data.stopPropagation){ | ||
|  | 			e.stopPropagation(); | ||
|  | 		} | ||
|  | 		bind(e.data.affects, touchmove, touchMove, e.data); | ||
|  | 		bind(e.data.affects, touchend, touchEnd, e.data); | ||
|  | 	} | ||
|  | 	function touchMove(e){ | ||
|  | 		if (e.preventDefault && e.data.preventDefault){ | ||
|  | 			e.preventDefault(); | ||
|  | 		} | ||
|  | 		if (e.stopPropagation && e.data.stopPropagation){ | ||
|  | 			e.stopPropagation(); | ||
|  | 		} | ||
|  | 		e.data.move.x = e.touches[0].pageX - e.data.position.x; | ||
|  | 		e.data.move.y = e.touches[0].pageY - e.data.position.y; | ||
|  | 		e.data.position.x = e.touches[0].pageX; | ||
|  | 		e.data.position.y = e.touches[0].pageY; | ||
|  | 		e.data.offset.x = e.touches[0].pageX - e.data.start.x; | ||
|  | 		e.data.offset.y = e.touches[0].pageY - e.data.start.y; | ||
|  | 		e.data.event = e; | ||
|  | 		if (e.data.onmove){ | ||
|  | 			e.data.onmove.call(e.data.elem, e.data); | ||
|  | 		} | ||
|  | 	} | ||
|  | 	function touchEnd(e){ | ||
|  | 		if (e.preventDefault && e.data.preventDefault){ | ||
|  | 			e.preventDefault(); | ||
|  | 		} | ||
|  | 		if (e.stopPropagation && e.data.stopPropagation){ | ||
|  | 			e.stopPropagation(); | ||
|  | 		} | ||
|  | 		unbind(e.data.affects, touchmove, touchMove); | ||
|  | 		unbind(e.data.affects, touchend, touchEnd); | ||
|  | 		e.data.event = e; | ||
|  | 		if (e.data.onfinish){ | ||
|  | 			e.data.onfinish.call(e.data.element, e.data); | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	bind._binds = []; | ||
|  | 
 | ||
|  | 	$.fn.grab = function(a, b){ | ||
|  | 		return this.each(function(){ | ||
|  | 			return grab(this, a, b); | ||
|  | 		}); | ||
|  | 	}; | ||
|  | 	$.fn.ungrab = function(a){ | ||
|  | 		return this.each(function(){ | ||
|  | 			return ungrab(this, a); | ||
|  | 		}); | ||
|  | 	}; | ||
|  | })(jQuery); |