Created
November 21, 2014 14:46
-
-
Save newbie78/18c1652c249120aafc67 to your computer and use it in GitHub Desktop.
mootools 1.5.1 drag&drop with mobile support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var Drag = new Class({ | |
| Implements: [Events, Options], | |
| options: {/* | |
| onBeforeStart: function(thisElement){}, | |
| onStart: function(thisElement, event){}, | |
| onSnap: function(thisElement){}, | |
| onDrag: function(thisElement, event){}, | |
| onCancel: function(thisElement){}, | |
| onComplete: function(thisElement, event){},*/ | |
| snap: 6, | |
| unit: 'px', | |
| grid: false, | |
| style: true, | |
| limit: false, | |
| handle: false, | |
| invert: false, | |
| preventDefault: false, | |
| stopPropagation: false, | |
| compensateScroll: false, | |
| modifiers: {x: 'left', y: 'top'} | |
| }, | |
| initialize: function(){ | |
| var params = Array.link(arguments, { | |
| 'options': Type.isObject, | |
| 'element': function(obj){ | |
| return obj != null; | |
| } | |
| }); | |
| this.element = document.id(params.element); | |
| this.document = this.element.getDocument(); | |
| this.setOptions(params.options || {}); | |
| var htype = typeOf(this.options.handle); | |
| this.handles = ((htype == 'array' || htype == 'collection') ? $$(this.options.handle) : document.id(this.options.handle)) || this.element; | |
| this.mouse = {'now': {}, 'pos': {}}; | |
| this.value = {'start': {}, 'now': {}}; | |
| this.offsetParent = (function(el){ | |
| var offsetParent = el.getOffsetParent(); | |
| var isBody = !offsetParent || (/^(?:body|html)$/i).test(offsetParent.tagName); | |
| return isBody ? window : document.id(offsetParent); | |
| })(this.element); | |
| this.selection = 'selectstart' in document ? 'selectstart' : 'mousedown'; | |
| this.compensateScroll = {start: {}, diff: {}, last: {}}; | |
| if ('ondragstart' in document && !('FileReader' in window) && !Drag.ondragstartFixed){ | |
| document.ondragstart = Function.from(false); | |
| Drag.ondragstartFixed = true; | |
| } | |
| this.bound = { | |
| start: this.start.bind(this), | |
| check: this.check.bind(this), | |
| drag: this.drag.bind(this), | |
| stop: this.stop.bind(this), | |
| cancel: this.cancel.bind(this), | |
| eventStop: Function.from(false), | |
| scrollListener: this.scrollListener.bind(this) | |
| }; | |
| this.attach(); | |
| }, | |
| attach: function(){ | |
| this.handles.addEvent('mousedown', this.bound.start); | |
| this.handles.addEvent('touchstart', this.bound.start); | |
| if (this.options.compensateScroll) this.offsetParent.addEvent('scroll', this.bound.scrollListener); | |
| return this; | |
| }, | |
| detach: function(){ | |
| this.handles.removeEvent('mousedown', this.bound.start); | |
| this.handles.removeEvent('touchstart', this.bound.start); | |
| if (this.options.compensateScroll) this.offsetParent.removeEvent('scroll', this.bound.scrollListener); | |
| return this; | |
| }, | |
| scrollListener: function(){ | |
| if (!this.mouse.start) return; | |
| var newScrollValue = this.offsetParent.getScroll(); | |
| if (this.element.getStyle('position') == 'absolute'){ | |
| var scrollDiff = this.sumValues(newScrollValue, this.compensateScroll.last, -1); | |
| this.mouse.now = this.sumValues(this.mouse.now, scrollDiff, 1); | |
| } else { | |
| this.compensateScroll.diff = this.sumValues(newScrollValue, this.compensateScroll.start, -1); | |
| } | |
| if (this.offsetParent != window) this.compensateScroll.diff = this.sumValues(this.compensateScroll.start, newScrollValue, -1); | |
| this.compensateScroll.last = newScrollValue; | |
| this.render(this.options); | |
| }, | |
| sumValues: function(alpha, beta, op){ | |
| var sum = {}, options = this.options; | |
| for (z in options.modifiers){ | |
| if (!options.modifiers[z]) continue; | |
| sum[z] = alpha[z] + beta[z] * op; | |
| } | |
| return sum; | |
| }, | |
| start: function(event){ | |
| var options = this.options; | |
| if (event.rightClick) return; | |
| if (options.preventDefault) event.preventDefault(); | |
| if (options.stopPropagation) event.stopPropagation(); | |
| this.compensateScroll.start = this.compensateScroll.last = this.offsetParent.getScroll(); | |
| this.compensateScroll.diff = {x: 0, y: 0}; | |
| this.mouse.start = event.page; | |
| this.fireEvent('beforeStart', this.element); | |
| var limit = options.limit; | |
| this.limit = {x: [], y: []}; | |
| var z, coordinates, offsetParent = this.offsetParent == window ? null : this.offsetParent; | |
| for (z in options.modifiers){ | |
| if (!options.modifiers[z]) continue; | |
| var style = this.element.getStyle(options.modifiers[z]); | |
| // Some browsers (IE and Opera) don't always return pixels. | |
| if (style && !style.match(/px$/)){ | |
| if (!coordinates) coordinates = this.element.getCoordinates(offsetParent); | |
| style = coordinates[options.modifiers[z]]; | |
| } | |
| if (options.style) this.value.now[z] = (style || 0).toInt(); | |
| else this.value.now[z] = this.element[options.modifiers[z]]; | |
| if (options.invert) this.value.now[z] *= -1; | |
| this.mouse.pos[z] = event.page[z] - this.value.now[z]; | |
| if (limit && limit[z]){ | |
| var i = 2; | |
| while (i--){ | |
| var limitZI = limit[z][i]; | |
| if (limitZI || limitZI === 0) this.limit[z][i] = (typeof limitZI == 'function') ? limitZI() : limitZI; | |
| } | |
| } | |
| } | |
| if (typeOf(this.options.grid) == 'number') this.options.grid = { | |
| x: this.options.grid, | |
| y: this.options.grid | |
| }; | |
| var events = { | |
| mousemove: this.bound.check, | |
| mouseup: this.bound.cancel, | |
| touchmove: this.bound.check, | |
| touchend: this.bound.cancel | |
| }; | |
| events[this.selection] = this.bound.eventStop; | |
| this.document.addEvents(events); | |
| }, | |
| check: function(event){ | |
| if (this.options.preventDefault) event.preventDefault(); | |
| var distance = Math.round(Math.sqrt(Math.pow(event.page.x - this.mouse.start.x, 2) + Math.pow(event.page.y - this.mouse.start.y, 2))); | |
| if (distance > this.options.snap){ | |
| this.cancel(); | |
| this.document.addEvents({ | |
| mousemove: this.bound.drag, | |
| mouseup: this.bound.stop, | |
| touchmove: this.bound.drag, | |
| touchend: this.bound.stop | |
| }); | |
| this.fireEvent('start', [this.element, event]).fireEvent('snap', this.element); | |
| } | |
| }, | |
| drag: function(event){ | |
| var options = this.options; | |
| if (options.preventDefault) event.preventDefault(); | |
| this.mouse.now = this.sumValues(event.page, this.compensateScroll.diff, -1); | |
| this.render(options); | |
| this.fireEvent('drag', [this.element, event]); | |
| }, | |
| render: function(options){ | |
| for (var z in options.modifiers){ | |
| if (!options.modifiers[z]) continue; | |
| this.value.now[z] = this.mouse.now[z] - this.mouse.pos[z]; | |
| if (options.invert) this.value.now[z] *= -1; | |
| if (options.limit && this.limit[z]){ | |
| if ((this.limit[z][1] || this.limit[z][1] === 0) && (this.value.now[z] > this.limit[z][1])){ | |
| this.value.now[z] = this.limit[z][1]; | |
| } else if ((this.limit[z][0] || this.limit[z][0] === 0) && (this.value.now[z] < this.limit[z][0])){ | |
| this.value.now[z] = this.limit[z][0]; | |
| } | |
| } | |
| if (options.grid[z]) this.value.now[z] -= ((this.value.now[z] - (this.limit[z][0]||0)) % options.grid[z]); | |
| if (options.style) this.element.setStyle(options.modifiers[z], this.value.now[z] + options.unit); | |
| else this.element[options.modifiers[z]] = this.value.now[z]; | |
| } | |
| }, | |
| cancel: function(event){ | |
| this.document.removeEvents({ | |
| mousemove: this.bound.check, | |
| mouseup: this.bound.cancel, | |
| touchmove: this.bound.check, | |
| touchend: this.bound.cancel | |
| }); | |
| if (event){ | |
| this.document.removeEvent(this.selection, this.bound.eventStop); | |
| this.fireEvent('cancel', this.element); | |
| } | |
| }, | |
| stop: function(event){ | |
| var events = { | |
| mousemove: this.bound.drag, | |
| mouseup: this.bound.stop, | |
| touchmove: this.bound.drag, | |
| touchend: this.bound.stop | |
| }; | |
| events[this.selection] = this.bound.eventStop; | |
| this.document.removeEvents(events); | |
| this.mouse.start = null; | |
| if (event) this.fireEvent('complete', [this.element, event]); | |
| } | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment