mirror of
https://github.com/scratchfoundation/scratch-paint.git
synced 2024-12-23 05:52:42 -05:00
nudge
This commit is contained in:
parent
1ff5fdff38
commit
f3dcc54bf3
4 changed files with 113 additions and 27 deletions
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue