From a105d967ba31b9bcb6262c856aae2ece96acceef Mon Sep 17 00:00:00 2001 From: DD Liu Date: Wed, 12 Sep 2018 18:03:19 -0400 Subject: [PATCH] Fence tools to make it less easy to lose work off the sides (#671) --- src/helper/selection-tools/move-tool.js | 7 +++++- src/helper/selection-tools/nudge-tool.js | 28 +++++++++++++++++++----- src/helper/selection-tools/point-tool.js | 18 +++++++++++---- src/helper/selection-tools/scale-tool.js | 12 +++++++++- 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/helper/selection-tools/move-tool.js b/src/helper/selection-tools/move-tool.js index 379ae7db..efd861d3 100644 --- a/src/helper/selection-tools/move-tool.js +++ b/src/helper/selection-tools/move-tool.js @@ -3,6 +3,7 @@ import Modes from '../../lib/modes'; import {isGroup} from '../group'; import {isCompoundPathItem, getRootItem} from '../item'; import {snapDeltaToAngle} from '../math'; +import {ART_BOARD_WIDTH, ART_BOARD_HEIGHT} from '../view'; import {clearSelection, cloneSelection, getSelectedLeafItems, getSelectedRootItems, setItemSelection} from '../selection'; @@ -97,7 +98,11 @@ class MoveTool { this.setSelectedItems(); } onMouseDrag (event) { - const dragVector = event.point.subtract(event.downPoint); + const point = event.point; + point.x = Math.max(0, Math.min(point.x, ART_BOARD_WIDTH)); + point.y = Math.max(0, Math.min(point.y, ART_BOARD_HEIGHT)); + const dragVector = point.subtract(event.downPoint); + for (const item of this.selectedItems) { // add the position of the item before the drag started // for later use in the snap calculation diff --git a/src/helper/selection-tools/nudge-tool.js b/src/helper/selection-tools/nudge-tool.js index d63b1c3c..d336e1c7 100644 --- a/src/helper/selection-tools/nudge-tool.js +++ b/src/helper/selection-tools/nudge-tool.js @@ -1,5 +1,8 @@ -import {getSelectedRootItems} from '../selection'; import paper from '@scratch/paper'; +import {getSelectedRootItems} from '../selection'; +import {ART_BOARD_WIDTH, ART_BOARD_HEIGHT} from '../view'; + +const NUDGE_MORE_MULTIPLIER = 15; /** * Tool containing handlers for arrow key events for nudging the selection. @@ -20,19 +23,31 @@ class NudgeTool { return; } - const nudgeAmount = 1 / paper.view.zoom; + let nudgeAmount = 1 / paper.view.zoom; + if (event.modifiers.shift) nudgeAmount *= NUDGE_MORE_MULTIPLIER; + const selected = getSelectedRootItems(); if (selected.length === 0) return; + + // 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; + } + } let translation; if (event.key === 'up') { - translation = new paper.Point(0, -nudgeAmount); + translation = new paper.Point(0, -Math.min(nudgeAmount, rect.bottom - 1)); } else if (event.key === 'down') { - translation = new paper.Point(0, nudgeAmount); + translation = new paper.Point(0, Math.min(nudgeAmount, ART_BOARD_HEIGHT - rect.top - 1)); } else if (event.key === 'left') { - translation = new paper.Point(-nudgeAmount, 0); + translation = new paper.Point(-Math.min(nudgeAmount, rect.right - 1), 0); } else if (event.key === 'right') { - translation = new paper.Point(nudgeAmount, 0); + translation = new paper.Point(Math.min(nudgeAmount, ART_BOARD_WIDTH - rect.left - 1), 0); } if (translation) { @@ -40,6 +55,7 @@ class NudgeTool { item.translate(translation); } this.boundingBoxTool.setSelectionBounds(); + event.preventDefault(); } } onKeyUp (event) { diff --git a/src/helper/selection-tools/point-tool.js b/src/helper/selection-tools/point-tool.js index f3675424..5b141d32 100644 --- a/src/helper/selection-tools/point-tool.js +++ b/src/helper/selection-tools/point-tool.js @@ -1,7 +1,7 @@ import paper from '@scratch/paper'; -import {snapDeltaToAngle} from '../math'; +import {HANDLE_RATIO, snapDeltaToAngle} from '../math'; +import {ART_BOARD_WIDTH, ART_BOARD_HEIGHT} from '../view'; import {clearSelection, getSelectedLeafItems, getSelectedSegments} from '../selection'; -import {HANDLE_RATIO} from '../math'; /** Subtool of ReshapeTool for moving control points. */ class PointTool { @@ -29,6 +29,7 @@ class PointTool { this.selectedItems = null; this.setSelectedItems = setSelectedItems; this.clearSelectedItems = clearSelectedItems; + this.lastPoint = null; this.onUpdateImage = onUpdateImage; } @@ -144,7 +145,14 @@ class PointTool { this.invertDeselect = false; this.deleteOnMouseUp = null; - const dragVector = event.point.subtract(event.downPoint); + const point = event.point; + point.x = Math.max(0, Math.min(point.x, ART_BOARD_WIDTH)); + point.y = Math.max(0, Math.min(point.y, ART_BOARD_HEIGHT)); + + if (!this.lastPoint) this.lastPoint = event.lastPoint; + const dragVector = point.subtract(event.downPoint); + const delta = point.subtract(this.lastPoint); + this.lastPoint = point; const selectedSegments = getSelectedSegments(); for (const seg of selectedSegments) { @@ -157,11 +165,13 @@ class PointTool { if (event.modifiers.shift) { seg.point = seg.origPoint.add(snapDeltaToAngle(dragVector, Math.PI / 4)); } else { - seg.point = seg.point.add(event.delta); + seg.point = seg.point.add(delta); } } } onMouseUp () { + this.lastPoint = null; + // resetting the items and segments origin points for the next usage let moved = false; const selectedSegments = getSelectedSegments(); diff --git a/src/helper/selection-tools/scale-tool.js b/src/helper/selection-tools/scale-tool.js index 65330e9c..9500e7e8 100644 --- a/src/helper/selection-tools/scale-tool.js +++ b/src/helper/selection-tools/scale-tool.js @@ -1,5 +1,6 @@ import paper from '@scratch/paper'; import {getItems} from '../selection'; +import {ART_BOARD_WIDTH, ART_BOARD_HEIGHT} from '../view'; /** * Tool to handle scaling items by pulling on the handles around the edges of the bounding @@ -20,6 +21,7 @@ class ScaleTool { this.itemGroup = null; // Lowest item above all scale items in z index this.itemToInsertBelow = null; + this.lastPoint = null; this.onUpdateImage = onUpdateImage; } @@ -66,6 +68,13 @@ class ScaleTool { } onMouseDrag (event) { if (!this.active) return; + const point = event.point; + point.x = Math.max(0, Math.min(point.x, ART_BOARD_WIDTH)); + point.y = Math.max(0, Math.min(point.y, ART_BOARD_HEIGHT)); + + if (!this.lastPoint) this.lastPoint = event.lastPoint; + const delta = point.subtract(this.lastPoint); + this.lastPoint = point; const modOrigSize = this.origSize; @@ -85,7 +94,7 @@ class ScaleTool { this.pivot = this.origPivot; } - this.corner = this.corner.add(event.delta); + this.corner = this.corner.add(delta); const size = this.corner.subtract(this.pivot); let sx = 1.0; let sy = 1.0; @@ -109,6 +118,7 @@ class ScaleTool { } onMouseUp () { if (!this.active) return; + this.lastPoint = null; this.pivot = null; this.origPivot = null;