This commit is contained in:
DD 2018-01-25 15:56:50 -05:00
parent 1ff5fdff38
commit f3dcc54bf3
4 changed files with 113 additions and 27 deletions

View file

@ -1,6 +1,6 @@
import paper from '@scratch/paper';
import {snapDeltaToAngle} from '../math';
import {clearSelection, getSelectedLeafItems} from '../selection';
import {clearSelection, getSelectedLeafItems, getSelectedSegments} from '../selection';
import {HANDLE_RATIO} from '../math';
/** Subtool of ReshapeTool for moving control points. */
@ -146,17 +146,14 @@ class PointTool {
const dragVector = event.point.subtract(event.downPoint);
for (const item of this.selectedItems) {
if (!item.segments) {
return;
}
for (const seg of item.segments) {
const selectedSegments = getSelectedSegments();
for (const seg of selectedSegments) {
// add the point of the segment before the drag started
// for later use in the snap calculation
if (!seg.origPoint) {
seg.origPoint = seg.point.clone();
}
if (seg.selected) {
if (event.modifiers.shift) {
seg.point = seg.origPoint.add(snapDeltaToAngle(dragVector, Math.PI / 4));
} else {
@ -164,22 +161,16 @@ class PointTool {
}
}
}
}
}
onMouseUp () {
// resetting the items and segments origin points for the next usage
let moved = false;
for (const item of this.selectedItems) {
if (!item.segments) {
return;
}
for (const seg of item.segments) {
const selectedSegments = getSelectedSegments();
for (const seg of selectedSegments) {
if (seg.origPoint && !seg.equals(seg.origPoint)) {
moved = true;
}
seg.origPoint = null;
}
}
// If no drag occurred between mouse down and mouse up, then we can go through with deselect
// and delete

View file

@ -5,6 +5,7 @@ import keyMirror from 'keymirror';
import Modes from '../../lib/modes';
import {getHoveredItem} from '../hover';
import {getRootItem, isPGTextItem} from '../item';
import {getSelectedLeafItems, getSelectedSegments} from '../selection';
import MoveTool from './move-tool';
import PointTool from './point-tool';
import HandleTool from './handle-tool';
@ -67,6 +68,8 @@ class ReshapeTool extends paper.Tool {
this.onMouseMove = this.handleMouseMove;
this.onMouseDrag = this.handleMouseDrag;
this.onMouseUp = this.handleMouseUp;
this.onKeyUp = this.handleKeyUp;
this.onKeyDown = this.handleKeyDown;
paper.settings.handleSize = 8;
}
@ -228,6 +231,44 @@ class ReshapeTool extends paper.Tool {
this.mode = ReshapeModes.SELECTION_BOX;
this.active = false;
}
handleKeyDown (event) {
const nudgeAmount = 1 / paper.view.zoom;
const selected = getSelectedLeafItems();
if (selected.length === 0) return;
let translation;
if (event.key === 'up') {
translation = new paper.Point(0, -nudgeAmount);
} else if (event.key === 'down') {
translation = new paper.Point(0, nudgeAmount);
} else if (event.key === 'left') {
translation = new paper.Point(-nudgeAmount, 0);
} else if (event.key === 'right') {
translation = new paper.Point(nudgeAmount, 0);
}
if (translation) {
const segments = getSelectedSegments();
// If no segments are selected, translate selected paths
if (segments.length === 0) {
for (const item of selected) {
item.translate(translation);
}
} else { // Translate segments
for (const seg of segments) {
seg.point = seg.point.add(translation);
}
}
}
}
handleKeyUp (event) {
const selected = getSelectedLeafItems();
if (selected.length === 0) return;
if (event.key === 'up' || event.key === 'down' || event.key === 'left' || event.key === 'right') {
this.onUpdateSvg();
}
}
deactivateTool () {
paper.settings.handleSize = 0;
this.clearHoveredItem();

View file

@ -1,7 +1,7 @@
import Modes from '../../lib/modes';
import {getHoveredItem} from '../hover';
import {selectRootItem} from '../selection';
import {getSelectedRootItems, selectRootItem} from '../selection';
import BoundingBoxTool from './bounding-box-tool';
import SelectionBoxTool from './selection-box-tool';
import paper from '@scratch/paper';
@ -42,6 +42,8 @@ class SelectTool extends paper.Tool {
this.onMouseMove = this.handleMouseMove;
this.onMouseDrag = this.handleMouseDrag;
this.onMouseUp = this.handleMouseUp;
this.onKeyUp = this.handleKeyUp;
this.onKeyDown = this.handleKeyDown;
selectRootItem();
setSelectedItems();
@ -131,6 +133,37 @@ class SelectTool extends paper.Tool {
this.selectionBoxMode = false;
this.active = false;
}
handleKeyDown (event) {
const nudgeAmount = 1 / paper.view.zoom;
const selected = getSelectedRootItems();
if (selected.length === 0) return;
let translation;
if (event.key === 'up') {
translation = new paper.Point(0, -nudgeAmount);
} else if (event.key === 'down') {
translation = new paper.Point(0, nudgeAmount);
} else if (event.key === 'left') {
translation = new paper.Point(-nudgeAmount, 0);
} else if (event.key === 'right') {
translation = new paper.Point(nudgeAmount, 0);
}
if (translation) {
for (const item of selected) {
item.translate(translation);
}
}
this.boundingBoxTool.setSelectionBounds();
}
handleKeyUp (event) {
const selected = getSelectedRootItems();
if (selected.length === 0) return;
if (event.key === 'up' || event.key === 'down' || event.key === 'left' || event.key === 'right') {
this.onUpdateSvg();
}
}
deactivateTool () {
this.clearHoveredItem();
this.boundingBoxTool.removeBoundsPath();

View file

@ -175,6 +175,26 @@ const getSelectedLeafItems = function () {
return items;
};
/**
* This gets all selected path segments.
* @return {Array<paper.Segment>} selected segments
*/
const getSelectedSegments = function () {
const selected = getSelectedLeafItems();
const segments = [];
for (const item of selected) {
if (!item.segments) {
continue;
}
for (const seg of item.segments) {
if (seg.selected) {
segments.push(seg);
}
}
}
return segments;
};
const _deleteItemSelection = function (items, onUpdateSvg) {
// @todo: Update toolbar state on change
if (items.length === 0) {
@ -408,6 +428,7 @@ export {
setItemSelection,
getSelectedLeafItems,
getSelectedRootItems,
getSelectedSegments,
processRectangularSelection,
selectRootItem,
shouldShowSelectAll