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 {commitOvalToBitmap} from '../bitmap';
|
||||||
import {getRaster} from '../layer';
|
import {getRaster} from '../layer';
|
||||||
import {clearSelection} from '../selection';
|
import {clearSelection} from '../selection';
|
||||||
|
import {getSquareDimensions} from '../math';
|
||||||
import BoundingBoxTool from '../selection-tools/bounding-box-tool';
|
import BoundingBoxTool from '../selection-tools/bounding-box-tool';
|
||||||
import NudgeTool from '../selection-tools/nudge-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 downPoint = new paper.Point(event.downPoint.x, event.downPoint.y);
|
||||||
const point = new paper.Point(event.point.x, event.point.y);
|
const point = new paper.Point(event.point.x, event.point.y);
|
||||||
|
const squareDimensions = getSquareDimensions(event.downPoint, event.point);
|
||||||
if (event.modifiers.shift) {
|
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 {
|
} else {
|
||||||
this.oval.size = downPoint.subtract(point);
|
this.oval.size = downPoint.subtract(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.modifiers.alt) {
|
if (event.modifiers.alt) {
|
||||||
this.oval.position = downPoint;
|
this.oval.position = downPoint;
|
||||||
|
} else if (event.modifiers.shift) {
|
||||||
|
this.oval.position = squareDimensions.position;
|
||||||
} else {
|
} else {
|
||||||
this.oval.position = downPoint.subtract(this.oval.size.multiply(0.5));
|
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 {commitRectToBitmap} from '../bitmap';
|
||||||
import {getRaster} from '../layer';
|
import {getRaster} from '../layer';
|
||||||
import {clearSelection} from '../selection';
|
import {clearSelection} from '../selection';
|
||||||
|
import {getSquareDimensions} from '../math';
|
||||||
import BoundingBoxTool from '../selection-tools/bounding-box-tool';
|
import BoundingBoxTool from '../selection-tools/bounding-box-tool';
|
||||||
import NudgeTool from '../selection-tools/nudge-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 dimensions = event.point.subtract(event.downPoint);
|
||||||
const baseRect = new paper.Rectangle(event.downPoint, event.point);
|
const baseRect = new paper.Rectangle(event.downPoint, event.point);
|
||||||
|
const squareDimensions = getSquareDimensions(event.downPoint, event.point);
|
||||||
if (event.modifiers.shift) {
|
if (event.modifiers.shift) {
|
||||||
baseRect.height = baseRect.width;
|
baseRect.size = squareDimensions.size.abs();
|
||||||
dimensions.y = event.downPoint.y > event.point.y ? -Math.abs(baseRect.width) : Math.abs(baseRect.width);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.rect) this.rect.remove();
|
if (this.rect) this.rect.remove();
|
||||||
this.rect = new paper.Shape.Rectangle(baseRect);
|
this.rect = new paper.Shape.Rectangle(baseRect);
|
||||||
if (this.filled) {
|
if (this.filled) {
|
||||||
|
@ -152,6 +154,8 @@ class RectTool extends paper.Tool {
|
||||||
|
|
||||||
if (event.modifiers.alt) {
|
if (event.modifiers.alt) {
|
||||||
this.rect.position = event.downPoint;
|
this.rect.position = event.downPoint;
|
||||||
|
} else if (event.modifiers.shift) {
|
||||||
|
this.rect.position = squareDimensions.position;
|
||||||
} else {
|
} else {
|
||||||
this.rect.position = event.downPoint.add(dimensions.multiply(.5));
|
this.rect.position = event.downPoint.add(dimensions.multiply(.5));
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,39 @@ const scaleWithStrokes = function (root, factor, pivot) {
|
||||||
root.scale(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 {
|
export {
|
||||||
HANDLE_RATIO,
|
HANDLE_RATIO,
|
||||||
checkPointsClose,
|
checkPointsClose,
|
||||||
|
@ -138,6 +171,7 @@ export {
|
||||||
expandBy,
|
expandBy,
|
||||||
getRandomInt,
|
getRandomInt,
|
||||||
getRandomBoolean,
|
getRandomBoolean,
|
||||||
|
getSquareDimensions,
|
||||||
scaleWithStrokes,
|
scaleWithStrokes,
|
||||||
snapDeltaToAngle,
|
snapDeltaToAngle,
|
||||||
sortItemsByZIndex
|
sortItemsByZIndex
|
||||||
|
|
|
@ -2,6 +2,7 @@ import paper from '@scratch/paper';
|
||||||
import Modes from '../../lib/modes';
|
import Modes from '../../lib/modes';
|
||||||
import {styleShape} from '../style-path';
|
import {styleShape} from '../style-path';
|
||||||
import {clearSelection} from '../selection';
|
import {clearSelection} from '../selection';
|
||||||
|
import {getSquareDimensions} from '../math';
|
||||||
import BoundingBoxTool from '../selection-tools/bounding-box-tool';
|
import BoundingBoxTool from '../selection-tools/bounding-box-tool';
|
||||||
import NudgeTool from '../selection-tools/nudge-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 downPoint = new paper.Point(event.downPoint.x, event.downPoint.y);
|
||||||
const point = new paper.Point(event.point.x, event.point.y);
|
const point = new paper.Point(event.point.x, event.point.y);
|
||||||
|
const squareDimensions = getSquareDimensions(event.downPoint, event.point);
|
||||||
if (event.modifiers.shift) {
|
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 {
|
} else {
|
||||||
this.oval.size = downPoint.subtract(point);
|
this.oval.size = downPoint.subtract(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.modifiers.alt) {
|
if (event.modifiers.alt) {
|
||||||
this.oval.position = downPoint;
|
this.oval.position = downPoint;
|
||||||
|
} else if (event.modifiers.shift) {
|
||||||
|
this.oval.position = squareDimensions.position;
|
||||||
} else {
|
} else {
|
||||||
this.oval.position = downPoint.subtract(this.oval.size.multiply(0.5));
|
this.oval.position = downPoint.subtract(this.oval.size.multiply(0.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
handleMouseUp (event) {
|
handleMouseUp (event) {
|
||||||
if (event.event.button > 0 || !this.active) return; // only first mouse button
|
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 Modes from '../../lib/modes';
|
||||||
import {styleShape} from '../style-path';
|
import {styleShape} from '../style-path';
|
||||||
import {clearSelection} from '../selection';
|
import {clearSelection} from '../selection';
|
||||||
|
import {getSquareDimensions} from '../math';
|
||||||
import BoundingBoxTool from '../selection-tools/bounding-box-tool';
|
import BoundingBoxTool from '../selection-tools/bounding-box-tool';
|
||||||
import NudgeTool from '../selection-tools/nudge-tool';
|
import NudgeTool from '../selection-tools/nudge-tool';
|
||||||
|
|
||||||
|
@ -85,18 +86,20 @@ class RectTool extends paper.Tool {
|
||||||
this.rect.remove();
|
this.rect.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
const dimensions = event.point.subtract(event.downPoint);
|
|
||||||
const rect = new paper.Rectangle(event.downPoint, event.point);
|
const rect = new paper.Rectangle(event.downPoint, event.point);
|
||||||
|
const squareDimensions = getSquareDimensions(event.downPoint, event.point);
|
||||||
if (event.modifiers.shift) {
|
if (event.modifiers.shift) {
|
||||||
rect.height = rect.width;
|
rect.size = squareDimensions.size.abs();
|
||||||
dimensions.y = event.downPoint.y > event.point.y ? -Math.abs(rect.width) : Math.abs(rect.width);
|
|
||||||
}
|
}
|
||||||
this.rect = new paper.Path.Rectangle(rect);
|
|
||||||
|
|
||||||
|
this.rect = new paper.Path.Rectangle(rect);
|
||||||
if (event.modifiers.alt) {
|
if (event.modifiers.alt) {
|
||||||
this.rect.position = event.downPoint;
|
this.rect.position = event.downPoint;
|
||||||
|
} else if (event.modifiers.shift) {
|
||||||
|
this.rect.position = squareDimensions.position;
|
||||||
} else {
|
} 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);
|
styleShape(this.rect, this.colorState);
|
||||||
|
|
Loading…
Reference in a new issue