aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/InkHandles.tsx
diff options
context:
space:
mode:
authorvkalev <vjk1883@gmail.com>2021-07-06 14:27:29 -0500
committervkalev <vjk1883@gmail.com>2021-07-06 14:27:29 -0500
commit5ab81f49a11bd8a74725228a887a90c88a3848ff (patch)
treeb04396026c765c6e216988927b71570497286ecf /src/client/views/InkHandles.tsx
parenta0207bf861908da9235a1752a723e69ecdbba734 (diff)
added breaking of tangent handle lines by holding 'Alt' key when moving
Diffstat (limited to 'src/client/views/InkHandles.tsx')
-rw-r--r--src/client/views/InkHandles.tsx32
1 files changed, 27 insertions, 5 deletions
diff --git a/src/client/views/InkHandles.tsx b/src/client/views/InkHandles.tsx
index c2163c124..993e427b3 100644
--- a/src/client/views/InkHandles.tsx
+++ b/src/client/views/InkHandles.tsx
@@ -15,6 +15,8 @@ export interface InkControlProps {
@observer
export class InkHandles extends React.Component<InkControlProps> {
+ @observable private _brokenIndices: number[] = [];
+
/**
* Handles the movement of a selected handle point when the user clicks and drags.
* @param handleNum The index of the currently selected handle point.
@@ -24,13 +26,25 @@ export class InkHandles extends React.Component<InkControlProps> {
InkStrokeProperties.Instance.moveControl(0, 0, 1);
const controlUndo = UndoManager.StartBatch("DocDecs set radius");
const screenScale = this.props.ScreenToLocalTransform().Scale;
+ document.addEventListener("keydown", (e: KeyboardEvent) => this.onBreakTangent(e, handleNum), true);
setupMoveUpEvents(this, e, (e: PointerEvent, down: number[], delta: number[]) => {
- InkStrokeProperties.Instance?.moveHandle(-delta[0] * screenScale, -delta[1] * screenScale, handleNum);
+ InkStrokeProperties.Instance?.moveHandle(-delta[0] * screenScale, -delta[1] * screenScale, handleNum, this._brokenIndices);
return false;
}, () => controlUndo?.end(), emptyFunction
);
}
}
+
+ @action
+ onBreakTangent = (e: KeyboardEvent, handleIndex: number) => {
+ if (["Alt"].includes(e.key)) {
+ const order = handleIndex % 4;
+ const oppositeHandleIndex = order === 1 ? handleIndex - 3 : handleIndex + 3;
+ if (!this._brokenIndices.includes(handleIndex) && !this._brokenIndices.includes(oppositeHandleIndex)) {
+ this._brokenIndices.push(handleIndex, oppositeHandleIndex);
+ }
+ }
+ }
render() {
const formatInstance = InkStrokeProperties.Instance;
@@ -39,15 +53,15 @@ export class InkHandles extends React.Component<InkControlProps> {
const handlePoints: HandlePoint[] = [];
const handleLines: HandleLine[] = [];
if (data.length >= 4) {
- // adding first and last (single) handle lines
- handleLines.push({ X1: data[0].X, Y1: data[0].Y, X2: data[1].X, Y2: data[1].Y, dot1: 0, dot2: 0 });
- handleLines.push({ X1: data[data.length - 2].X, Y1: data[data.length - 2].Y, X2: data[data.length - 1].X, Y2: data[data.length - 1].Y, dot1: data.length - 1, dot2: data.length - 1 });
for (let i = 0; i <= data.length - 4; i += 4) {
handlePoints.push({ X: data[i + 1].X, Y: data[i + 1].Y, I: i + 1, dot1: i, dot2: i === 0 ? i : i - 1 });
handlePoints.push({ X: data[i + 2].X, Y: data[i + 2].Y, I: i + 2, dot1: i + 3, dot2: i === data.length ? i + 3 : i + 4 });
}
+ // adding first and last (single) handle lines
+ handleLines.push({ X1: data[0].X, Y1: data[0].Y, X2: data[0].X, Y2: data[0].Y, X3: data[1].X, Y3: data[1].Y, dot1: 0, dot2: 0 });
+ handleLines.push({ X1: data[data.length - 2].X, Y1: data[data.length - 2].Y, X2: data[data.length - 1].X, Y2: data[data.length - 1].Y, X3: data[data.length - 1].X, Y3: data[data.length - 1].Y, dot1: data.length - 1, dot2: data.length - 1 });
for (let i = 2; i < data.length - 4; i += 4) {
- handleLines.push({ X1: data[i].X, Y1: data[i].Y, X2: data[i + 3].X, Y2: data[i + 3].Y, dot1: i + 1, dot2: i + 2 });
+ handleLines.push({ X1: data[i].X, Y1: data[i].Y, X2: data[i + 1].X, Y2: data[i + 1].Y, X3: data[i + 3].X, Y3: data[i + 3].Y, dot1: i + 1, dot2: i + 2 });
}
}
const [left, top, scaleX, scaleY, strokeWidth, dotsize] = this.props.format;
@@ -77,6 +91,14 @@ export class InkHandles extends React.Component<InkControlProps> {
stroke="#1F85DE"
strokeWidth={dotsize / 8}
display={(pts.dot1 === formatInstance._currentPoint || pts.dot2 === formatInstance._currentPoint) ? "inherit" : "none"} />
+ <line
+ x1={(pts.X2 - left - strokeWidth / 2) * scaleX + strokeWidth / 2}
+ y1={(pts.Y2 - top - strokeWidth / 2) * scaleY + strokeWidth / 2}
+ x2={(pts.X3 - left - strokeWidth / 2) * scaleX + strokeWidth / 2}
+ y2={(pts.Y3 - top - strokeWidth / 2) * scaleY + strokeWidth / 2}
+ stroke="#1F85DE"
+ strokeWidth={dotsize / 8}
+ display={(pts.dot1 === formatInstance._currentPoint || pts.dot2 === formatInstance._currentPoint) ? "inherit" : "none"} />
</svg>)}
</>
);