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