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

View file

@ -5,6 +5,7 @@ import keyMirror from 'keymirror';
import Modes from '../../lib/modes'; import Modes from '../../lib/modes';
import {getHoveredItem} from '../hover'; import {getHoveredItem} from '../hover';
import {getRootItem, isPGTextItem} from '../item'; import {getRootItem, isPGTextItem} from '../item';
import {getSelectedLeafItems, getSelectedSegments} from '../selection';
import MoveTool from './move-tool'; import MoveTool from './move-tool';
import PointTool from './point-tool'; import PointTool from './point-tool';
import HandleTool from './handle-tool'; import HandleTool from './handle-tool';
@ -67,6 +68,8 @@ class ReshapeTool extends paper.Tool {
this.onMouseMove = this.handleMouseMove; this.onMouseMove = this.handleMouseMove;
this.onMouseDrag = this.handleMouseDrag; this.onMouseDrag = this.handleMouseDrag;
this.onMouseUp = this.handleMouseUp; this.onMouseUp = this.handleMouseUp;
this.onKeyUp = this.handleKeyUp;
this.onKeyDown = this.handleKeyDown;
paper.settings.handleSize = 8; paper.settings.handleSize = 8;
} }
@ -228,6 +231,44 @@ class ReshapeTool extends paper.Tool {
this.mode = ReshapeModes.SELECTION_BOX; this.mode = ReshapeModes.SELECTION_BOX;
this.active = false; 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 () { deactivateTool () {
paper.settings.handleSize = 0; paper.settings.handleSize = 0;
this.clearHoveredItem(); this.clearHoveredItem();

View file

@ -1,7 +1,7 @@
import Modes from '../../lib/modes'; import Modes from '../../lib/modes';
import {getHoveredItem} from '../hover'; import {getHoveredItem} from '../hover';
import {selectRootItem} from '../selection'; import {getSelectedRootItems, selectRootItem} from '../selection';
import BoundingBoxTool from './bounding-box-tool'; import BoundingBoxTool from './bounding-box-tool';
import SelectionBoxTool from './selection-box-tool'; import SelectionBoxTool from './selection-box-tool';
import paper from '@scratch/paper'; import paper from '@scratch/paper';
@ -42,6 +42,8 @@ class SelectTool extends paper.Tool {
this.onMouseMove = this.handleMouseMove; this.onMouseMove = this.handleMouseMove;
this.onMouseDrag = this.handleMouseDrag; this.onMouseDrag = this.handleMouseDrag;
this.onMouseUp = this.handleMouseUp; this.onMouseUp = this.handleMouseUp;
this.onKeyUp = this.handleKeyUp;
this.onKeyDown = this.handleKeyDown;
selectRootItem(); selectRootItem();
setSelectedItems(); setSelectedItems();
@ -131,6 +133,37 @@ class SelectTool extends paper.Tool {
this.selectionBoxMode = false; this.selectionBoxMode = false;
this.active = 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 () { deactivateTool () {
this.clearHoveredItem(); this.clearHoveredItem();
this.boundingBoxTool.removeBoundsPath(); this.boundingBoxTool.removeBoundsPath();

View file

@ -175,6 +175,26 @@ const getSelectedLeafItems = function () {
return items; 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) { const _deleteItemSelection = function (items, onUpdateSvg) {
// @todo: Update toolbar state on change // @todo: Update toolbar state on change
if (items.length === 0) { if (items.length === 0) {
@ -408,6 +428,7 @@ export {
setItemSelection, setItemSelection,
getSelectedLeafItems, getSelectedLeafItems,
getSelectedRootItems, getSelectedRootItems,
getSelectedSegments,
processRectangularSelection, processRectangularSelection,
selectRootItem, selectRootItem,
shouldShowSelectAll shouldShowSelectAll