mirror of
https://github.com/scratchfoundation/scratch-paint.git
synced 2024-12-22 21:42:30 -05:00
Fence tools to make it less easy to lose work off the sides (#671)
This commit is contained in:
parent
e4883063fe
commit
a105d967ba
4 changed files with 53 additions and 12 deletions
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue