aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/InkStrokeProperties.ts
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2021-12-02 13:46:17 -0500
committerbobzel <zzzman@gmail.com>2021-12-02 13:46:17 -0500
commitc2cd77ca1d2a67539f0af2a68c1e7336b3bc232b (patch)
tree4557b82e9e26167f3ae9d651f644dd5cad570314 /src/client/views/InkStrokeProperties.ts
parentf0495cc1a050abfbaffe96b73bed24c8afe4b7b4 (diff)
added scale factor for arrows. added control point drag to reparameterize. fixed toggling tangent lines to not happen when dragging.
Diffstat (limited to 'src/client/views/InkStrokeProperties.ts')
-rw-r--r--src/client/views/InkStrokeProperties.ts50
1 files changed, 46 insertions, 4 deletions
diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts
index 695bdcc5a..cab4e1216 100644
--- a/src/client/views/InkStrokeProperties.ts
+++ b/src/client/views/InkStrokeProperties.ts
@@ -1,4 +1,5 @@
import { Bezier } from "bezier-js";
+import { Normalize, Distance } from "../util/bezierFit";
import { action, observable, reaction } from "mobx";
import { Doc, NumListCast, Opt } from "../../fields/Doc";
import { InkData, InkField, InkTool, PointData } from "../../fields/InkField";
@@ -225,15 +226,57 @@ export class InkStrokeProperties {
*/
@undoBatch
@action
- moveControlPtHandle = (inkView: DocumentView, deltaX: number, deltaY: number, controlIndex: number) =>
+ moveControlPtHandle = (inkView: DocumentView, deltaX: number, deltaY: number, controlIndex: number, origInk?: InkData) =>
this.applyFunction(inkView, (view: DocumentView, ink: InkData, xScale: number, yScale: number) => {
const order = controlIndex % 4;
const closed = InkingStroke.IsClosed(ink);
+ if (origInk && this._currentPoint > 0 && this._currentPoint < ink.length - 1) {
+ const cpt_before = ink[controlIndex];
+ const cpt = { X: cpt_before.X + deltaX, Y: cpt_before.Y + deltaY };
+ if (true) {
+ const newink = origInk.slice();
+ const start = this._currentPoint === 0 ? 0 : this._currentPoint - 4;
+ const splicedPoints = origInk.slice(start, start + (this._currentPoint === 0 || this._currentPoint === ink.length - 1 ? 4 : 8));
+ const { nearestT, nearestSeg } = InkStrokeProperties.nearestPtToStroke(splicedPoints, cpt);
+ const samplesLeft: Point[] = [];
+ const samplesRight: Point[] = [];
+ var startDir = { x: 0, y: 0 };
+ var endDir = { x: 0, y: 0 };
+ for (var i = 0; i < nearestSeg / 4 + 1; i++) {
+ const bez = new Bezier(splicedPoints.slice(i * 4, i * 4 + 4).map(p => ({ x: p.X, y: p.Y })));
+ if (i === 0) startDir = bez.derivative(0);
+ if (i === nearestSeg / 4) endDir = bez.derivative(nearestT);
+ for (var t = 0; t < (i === nearestSeg / 4 ? nearestT + .05 : 1); t += 0.05) {
+ const pt = bez.compute(i !== nearestSeg / 4 ? t : Math.min(nearestT, t));
+ samplesLeft.push(new Point(pt.x, pt.y));
+ }
+ }
+ var { finalCtrls, error } = FitOneCurve(samplesLeft, { X: startDir.x, Y: startDir.y }, { X: endDir.x, Y: endDir.y });
+ for (var i = nearestSeg / 4; i < splicedPoints.length / 4; i++) {
+ const bez = new Bezier(splicedPoints.slice(i * 4, i * 4 + 4).map(p => ({ x: p.X, y: p.Y })));
+ if (i === nearestSeg / 4) startDir = bez.derivative(nearestT);
+ if (i === splicedPoints.length / 4 - 1) endDir = bez.derivative(1);
+ for (var t = i === nearestSeg / 4 ? nearestT : 0; t < (i === nearestSeg / 4 ? 1 + .05 + 1e-7 : 1 + 1e-7); t += 0.05) {
+ const pt = bez.compute(Math.min(1, t));
+ samplesRight.push(new Point(pt.x, pt.y));
+ }
+ }
+ const { finalCtrls: rightCtrls, error: errorRight } = FitOneCurve(samplesRight, { X: startDir.x, Y: startDir.y }, { X: endDir.x, Y: endDir.y });
+ finalCtrls = finalCtrls.concat(rightCtrls);
+ newink.splice(this._currentPoint - 4, 8, ...finalCtrls);
+ return newink;
+ }
+ }
- const newpts = ink.map((pt, i) => {
+ return ink.map((pt, i) => {
const leftHandlePoint = order === 0 && i === controlIndex + 1;
const rightHandlePoint = order === 0 && controlIndex !== 0 && i === controlIndex - 2;
if (controlIndex === i ||
+ (order === 0 && controlIndex !== 0 && i === controlIndex - 1) ||
+ (order === 3 && i === controlIndex - 1)) {
+ return ({ X: pt.X + deltaX, Y: pt.Y + deltaY });
+ }
+ if (controlIndex === i ||
leftHandlePoint ||
rightHandlePoint ||
(order === 0 && controlIndex !== 0 && i === controlIndex - 1) ||
@@ -246,7 +289,6 @@ export class InkStrokeProperties {
}
return pt;
});
- return newpts;
})
@@ -286,7 +328,7 @@ export class InkStrokeProperties {
if (snapData.distance < 10) {
const deltaX = (snapData.nearestPt.X - ink[controlIndex].X);
const deltaY = (snapData.nearestPt.Y - ink[controlIndex].Y);
- const res = this.moveControlPtHandle(inkView, deltaX, deltaY, controlIndex);
+ const res = this.moveControlPtHandle(inkView, deltaX, deltaY, controlIndex, ink.slice());
console.log("X = " + snapData.nearestPt.X + " " + snapData.nearestPt.Y);
return res;
}