mirror of
https://github.com/scratchfoundation/scratch-paint.git
synced 2024-12-22 21:42:30 -05:00
Make circle (shift-oval) tool work for any direction dragged (#774)
This commit is contained in:
parent
ada81cbd88
commit
a04f1276f8
5 changed files with 61 additions and 11 deletions
|
@ -3,6 +3,7 @@ import Modes from '../../lib/modes';
|
|||
import {commitOvalToBitmap} from '../bitmap';
|
||||
import {getRaster} from '../layer';
|
||||
import {clearSelection} from '../selection';
|
||||
import {getSquareDimensions} from '../math';
|
||||
import BoundingBoxTool from '../selection-tools/bounding-box-tool';
|
||||
import NudgeTool from '../selection-tools/nudge-tool';
|
||||
|
||||
|
@ -151,13 +152,17 @@ class OvalTool extends paper.Tool {
|
|||
|
||||
const downPoint = new paper.Point(event.downPoint.x, event.downPoint.y);
|
||||
const point = new paper.Point(event.point.x, event.point.y);
|
||||
const squareDimensions = getSquareDimensions(event.downPoint, event.point);
|
||||
if (event.modifiers.shift) {
|
||||
this.oval.size = new paper.Point(event.downPoint.x - event.point.x, event.downPoint.x - event.point.x);
|
||||
this.oval.size = squareDimensions.size.abs();
|
||||
} else {
|
||||
this.oval.size = downPoint.subtract(point);
|
||||
}
|
||||
|
||||
if (event.modifiers.alt) {
|
||||
this.oval.position = downPoint;
|
||||
} else if (event.modifiers.shift) {
|
||||
this.oval.position = squareDimensions.position;
|
||||
} else {
|
||||
this.oval.position = downPoint.subtract(this.oval.size.multiply(0.5));
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import Modes from '../../lib/modes';
|
|||
import {commitRectToBitmap} from '../bitmap';
|
||||
import {getRaster} from '../layer';
|
||||
import {clearSelection} from '../selection';
|
||||
import {getSquareDimensions} from '../math';
|
||||
import BoundingBoxTool from '../selection-tools/bounding-box-tool';
|
||||
import NudgeTool from '../selection-tools/nudge-tool';
|
||||
|
||||
|
@ -133,10 +134,11 @@ class RectTool extends paper.Tool {
|
|||
|
||||
const dimensions = event.point.subtract(event.downPoint);
|
||||
const baseRect = new paper.Rectangle(event.downPoint, event.point);
|
||||
const squareDimensions = getSquareDimensions(event.downPoint, event.point);
|
||||
if (event.modifiers.shift) {
|
||||
baseRect.height = baseRect.width;
|
||||
dimensions.y = event.downPoint.y > event.point.y ? -Math.abs(baseRect.width) : Math.abs(baseRect.width);
|
||||
baseRect.size = squareDimensions.size.abs();
|
||||
}
|
||||
|
||||
if (this.rect) this.rect.remove();
|
||||
this.rect = new paper.Shape.Rectangle(baseRect);
|
||||
if (this.filled) {
|
||||
|
@ -152,6 +154,8 @@ class RectTool extends paper.Tool {
|
|||
|
||||
if (event.modifiers.alt) {
|
||||
this.rect.position = event.downPoint;
|
||||
} else if (event.modifiers.shift) {
|
||||
this.rect.position = squareDimensions.position;
|
||||
} else {
|
||||
this.rect.position = event.downPoint.add(dimensions.multiply(.5));
|
||||
}
|
||||
|
|
|
@ -131,6 +131,39 @@ const scaleWithStrokes = function (root, factor, pivot) {
|
|||
root.scale(factor, pivot);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the size and position of a square, as in if the user were holding the shift key down while drawing the shape,
|
||||
* from the point where the drag started and the point where the mouse is currently positioned. (Note: This also works
|
||||
* for shapes like circles ("square ovals"), which fill the same dimensions.)
|
||||
* @param {!paper.Point} startPos The point where the user started dragging
|
||||
* @param {!paper.Point} eventPoint The point where the user has currently dragged to
|
||||
* @return {object} Information about the size and position of how the square should be drawn
|
||||
*/
|
||||
const getSquareDimensions = function (startPos, eventPoint) {
|
||||
// These variables are used for determining the relative quadrant that the shape will appear in.
|
||||
// So if you drag up and right, it'll show up above and to the right of where you started dragging, etc.
|
||||
let offsetX = eventPoint.x - startPos.x;
|
||||
let offsetY = eventPoint.y - startPos.y;
|
||||
|
||||
// If the offset variables are zero, the shape ends up having zero width or height, which is bad.
|
||||
// Deal with this by forcing them to be non-zero (we arbitrarily choose 1; any non-zero value would work).
|
||||
offsetX = offsetX ? offsetX : 1;
|
||||
offsetY = offsetY ? offsetY : 1;
|
||||
|
||||
// The length of the shape is the greater of the X and Y offsets.
|
||||
const offsetDistance = eventPoint.subtract(startPos).abs();
|
||||
const length = Math.max(offsetDistance.x, offsetDistance.y);
|
||||
|
||||
const size = new paper.Point(
|
||||
length * offsetX / Math.abs(offsetX),
|
||||
length * offsetY / Math.abs(offsetY)
|
||||
);
|
||||
|
||||
const position = startPos.add(size.multiply(0.5));
|
||||
|
||||
return {size, position};
|
||||
};
|
||||
|
||||
export {
|
||||
HANDLE_RATIO,
|
||||
checkPointsClose,
|
||||
|
@ -138,6 +171,7 @@ export {
|
|||
expandBy,
|
||||
getRandomInt,
|
||||
getRandomBoolean,
|
||||
getSquareDimensions,
|
||||
scaleWithStrokes,
|
||||
snapDeltaToAngle,
|
||||
sortItemsByZIndex
|
||||
|
|
|
@ -2,6 +2,7 @@ import paper from '@scratch/paper';
|
|||
import Modes from '../../lib/modes';
|
||||
import {styleShape} from '../style-path';
|
||||
import {clearSelection} from '../selection';
|
||||
import {getSquareDimensions} from '../math';
|
||||
import BoundingBoxTool from '../selection-tools/bounding-box-tool';
|
||||
import NudgeTool from '../selection-tools/nudge-tool';
|
||||
|
||||
|
@ -88,17 +89,20 @@ class OvalTool extends paper.Tool {
|
|||
|
||||
const downPoint = new paper.Point(event.downPoint.x, event.downPoint.y);
|
||||
const point = new paper.Point(event.point.x, event.point.y);
|
||||
const squareDimensions = getSquareDimensions(event.downPoint, event.point);
|
||||
if (event.modifiers.shift) {
|
||||
this.oval.size = new paper.Point(event.downPoint.x - event.point.x, event.downPoint.x - event.point.x);
|
||||
this.oval.size = squareDimensions.size.abs();
|
||||
} else {
|
||||
this.oval.size = downPoint.subtract(point);
|
||||
}
|
||||
|
||||
if (event.modifiers.alt) {
|
||||
this.oval.position = downPoint;
|
||||
} else if (event.modifiers.shift) {
|
||||
this.oval.position = squareDimensions.position;
|
||||
} else {
|
||||
this.oval.position = downPoint.subtract(this.oval.size.multiply(0.5));
|
||||
}
|
||||
|
||||
}
|
||||
handleMouseUp (event) {
|
||||
if (event.event.button > 0 || !this.active) return; // only first mouse button
|
||||
|
|
|
@ -2,6 +2,7 @@ import paper from '@scratch/paper';
|
|||
import Modes from '../../lib/modes';
|
||||
import {styleShape} from '../style-path';
|
||||
import {clearSelection} from '../selection';
|
||||
import {getSquareDimensions} from '../math';
|
||||
import BoundingBoxTool from '../selection-tools/bounding-box-tool';
|
||||
import NudgeTool from '../selection-tools/nudge-tool';
|
||||
|
||||
|
@ -85,18 +86,20 @@ class RectTool extends paper.Tool {
|
|||
this.rect.remove();
|
||||
}
|
||||
|
||||
const dimensions = event.point.subtract(event.downPoint);
|
||||
const rect = new paper.Rectangle(event.downPoint, event.point);
|
||||
const squareDimensions = getSquareDimensions(event.downPoint, event.point);
|
||||
if (event.modifiers.shift) {
|
||||
rect.height = rect.width;
|
||||
dimensions.y = event.downPoint.y > event.point.y ? -Math.abs(rect.width) : Math.abs(rect.width);
|
||||
rect.size = squareDimensions.size.abs();
|
||||
}
|
||||
this.rect = new paper.Path.Rectangle(rect);
|
||||
|
||||
this.rect = new paper.Path.Rectangle(rect);
|
||||
if (event.modifiers.alt) {
|
||||
this.rect.position = event.downPoint;
|
||||
} else if (event.modifiers.shift) {
|
||||
this.rect.position = squareDimensions.position;
|
||||
} else {
|
||||
this.rect.position = event.downPoint.add(dimensions.multiply(.5));
|
||||
const dimensions = event.point.subtract(event.downPoint);
|
||||
this.rect.position = event.downPoint.add(dimensions.multiply(0.5));
|
||||
}
|
||||
|
||||
styleShape(this.rect, this.colorState);
|
||||
|
|
Loading…
Reference in a new issue