wpfw_ewei_shopv2/plugin/app/static/js/jquery.udraggable.js
2023-02-14 19:57:32 +08:00

353 lines
11 KiB
JavaScript

/*
* jQuery udraggable plugin v0.3.0
* Copyright (c) 2013-2014 Grant McLean (grant@mclean.net.nz)
*
* Homepage: https://github.com/grantm/jquery-udraggable
*
* Dual licensed under the MIT and GPL (v2.0 or later) licenses:
* http://opensource.org/licenses/MIT
* http://opensource.org/licenses/GPL-2.0
*
* This library requires Michael S. Mikowski's unified mouse and touch
* event plugin: https://github.com/mmikowski/jquery.event.ue
*
*/
(function ($) {
"use strict";
var floor = Math.floor;
var min = Math.min;
var max = Math.max;
window.requestAnimationFrame = window.requestAnimationFrame || function (work) {
return setTimeout(work, 10);
};
window.cancelAnimationFrame = window.cancelAnimationFrame || function (id) {
return clearTimeout(id);
};
// Constructor function
var UDraggable = function (el, options) {
var that = this;
this.el = el;
this.$el = $(el);
this.options = $.extend({}, $.fn.udraggable.defaults, options);
this.positionElement = this.options.positionElement || this.positionElement;
this.getStartPosition = this.options.getStartPosition || this.getStartPosition;
this.updatePositionFrameHandler = function () {
delete that.queuedUpdate;
var pos = that.ui.position;
that.positionElement(that.$el, that.started, pos.left, pos.top);
if (that.options.dragUpdate) {
that.options.dragUpdate.apply(that.el, [that.ui]);
}
};
this.queuePositionUpdate = function () {
if (!that.queuedUpdate) {
that.queuedUpdate = window.requestAnimationFrame(that.updatePositionFrameHandler);
}
};
this.init();
};
UDraggable.prototype = {
constructor: UDraggable,
init: function () {
var that = this;
this.disabled = false;
this.started = false;
this.normalisePosition();
var $target = this.options.handle ?
this.$el.find(this.options.handle) :
this.$el;
if (this.options.longPress) {
$target
.on('uheldstart.udraggable', function (e) {
that.start(e);
})
.on('uheldmove.udraggable', function (e) {
that.move(e);
})
.on('uheldend.udraggable', function (e) {
that.end(e);
});
}
else {
$target
.on('udragstart.udraggable', function (e) {
that.start(e);
})
.on('udragmove.udraggable', function (e) {
that.move(e);
})
.on('udragend.udraggable', function (e) {
that.end(e);
});
}
},
destroy: function () {
var $target = this.options.handle ?
this.$el.find(this.options.handle) :
this.$el;
$target.off('.udraggable');
this.$el.removeData('udraggable');
},
disable: function () {
this.disabled = true;
},
enable: function () {
this.disabled = false;
},
option: function () {
var name;
if (arguments.length === 0) {
return this.options;
}
if (arguments.length === 2) {
this.options[arguments[0]] = arguments[1];
return;
}
if (arguments.length === 1) {
if (typeof arguments[0] === 'string') {
return this.options[arguments[0]];
}
if (typeof arguments[0] === 'object') {
for (name in arguments[0]) {
if (arguments[0].hasOwnProperty(name)) {
this.options[name] = arguments[0][name];
}
}
}
}
if (this.options.containment) {
this._initContainment();
}
},
normalisePosition: function () {
var pos = this.$el.position();
this.$el.css({
position: 'absolute',
top: pos.top,
left: pos.left,
right: 'auto',
bottom: 'auto'
});
},
start: function (e) {
if (this.disabled) {
return;
}
var start = this.getStartPosition(this.$el);
this._initContainment();
this.ui = {
helper: this.$el,
offset: {top: start.y, left: start.x},
originalPosition: {top: start.y, left: start.x},
position: {top: start.y, left: start.x},
};
if (this.options.longPress) {
this._start(e);
}
return this._stopPropagation(e);
},
move: function (e) {
if (this.disabled || (!this.started && !this._start(e))) {
return;
}
var delta_x = e.px_current_x - e.px_start_x;
var delta_y = e.px_current_y - e.px_start_y;
var axis = this.options.axis;
if (axis && axis === "x") {
delta_y = 0;
}
if (axis && axis === "y") {
delta_x = 0;
}
var cur = {
left: this.ui.originalPosition.left,
top: this.ui.originalPosition.top
};
if (!axis || (axis === "x")) {
cur.left += delta_x;
}
if (!axis || (axis === "y")) {
cur.top += delta_y;
}
this._applyGrid(cur);
this._applyContainment(cur);
var pos = this.ui.position;
if ((cur.top !== pos.top) || (cur.left !== pos.left)) {
this.ui.position.left = cur.left;
this.ui.position.top = cur.top;
this.ui.offset.left = cur.left;
this.ui.offset.top = cur.top;
if (this.options.drag) {
this.options.drag.apply(this.el, [e, this.ui]);
}
this.queuePositionUpdate();
}
return this._stopPropagation(e);
},
end: function (e) {
if (this.started || this._start(e)) {
this.$el.removeClass("udraggable-dragging");
this.started = false;
if (this.queuedUpdate) {
window.cancelAnimationFrame(this.queuedUpdate);
}
this.updatePositionFrameHandler();
if (this.options.stop) {
this.options.stop.apply(this.el, [e, this.ui]);
}
}
return this._stopPropagation(e);
},
// helper methods
_stopPropagation: function (e) {
e.stopPropagation();
e.preventDefault();
return false;
},
_start: function (e) {
if (!this._mouseDistanceMet(e) || !this._mouseDelayMet(e)) {
return;
}
this.started = true;
this.queuePositionUpdate();
if (this.options.start) {
this.options.start.apply(this.el, [e, this.ui]);
}
this.$el.addClass("udraggable-dragging");
return true;
},
_mouseDistanceMet: function (e) {
return max(
Math.abs(e.px_start_x - e.px_current_x),
Math.abs(e.px_start_y - e.px_current_y)
) >= this.options.distance;
},
_mouseDelayMet: function (e) {
return e.ms_elapsed > this.options.delay;
},
_initContainment: function () {
var o = this.options;
var $c, ce;
if (!o.containment) {
this.containment = null;
return;
}
if (o.containment.constructor === Array) {
this.containment = o.containment;
return;
}
if (o.containment === "parent") {
o.containment = this.$el.offsetParent();
}
$c = $(o.containment);
ce = $c[0];
if (!ce) {
return;
}
this.containment = [
0,
0,
$c.innerWidth() - this.$el.outerWidth(),
$c.innerHeight() - this.$el.outerHeight(),
];
},
_applyGrid: function (cur) {
if (this.options.grid) {
var gx = this.options.grid[0];
var gy = this.options.grid[1];
cur.left = floor((cur.left + gx / 2) / gx) * gx;
cur.top = floor((cur.top + gy / 2) / gy) * gy;
}
},
_applyContainment: function (cur) {
var cont = this.containment;
if (cont) {
cur.left = min(max(cur.left, cont[0]), cont[2]);
cur.top = min(max(cur.top, cont[1]), cont[3]);
}
},
getStartPosition: function ($el) {
return {
x: parseInt($el.css('left'), 10) || 0,
y: parseInt($el.css('top'), 10) || 0
};
},
positionElement: function ($el, dragging, left, top) {
$el.css({left: left, top: top});
}
};
// jQuery plugin function
$.fn.udraggable = function (option) {
var args = Array.prototype.slice.call(arguments, 1);
var results = [];
this.each(function () {
var $this = $(this);
var data = $this.data('udraggable');
if (!data) {
data = new UDraggable(this, option);
$this.data('udraggable', data);
}
if (typeof option === 'string') { // option is a method - call it
if (typeof data[option] !== 'function') {
throw "jquery.udraggable has no '" + option + "' method";
}
var result = data[option].apply(data, args);
if (result !== undefined) {
results.push(result);
}
}
});
return results.length > 0 ? results[0] : this;
};
$.fn.udraggable.defaults = {
axis: null,
delay: 0,
distance: 0,
longPress: false,
// callbacks
drag: null,
start: null,
stop: null
};
})(jQuery);