Skip to content

Commit

Permalink
shift-drag corner box handle preserves aspect-ratio
Browse files Browse the repository at this point in the history
  • Loading branch information
mbloch committed Mar 7, 2024
1 parent acbac8b commit 5b86c98
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 24 deletions.
71 changes: 47 additions & 24 deletions src/gui/gui-highlight-box.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { El } from './gui-el';
import { EventDispatcher } from './gui-events';
import { getBBoxCoords } from './gui-display-utils';
import { internal } from './gui-core';
import { internal, geom } from './gui-core';

export function HighlightBox(gui, optsArg) {
var el = El('div').addClass('zoom-box').appendTo('body'),
Expand Down Expand Up @@ -61,37 +61,21 @@ export function HighlightBox(gui, optsArg) {
});
});

document.addEventListener('mousemove', function(e) {
gui.map.getMouse().on('mousemove', function(e) {
if (!_on || !activeHandle || !prevXY || !boxCoords || !_visible) return;
var xy = {x: e.pageX, y: e.pageY};
var scale = gui.map.getExtent().getPixelSize();
var dx = (xy.x - prevXY.x) * scale;
var dy = -(xy.y - prevXY.y) * scale;
var shifting = activeHandle.col == 'center' && activeHandle.row == 'center';
var centered = gui.keyboard.shiftIsPressed() && !shifting;
if (activeHandle.col == 'left' || shifting) {
boxCoords[0] += dx;
if (centered) boxCoords[2] -= dx;
var scaling = gui.keyboard.shiftIsPressed() && activeHandle.type == 'corner';
if (scaling) {
rescaleBox(e.x, e.y);
} else {
resizeBox(xy.x - prevXY.x, xy.y - prevXY.y, activeHandle);
}
if (activeHandle.col == 'right' || shifting) {
boxCoords[2] += dx;
if (centered) boxCoords[0] -= dx;
}
if (activeHandle.row == 'top' || shifting) {
boxCoords[3] += dy;
if (centered) boxCoords[1] -= dy;
}
if (activeHandle.row == 'bottom' || shifting) {
boxCoords[1] += dy;
if (centered) boxCoords[3] -= dy;
}

prevXY = xy;
redraw();
box.dispatchEvent('handle_drag');
});

document.addEventListener('mouseup', function() {
gui.map.getMouse().on('mouseup', function(e) {
if (activeHandle && _on) {
activeHandle.el.css('background', null);
activeHandle = null;
Expand All @@ -104,6 +88,43 @@ export function HighlightBox(gui, optsArg) {
});
}

function resizeBox(dx, dy, activeHandle) {
var shifting = activeHandle.type == 'center';
var centered = gui.keyboard.shiftIsPressed() && activeHandle.type == 'edge';
var scale = gui.map.getExtent().getPixelSize();
dx *= scale;
dy *= -scale;

if (activeHandle.col == 'left' || shifting) {
boxCoords[0] += dx;
if (centered) boxCoords[2] -= dx;
}
if (activeHandle.col == 'right' || shifting) {
boxCoords[2] += dx;
if (centered) boxCoords[0] -= dx;
}
if (activeHandle.row == 'top' || shifting) {
boxCoords[3] += dy;
if (centered) boxCoords[1] -= dy;
}
if (activeHandle.row == 'bottom' || shifting) {
boxCoords[1] += dy;
if (centered) boxCoords[3] -= dy;
}
}

function rescaleBox(x, y) {
var p = gui.map.getExtent().translatePixelCoords(x, y);
var cx = (boxCoords[0] + boxCoords[2])/2;
var cy = (boxCoords[1] + boxCoords[3])/2;
var dist2 = geom.distance2D(cx, cy, p[0], p[1]);
var dist = geom.distance2D(cx, cy, boxCoords[0], boxCoords[1]);
var k = dist2 / dist;
var dx = (boxCoords[2] - cx) * k;
var dy = (boxCoords[3] - cy) * k;
boxCoords = [cx - dx, cy - dy, cx + dx, cy + dy];
}

box.setDataCoords = function(bbox) {
boxCoords = bbox;
redraw();
Expand Down Expand Up @@ -199,8 +220,10 @@ function initHandles(el) {
// if (i == 4) continue; // skip middle handle
var c = Math.floor(i / 3);
var r = i % 3;
var type = i == 4 && 'center' || c != 1 && r != 1 && 'corner' || 'edge';
handles.push({
el: El('div').addClass('handle').appendTo(el),
type: type,
col: c == 0 && 'left' || c == 1 && 'center' || 'right',
row: r == 0 && 'top' || r == 1 && 'center' || 'bottom'
});
Expand Down
2 changes: 2 additions & 0 deletions src/gui/gui-mouse.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ export function MouseArea(element, pos) {
function onMouseUp(e) {
var evt = procMouseEvent(e),
elapsed, dx, dy;
_self.dispatchEvent('mouseup', evt);
if (_dragging) {
stopDragging(evt);
}
Expand Down Expand Up @@ -208,6 +209,7 @@ export function MouseArea(element, pos) {

function onMouseMove(e) {
var evt = procMouseEvent(e);
_self.dispatchEvent('mousemove', evt);
if (!_dragging && _downEvt && _downEvt.hover) {
_dragging = true;
_self.dispatchEvent('dragstart', evt);
Expand Down

0 comments on commit 5b86c98

Please sign in to comment.