2018-01-25 16:39:38 -05:00
|
|
|
import paper from '@scratch/paper';
|
2018-09-12 18:03:19 -04:00
|
|
|
import {getSelectedRootItems} from '../selection';
|
|
|
|
import {ART_BOARD_WIDTH, ART_BOARD_HEIGHT} from '../view';
|
|
|
|
|
|
|
|
const NUDGE_MORE_MULTIPLIER = 15;
|
2018-01-25 16:39:38 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Tool containing handlers for arrow key events for nudging the selection.
|
|
|
|
* Note that this tool is built for selection mode, not reshape mode.
|
|
|
|
*/
|
|
|
|
class NudgeTool {
|
|
|
|
/**
|
|
|
|
* @param {function} boundingBoxTool to control the bounding box
|
2018-04-26 18:45:50 -04:00
|
|
|
* @param {!function} onUpdateImage A callback to call when the image visibly changes
|
2018-01-25 16:39:38 -05:00
|
|
|
*/
|
2018-04-26 18:45:50 -04:00
|
|
|
constructor (boundingBoxTool, onUpdateImage) {
|
2018-01-25 16:39:38 -05:00
|
|
|
this.boundingBoxTool = boundingBoxTool;
|
2018-04-26 18:45:50 -04:00
|
|
|
this.onUpdateImage = onUpdateImage;
|
2018-01-25 16:39:38 -05:00
|
|
|
}
|
|
|
|
onKeyDown (event) {
|
2018-02-07 11:35:59 -05:00
|
|
|
if (event.event.target instanceof HTMLInputElement) {
|
|
|
|
// Ignore nudge if a text input field is focused
|
|
|
|
return;
|
|
|
|
}
|
2018-02-06 19:29:43 -05:00
|
|
|
|
2018-09-12 18:03:19 -04:00
|
|
|
let nudgeAmount = 1 / paper.view.zoom;
|
|
|
|
if (event.modifiers.shift) nudgeAmount *= NUDGE_MORE_MULTIPLIER;
|
|
|
|
|
2018-01-25 16:39:38 -05:00
|
|
|
const selected = getSelectedRootItems();
|
|
|
|
if (selected.length === 0) return;
|
2018-09-12 18:03:19 -04:00
|
|
|
|
|
|
|
// Get bounds. Don't let item bounds go out of bounds.
|
|
|
|
let rect;
|
|
|
|
for (const item of selected) {
|
|
|
|
if (rect) {
|
|
|
|
rect = rect.unite(item.bounds);
|
|
|
|
} else {
|
|
|
|
rect = item.bounds;
|
|
|
|
}
|
|
|
|
}
|
2018-01-25 16:39:38 -05:00
|
|
|
|
|
|
|
let translation;
|
|
|
|
if (event.key === 'up') {
|
2018-09-12 18:03:19 -04:00
|
|
|
translation = new paper.Point(0, -Math.min(nudgeAmount, rect.bottom - 1));
|
2018-01-25 16:39:38 -05:00
|
|
|
} else if (event.key === 'down') {
|
2018-09-12 18:03:19 -04:00
|
|
|
translation = new paper.Point(0, Math.min(nudgeAmount, ART_BOARD_HEIGHT - rect.top - 1));
|
2018-01-25 16:39:38 -05:00
|
|
|
} else if (event.key === 'left') {
|
2018-09-12 18:03:19 -04:00
|
|
|
translation = new paper.Point(-Math.min(nudgeAmount, rect.right - 1), 0);
|
2018-01-25 16:39:38 -05:00
|
|
|
} else if (event.key === 'right') {
|
2018-09-12 18:03:19 -04:00
|
|
|
translation = new paper.Point(Math.min(nudgeAmount, ART_BOARD_WIDTH - rect.left - 1), 0);
|
2018-01-25 16:39:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (translation) {
|
|
|
|
for (const item of selected) {
|
|
|
|
item.translate(translation);
|
|
|
|
}
|
2018-02-06 19:15:25 -05:00
|
|
|
this.boundingBoxTool.setSelectionBounds();
|
2018-09-12 18:03:19 -04:00
|
|
|
event.preventDefault();
|
2018-01-25 16:39:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
onKeyUp (event) {
|
|
|
|
const selected = getSelectedRootItems();
|
|
|
|
if (selected.length === 0) return;
|
|
|
|
|
|
|
|
if (event.key === 'up' || event.key === 'down' || event.key === 'left' || event.key === 'right') {
|
2018-04-26 18:45:50 -04:00
|
|
|
this.onUpdateImage();
|
2018-01-25 16:39:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default NudgeTool;
|