szurubooru/public_html/js/Util/Draggable.js

149 lines
3.4 KiB
JavaScript
Raw Normal View History

var App = App || {};
App.Util = App.Util || {};
App.Util.Draggable = function(jQuery) {
var KEY_LEFT = 37;
var KEY_UP = 38;
var KEY_RIGHT = 39;
var KEY_DOWN = 40;
function relativeDragStrategy($element) {
var $parent = $element.parent();
var delta;
var x = $element.offset().left - $parent.offset().left;
var y = $element.offset().top - $parent.offset().top;
var getPosition = function() {
return {x: x, y: y};
};
var setPosition = function(newX, newY) {
x = newX;
y = newY;
var screenX = Math.min(Math.max(newX, 0), $parent.outerWidth() - $element.outerWidth());
var screenY = Math.min(Math.max(newY, 0), $parent.outerHeight() - $element.outerHeight());
screenX *= 100.0 / $parent.outerWidth();
screenY *= 100.0 / $parent.outerHeight();
$element.css({
left: screenX + '%',
top: screenY + '%'});
};
return {
mouseClicked: function(e) {
delta = {
x: $element.offset().left - e.clientX,
y: $element.offset().top - e.clientY,
};
},
mouseMoved: function(e) {
setPosition(
e.clientX + delta.x - $parent.offset().left,
e.clientY + delta.y - $parent.offset().top);
},
getPosition: getPosition,
setPosition: setPosition,
};
}
function absoluteDragStrategy($element) {
var delta;
var x = $element.offset().left;
var y = $element.offset().top;
var getPosition = function() {
return {x: x, y: y};
};
var setPosition = function(newX, newY) {
x = newX;
y = newY;
$element.css({
left: x + 'px',
top: y + 'px'});
};
return {
mouseClicked: function(e) {
delta = {
x: $element.position().left - e.clientX,
y: $element.position().top - e.clientY,
};
},
mouseMoved: function(e) {
setPosition(e.clientX + delta.x, e.clientY + delta.y);
},
getPosition: getPosition,
setPosition: setPosition,
};
}
function makeDraggable($element, dragStrategy, enableHotkeys) {
var strategy = dragStrategy($element);
$element.data('drag-strategy', strategy);
$element.addClass('draggable');
$element.mousedown(function(e) {
if (e.target !== $element.get(0)) {
return;
}
e.preventDefault();
$element.focus();
$element.addClass('dragging');
strategy.mouseClicked(e);
jQuery(window).bind('mousemove.elemmove', function(e) {
strategy.mouseMoved(e);
}).bind('mouseup.elemmove', function(e) {
e.preventDefault();
strategy.mouseMoved(e);
$element.removeClass('dragging');
jQuery(window).unbind('mousemove.elemmove');
jQuery(window).unbind('mouseup.elemmove');
});
});
if (enableHotkeys) {
$element.keydown(function(e) {
var position = strategy.getPosition();
var oldPosition = {x: position.x, y: position.y};
if (e.shiftKey) {
return;
}
var delta = e.ctrlKey ? 10 : 1;
if (e.which === KEY_LEFT) {
position.x -= delta;
} else if (e.which === KEY_RIGHT) {
position.x += delta;
} else if (e.which === KEY_UP) {
position.y -= delta;
} else if (e.which === KEY_DOWN) {
position.y += delta;
}
if (position.x !== oldPosition.x || position.y !== oldPosition.y) {
e.stopPropagation();
e.stopImmediatePropagation();
e.preventDefault();
strategy.setPosition(position.x, position.y);
}
});
}
}
return {
makeDraggable: makeDraggable,
absoluteDragStrategy: absoluteDragStrategy,
relativeDragStrategy: relativeDragStrategy,
};
};
App.DI.registerSingleton('draggable', ['jQuery'], App.Util.Draggable);