From 53713fc7ab10257d1117193941cda2f3e0cabcf5 Mon Sep 17 00:00:00 2001
From: yunahi <60233430+yunahi@users.noreply.github.com>
Date: Sun, 19 Jul 2020 04:44:51 +0900
Subject: added control points

---
 src/client/views/InkingStroke.tsx | 82 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

(limited to 'src/client/views/InkingStroke.tsx')

diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index abc698e62..974921be8 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -17,6 +17,7 @@ import { Scripting } from "../util/Scripting";
 import { Doc } from "../../fields/Doc";
 import FormatShapePane from "./collections/collectionFreeForm/FormatShapePane";
 import { action } from "mobx";
+import { setupMoveUpEvents } from "../../Utils";
 
 library.add(faPaintBrush);
 
@@ -45,6 +46,38 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
         FormatShapePane.Instance.Pinned = true;
     }
 
+    private _prevX = 0;
+    private _prevY = 0;
+    private _controlNum = 0;
+    @action
+    onControlDown = (e: React.PointerEvent, i: number): void => {
+        setupMoveUpEvents(this, e, this.onControlMove, this.onControlup, (e) => { });
+        this._prevX = e.clientX;
+        this._prevY = e.clientY;
+        this._controlNum = i;
+    }
+
+    @action
+    changeCurrPoint = (i: number) => {
+        FormatShapePane.Instance._currPoint = i;
+    }
+
+    @action
+    onControlMove = (e: PointerEvent, down: number[]): boolean => {
+        const xDiff = this._prevX - e.clientX;
+        const yDiff = this._prevY - e.clientY;
+        FormatShapePane.Instance.control(xDiff, yDiff, this._controlNum);
+        this._prevX = e.clientX;
+        this._prevY = e.clientY;
+        return false;
+    }
+
+    onControlup = (e: PointerEvent) => {
+        this._prevX = 0;
+        this._prevY = 0;
+        this._controlNum = 0;
+    }
+
     render() {
         TraceMobx();
         const data: InkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? [];
@@ -69,6 +102,51 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
             this.props.isSelected() && strokeWidth > 5 ? strokeColor : "transparent", strokeWidth, (strokeWidth + 15),
             StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "transparent"),
             "none", "none", "0", scaleX, scaleY, "", this.props.active() ? "visiblepainted" : "none", false, true);
+
+        const controlPoints: { X: number, Y: number, I: number }[] = [];
+        const handlePoints: { X: number, Y: number, I: number, dot1: number, dot2: number }[] = [];
+        const handleLine: { X1: number, Y1: number, X2: number, Y2: number, X3: number, Y3: number, dot1: number, dot2: number }[] = [];
+
+        if (data.length > 5) {
+            for (var i = 0; i <= data.length - 4; i += 4) {
+                controlPoints.push({ X: data[i].X, Y: data[i].Y, I: i });
+                controlPoints.push({ X: data[i + 3].X, Y: data[i + 3].Y, I: i + 3 });
+                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 });
+            }
+            handleLine.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 });
+            for (var i = 2; i < data.length - 2; i += 4) {
+                handleLine.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 });
+            }
+            handleLine.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 });
+
+
+        }
+        const controls = controlPoints.map((pts, i) =>
+
+            <svg height="10" width="10">
+                <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r="5" stroke="black" stroke-width="1" fill="red"
+                    onPointerDown={(e) => { this.changeCurrPoint(pts.I); this.onControlDown(e, pts.I); }} pointerEvents="all" cursor="all-scroll" />
+            </svg>);
+        const handles = handlePoints.map((pts, i) =>
+
+            <svg height="10" width="10">
+                <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r="5" stroke="black" stroke-width="1" fill="green"
+                    onPointerDown={(e) => this.onControlDown(e, pts.I)} pointerEvents="all" cursor="all-scroll" display={(pts.dot1 === FormatShapePane.Instance._currPoint || pts.dot2 === FormatShapePane.Instance._currPoint) ? "inherit" : "none"} />
+            </svg>);
+        const handleLines = handleLine.map((pts, i) =>
+
+            <svg height="100" width="100">
+                <line x1={(pts.X1 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y1={(pts.Y1 - top - strokeWidth / 2) * scaleY + strokeWidth / 2}
+                    x2={(pts.X2 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y2={(pts.Y2 - top - strokeWidth / 2) * scaleY + strokeWidth / 2} stroke="black" stroke-width="1"
+                    display={(pts.dot1 === FormatShapePane.Instance._currPoint || pts.dot2 === FormatShapePane.Instance._currPoint) ? "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="black" stroke-width="1"
+                    display={(pts.dot1 === FormatShapePane.Instance._currPoint || pts.dot2 === FormatShapePane.Instance._currPoint) ? "inherit" : "none"} />
+
+            </svg>);
+
+
         return (
             <svg className="inkingStroke"
                 width={width}
@@ -91,6 +169,10 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
                 </defs>
                 {hpoints}
                 {points}
+                {FormatShapePane.Instance._controlBtn && this.props.isSelected() ? controls : ""}
+                {FormatShapePane.Instance._controlBtn && this.props.isSelected() ? handles : ""}
+                {FormatShapePane.Instance._controlBtn && this.props.isSelected() ? handleLines : ""}
+
             </svg>
         );
     }
-- 
cgit v1.2.3-70-g09d2

