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); |