Added arrow hotkeys to Draggable and Resizable
Which means better control over the post notes placement for all the keyboard lovers.
This commit is contained in:
parent
90406b1278
commit
b416868aa7
4 changed files with 121 additions and 22 deletions
|
@ -224,12 +224,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-note {
|
.post-note {
|
||||||
|
outline: 0;
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: rgba(255, 255, 255, 0.3);
|
background: rgba(255, 255, 255, 0.3);
|
||||||
border: 1px solid rgba(0, 0, 0, 0.3);
|
border: 1px solid rgba(0, 0, 0, 0.3);
|
||||||
font-size: 12pt;
|
font-size: 12pt;
|
||||||
}
|
}
|
||||||
|
.post-note:focus {
|
||||||
|
border-color: rgba(255, 0, 0, 0.3);
|
||||||
|
background-color: rgba(255, 225, 225, 0.3);
|
||||||
|
}
|
||||||
.post-note .text-wrapper {
|
.post-note .text-wrapper {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
@ -2,75 +2,137 @@ var App = App || {};
|
||||||
App.Util = App.Util || {};
|
App.Util = App.Util || {};
|
||||||
|
|
||||||
App.Util.Draggable = function(jQuery) {
|
App.Util.Draggable = function(jQuery) {
|
||||||
|
var KEY_LEFT = 37;
|
||||||
|
var KEY_UP = 38;
|
||||||
|
var KEY_RIGHT = 39;
|
||||||
|
var KEY_DOWN = 40;
|
||||||
|
|
||||||
function relativeDragStrategy($element) {
|
function relativeDragStrategy($element) {
|
||||||
var $parent = $element.parent();
|
var $parent = $element.parent();
|
||||||
var delta;
|
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 {
|
return {
|
||||||
click: function(e) {
|
mouseClicked: function(e) {
|
||||||
delta = {
|
delta = {
|
||||||
x: $element.offset().left - e.clientX,
|
x: $element.offset().left - e.clientX,
|
||||||
y: $element.offset().top - e.clientY,
|
y: $element.offset().top - e.clientY,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
update: function(e) {
|
mouseMoved: function(e) {
|
||||||
var x = e.clientX + delta.x - $parent.offset().left;
|
setPosition(
|
||||||
var y = e.clientY + delta.y - $parent.offset().top;
|
e.clientX + delta.x - $parent.offset().left,
|
||||||
x = Math.min(Math.max(x, 0), $parent.outerWidth() - $element.outerWidth());
|
e.clientY + delta.y - $parent.offset().top);
|
||||||
y = Math.min(Math.max(y, 0), $parent.outerHeight() - $element.outerHeight());
|
|
||||||
x *= 100.0 / $parent.outerWidth();
|
|
||||||
y *= 100.0 / $parent.outerHeight();
|
|
||||||
$element.css({
|
|
||||||
left: x + '%',
|
|
||||||
top: y + '%'});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getPosition: getPosition,
|
||||||
|
setPosition: setPosition,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function absoluteDragStrategy($element) {
|
function absoluteDragStrategy($element) {
|
||||||
var delta;
|
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 {
|
return {
|
||||||
click: function(e) {
|
mouseClicked: function(e) {
|
||||||
delta = {
|
delta = {
|
||||||
x: $element.position().left - e.clientX,
|
x: $element.position().left - e.clientX,
|
||||||
y: $element.position().top - e.clientY,
|
y: $element.position().top - e.clientY,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
update: function(e) {
|
mouseMoved: function(e) {
|
||||||
var x = e.clientX + delta.x;
|
setPosition(e.clientX + delta.x, e.clientY + delta.y);
|
||||||
var y = e.clientY + delta.y;
|
|
||||||
$element.css({
|
|
||||||
left: x + 'px',
|
|
||||||
top: y + 'px'});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getPosition: getPosition,
|
||||||
|
setPosition: setPosition,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeDraggable($element, dragStrategy) {
|
function makeDraggable($element, dragStrategy) {
|
||||||
var strategy = dragStrategy($element);
|
var strategy = dragStrategy($element);
|
||||||
|
$element.data('drag-strategy', strategy);
|
||||||
|
|
||||||
$element.addClass('draggable');
|
$element.addClass('draggable');
|
||||||
|
|
||||||
$element.mousedown(function(e) {
|
$element.mousedown(function(e) {
|
||||||
if (e.target !== $element.get(0)) {
|
if (e.target !== $element.get(0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
$element.focus();
|
||||||
$element.addClass('dragging');
|
$element.addClass('dragging');
|
||||||
|
|
||||||
strategy.click(e);
|
strategy.mouseClicked(e);
|
||||||
jQuery(window).bind('mousemove.elemmove', function(e) {
|
jQuery(window).bind('mousemove.elemmove', function(e) {
|
||||||
strategy.update(e);
|
strategy.mouseMoved(e);
|
||||||
}).bind('mouseup.elemmove', function(e) {
|
}).bind('mouseup.elemmove', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
strategy.update(e);
|
strategy.mouseMoved(e);
|
||||||
$element.removeClass('dragging');
|
$element.removeClass('dragging');
|
||||||
jQuery(window).unbind('mousemove.elemmove');
|
jQuery(window).unbind('mousemove.elemmove');
|
||||||
jQuery(window).unbind('mouseup.elemmove');
|
jQuery(window).unbind('mouseup.elemmove');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$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 {
|
return {
|
||||||
|
|
|
@ -2,6 +2,11 @@ var App = App || {};
|
||||||
App.Util = App.Util || {};
|
App.Util = App.Util || {};
|
||||||
|
|
||||||
App.Util.Resizable = function(jQuery) {
|
App.Util.Resizable = function(jQuery) {
|
||||||
|
var KEY_LEFT = 37;
|
||||||
|
var KEY_UP = 38;
|
||||||
|
var KEY_RIGHT = 39;
|
||||||
|
var KEY_DOWN = 40;
|
||||||
|
|
||||||
function relativeResizeStrategy($element) {
|
function relativeResizeStrategy($element) {
|
||||||
var $parent = $element.parent();
|
var $parent = $element.parent();
|
||||||
var delta;
|
var delta;
|
||||||
|
@ -51,6 +56,7 @@ App.Util.Resizable = function(jQuery) {
|
||||||
$resizer.mousedown(function(e) {
|
$resizer.mousedown(function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
$element.focus();
|
||||||
$element.addClass('resizing');
|
$element.addClass('resizing');
|
||||||
|
|
||||||
strategy.mouseClicked(e);
|
strategy.mouseClicked(e);
|
||||||
|
@ -65,6 +71,32 @@ App.Util.Resizable = function(jQuery) {
|
||||||
jQuery(window).unbind('mouseup.elemsize');
|
jQuery(window).unbind('mouseup.elemsize');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$element.keydown(function(e) {
|
||||||
|
var size = strategy.getSize();
|
||||||
|
var oldSize = {width: size.width, height: size.height};
|
||||||
|
if (!e.shiftKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var delta = e.ctrlKey ? 10 : 1;
|
||||||
|
if (e.which === KEY_LEFT) {
|
||||||
|
size.width -= delta;
|
||||||
|
} else if (e.which === KEY_RIGHT) {
|
||||||
|
size.width += delta;
|
||||||
|
} else if (e.which === KEY_UP) {
|
||||||
|
size.height -= delta;
|
||||||
|
} else if (e.which === KEY_DOWN) {
|
||||||
|
size.height += delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size.width !== oldSize.width || size.height !== oldSize.height) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
strategy.setSize(size.width, size.height);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="post-notes">
|
<div class="post-notes">
|
||||||
<% _.each(notes, function(note) { %>
|
<% _.each(notes, function(note) { %>
|
||||||
<div class="post-note"
|
<div tabindex="0" class="post-note"
|
||||||
style="left: <%= note.left %>%;
|
style="left: <%= note.left %>%;
|
||||||
top: <%= note.top %>%;
|
top: <%= note.top %>%;
|
||||||
width: <%= note.width %>%;
|
width: <%= note.width %>%;
|
||||||
|
|
Loading…
Reference in a new issue