From b416868aa794f0483289647f1a1728622d0b98df Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Sun, 22 Feb 2015 18:56:35 +0100 Subject: [PATCH] Added arrow hotkeys to Draggable and Resizable Which means better control over the post notes placement for all the keyboard lovers. --- public_html/css/post.css | 5 ++ public_html/js/Util/Draggable.js | 104 +++++++++++++++++++++------ public_html/js/Util/Resizable.js | 32 +++++++++ public_html/templates/post-notes.tpl | 2 +- 4 files changed, 121 insertions(+), 22 deletions(-) diff --git a/public_html/css/post.css b/public_html/css/post.css index 600bea83..3696508c 100644 --- a/public_html/css/post.css +++ b/public_html/css/post.css @@ -224,12 +224,17 @@ } .post-note { + outline: 0; pointer-events: auto; position: absolute; background: rgba(255, 255, 255, 0.3); border: 1px solid rgba(0, 0, 0, 0.3); 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 { position: absolute; display: none; diff --git a/public_html/js/Util/Draggable.js b/public_html/js/Util/Draggable.js index 955e5ee4..72fa7363 100644 --- a/public_html/js/Util/Draggable.js +++ b/public_html/js/Util/Draggable.js @@ -2,75 +2,137 @@ 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 { - click: function(e) { + mouseClicked: function(e) { delta = { x: $element.offset().left - e.clientX, y: $element.offset().top - e.clientY, }; }, - update: function(e) { - var x = e.clientX + delta.x - $parent.offset().left; - var y = e.clientY + delta.y - $parent.offset().top; - x = Math.min(Math.max(x, 0), $parent.outerWidth() - $element.outerWidth()); - 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 + '%'}); + 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 { - click: function(e) { + mouseClicked: function(e) { delta = { x: $element.position().left - e.clientX, y: $element.position().top - e.clientY, }; }, - update: function(e) { - var x = e.clientX + delta.x; - var y = e.clientY + delta.y; - $element.css({ - left: x + 'px', - top: y + 'px'}); + mouseMoved: function(e) { + setPosition(e.clientX + delta.x, e.clientY + delta.y); }, + + getPosition: getPosition, + setPosition: setPosition, }; } function makeDraggable($element, dragStrategy) { 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.click(e); + strategy.mouseClicked(e); jQuery(window).bind('mousemove.elemmove', function(e) { - strategy.update(e); + strategy.mouseMoved(e); }).bind('mouseup.elemmove', function(e) { e.preventDefault(); - strategy.update(e); + strategy.mouseMoved(e); $element.removeClass('dragging'); jQuery(window).unbind('mousemove.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 { diff --git a/public_html/js/Util/Resizable.js b/public_html/js/Util/Resizable.js index 68ee6796..303ff27f 100644 --- a/public_html/js/Util/Resizable.js +++ b/public_html/js/Util/Resizable.js @@ -2,6 +2,11 @@ var App = App || {}; App.Util = App.Util || {}; App.Util.Resizable = function(jQuery) { + var KEY_LEFT = 37; + var KEY_UP = 38; + var KEY_RIGHT = 39; + var KEY_DOWN = 40; + function relativeResizeStrategy($element) { var $parent = $element.parent(); var delta; @@ -51,6 +56,7 @@ App.Util.Resizable = function(jQuery) { $resizer.mousedown(function(e) { e.preventDefault(); e.stopPropagation(); + $element.focus(); $element.addClass('resizing'); strategy.mouseClicked(e); @@ -65,6 +71,32 @@ App.Util.Resizable = function(jQuery) { 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 { diff --git a/public_html/templates/post-notes.tpl b/public_html/templates/post-notes.tpl index 2803a035..92b2836b 100644 --- a/public_html/templates/post-notes.tpl +++ b/public_html/templates/post-notes.tpl @@ -1,6 +1,6 @@
<% _.each(notes, function(note) { %> -