diff options
Diffstat (limited to 'src/client/util/InteractionUtils.tsx')
-rw-r--r-- | src/client/util/InteractionUtils.tsx | 149 |
1 files changed, 33 insertions, 116 deletions
diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx index e009fb3a9..a32a8eecc 100644 --- a/src/client/util/InteractionUtils.tsx +++ b/src/client/util/InteractionUtils.tsx @@ -1,8 +1,6 @@ import React = require("react"); -import * as beziercurve from 'bezier-curve'; -import * as fitCurve from 'fit-curve'; -import "./InteractionUtils.scss"; import { Utils } from "../../Utils"; +import "./InteractionUtils.scss"; export namespace InteractionUtils { export const MOUSETYPE = "mouse"; @@ -91,138 +89,57 @@ export namespace InteractionUtils { return myTouches; } - export function CreatePoints(points: { X: number, Y: number }[], left: number, top: number, - color: string, width: number, strokeWidth: number, bezier: string, fill: string, arrowStart: string, arrowEnd: string, - dash: string, scalex: number, scaley: number, shape: string, pevents: string, drawHalo: boolean, nodefs: boolean) { - let pts: { X: number; Y: number; }[] = []; - if (shape) { //if any of the shape are true - pts = makePolygon(shape, points); - } - else if ((points.length >= 5 && points[3].X === points[4].X) || (points.length === 4)) { - for (var i = 0; i < points.length - 3; i += 4) { - const array = [[points[i].X, points[i].Y], [points[i + 1].X, points[i + 1].Y], [points[i + 2].X, points[i + 2].Y], [points[i + 3].X, points[i + 3].Y]]; - for (var t = 0; t < 1; t += 0.01) { - const point = beziercurve(t, array); - pts.push({ X: point[0], Y: point[1] }); - } - } - } - else if (points.length > 1 && points[points.length - 1].X === points[0].X && points[points.length - 1].Y === points[0].Y) { - //pointer is up (first and last points are the same) - const newPoints = points.reduce((p, pts) => { p.push([pts.X, pts.Y]); return p; }, [] as number[][]); - newPoints.pop(); - - const bezierCurves = fitCurve(newPoints, parseInt(bezier)); - for (const curve of bezierCurves) { - for (var t = 0; t < 1; t += 0.01) { - const point = beziercurve(t, curve); - pts.push({ X: point[0], Y: point[1] }); - } - } - } else { - pts = points.slice(); - // bcz: Ugh... this is ugly, but shapes apprently have an extra point added that is = (p[0].x,p[0].y+1) as some sort of flag. need to remove it here. - if (pts.length > 2 && pts[pts.length - 2].X === pts[0].X && pts[pts.length - 2].Y === pts[0].Y) { - pts.pop(); - } - } - if (isNaN(scalex)) { - scalex = 1; - } - if (isNaN(scaley)) { - scaley = 1; - } - return pts; - } + export function CreatePolyline(points: { X: number, Y: number }[], left: number, top: number, + color: string, width: number, strokeWidth: number, lineJoin: string, lineCap: string, bezier: string, fill: string, arrowStart: string, arrowEnd: string, + dash: string | undefined, scalex: number, scaley: number, shape: string, pevents: string, opacity: number, nodefs: boolean) { + const pts = shape ? makePolygon(shape, points) : points; + if (isNaN(scalex)) scalex = 1; + if (isNaN(scaley)) scaley = 1; + const toScr = (p: { X: number, Y: number }) => ` ${!p ? 0 : (p.X - left - width / 2) * scalex + width / 2}, ${!p ? 0 : (p.Y - top - width / 2) * scaley + width / 2} `; + const strpts = bezier ? + pts.reduce((acc: string, pt, i) => acc + (i % 4 !== 0 ? "" : (i === 0 ? "M" + toScr(pt) : "") + "C" + toScr(pts[i + 1]) + toScr(pts[i + 2]) + toScr(pts[i + 3])), "") : + pts.reduce((acc: string, pt) => acc + `${toScr(pt)} `, ""); - export function CreatePolyline(points: { X: number, Y: number }[], left: number, top: number, - color: string, width: number, strokeWidth: number, bezier: string, fill: string, arrowStart: string, arrowEnd: string, - dash: string | undefined, scalex: number, scaley: number, shape: string, pevents: string, drawHalo: boolean, nodefs: boolean) { - let pts: { X: number; Y: number; }[] = []; - if (shape) { //if any of the shape are true - pts = makePolygon(shape, points); - } - else if ((points.length >= 5 && points[3].X === points[4].X) || (points.length === 4)) { - for (var i = 0; i < points.length - 3; i += 4) { - const array = [[points[i].X, points[i].Y], [points[i + 1].X, points[i + 1].Y], [points[i + 2].X, points[i + 2].Y], [points[i + 3].X, points[i + 3].Y]]; - for (var t = 0; t < 1; t += 0.01) { - const point = beziercurve(t, array); - pts.push({ X: point[0], Y: point[1] }); - } - } - } - else if (points.length > 1 && points[points.length - 1].X === points[0].X && points[points.length - 1].Y === points[0].Y) { - //pointer is up (first and last points are the same) - const newPoints = points.reduce((p, pts) => { p.push([pts.X, pts.Y]); return p; }, [] as number[][]); - newPoints.pop(); - - const bezierCurves = fitCurve(newPoints, parseInt(bezier)); - for (const curve of bezierCurves) { - for (var t = 0; t < 1; t += 0.01) { - const point = beziercurve(t, curve); - pts.push({ X: point[0], Y: point[1] }); - } - } - } else { - pts = points.slice(); - // bcz: Ugh... this is ugly, but shapes apprently have an extra point added that is = (p[0].x,p[0].y+1) as some sort of flag. need to remove it here. - if (pts.length > 2 && pts[pts.length - 2].X === pts[0].X && pts[pts.length - 2].Y === pts[0].Y) { - pts.pop(); - } - } - if (isNaN(scalex)) { - scalex = 1; - } - if (isNaN(scaley)) { - scaley = 1; - } - const strpts = pts.reduce((acc: string, pt: { X: number, Y: number }) => acc + - `${(pt.X - left - width / 2) * scalex + width / 2}, - ${(pt.Y - top - width / 2) * scaley + width / 2} `, ""); const dashArray = dash && Number(dash) ? String(Number(width) * Number(dash)) : undefined; const defGuid = Utils.GenerateGuid(); - const arrowDim = Math.max(0.5, 8 / Math.log(Math.max(2, strokeWidth))); - - const addables = pts.map((pts, i) => - <svg height="10" width="10"> - <circle cx={(pts.X - left - width / 2) * scalex + width / 2} cy={(pts.Y - top - width / 2) * scaley + width / 2} r={strokeWidth / 2} stroke="black" strokeWidth={1} fill="blue" - onDoubleClick={(e) => { console.log(i); }} pointerEvents="all" cursor="all-scroll" - /> - </svg>); - + const Tag = (bezier ? "path" : "polyline") as keyof JSX.IntrinsicElements; + const makerStrokeWidth = strokeWidth / 2; return (<svg fill={color}> {/* setting the svg fill sets the arrowStart fill */} {nodefs ? (null) : <defs> - {arrowStart !== "dot" && arrowEnd !== "dot" ? (null) : <marker id={`dot${defGuid}`} orient="auto" overflow="visible"> - <circle r={1} fill="context-stroke" /> - </marker>} - {arrowStart !== "arrow" && arrowEnd !== "arrow" ? (null) : <marker id={`arrowStart${defGuid}`} orient="auto" overflow="visible" refX="1.6" refY="0" markerWidth="10" markerHeight="7"> - <polygon points={`${arrowDim} ${-Math.max(1, arrowDim / 2)}, ${arrowDim} ${Math.max(1, arrowDim / 2)}, -1 0`} /> - </marker>} - {arrowStart !== "arrow" && arrowEnd !== "arrow" ? (null) : <marker id={`arrowEnd${defGuid}`} orient="auto" overflow="visible" refX="1.6" refY="0" markerWidth="10" markerHeight="7"> - <polygon points={`${2 - arrowDim} ${-Math.max(1, arrowDim / 2)}, ${2 - arrowDim} ${Math.max(1, arrowDim / 2)}, 3 0`} /> - </marker>} + {arrowStart !== "dot" && arrowEnd !== "dot" ? (null) : + <marker id={`dot${defGuid}`} orient="auto" markerUnits="userSpaceOnUse" refX={0} refY="0" overflow="visible"> + <circle r={strokeWidth * 1.5} fill="context-stroke" /> + </marker>} + {arrowStart !== "arrow" ? (null) : + <marker id={`arrowStart${defGuid}`} markerUnits="userSpaceOnUse" orient="auto" overflow="visible" refX={makerStrokeWidth * 1.5} refY={0} markerWidth="10" markerHeight="7"> + <polygon style={{ stroke: color }} strokeLinejoin={lineJoin as any} strokeWidth={makerStrokeWidth * 2 / 3} points={`${3 * makerStrokeWidth} ${-makerStrokeWidth * 1.5}, ${makerStrokeWidth * 2} 0, ${3 * makerStrokeWidth} ${makerStrokeWidth * 1.5}, 0 0`} /> + </marker>} + {arrowEnd !== "arrow" ? (null) : + <marker id={`arrowEnd${defGuid}`} markerUnits="userSpaceOnUse" orient="auto" overflow="visible" refX={makerStrokeWidth * 1.5} refY={0} markerWidth="10" markerHeight="7"> + <polygon style={{ stroke: color }} strokeLinejoin={lineJoin as any} strokeWidth={makerStrokeWidth * 2 / 3} points={`0 ${-makerStrokeWidth * 1.5}, ${makerStrokeWidth} 0, 0 ${makerStrokeWidth * 1.5}, ${3 * makerStrokeWidth} 0`} /> + </marker>} </defs>} - <polyline - points={strpts} + + <Tag + d={bezier ? strpts : undefined} + points={bezier ? undefined : strpts} style={{ // filter: drawHalo ? "url(#inkSelectionHalo)" : undefined, - fill: fill ? fill : "none", + fill: fill && fill !== "transparent" ? fill : "none", opacity: 1.0, // opacity: strokeWidth !== width ? 0.5 : undefined, pointerEvents: pevents as any, stroke: color ?? "rgb(0, 0, 0)", strokeWidth: strokeWidth, - strokeLinejoin: "round", - strokeLinecap: "round", + strokeLinecap: lineCap as any, strokeDasharray: dashArray }} - markerStart={`url(#${arrowStart + "Start" + defGuid})`} - markerEnd={`url(#${arrowEnd + "End" + defGuid})`} + markerStart={`url(#${arrowStart === "dot" ? arrowStart + defGuid : arrowStart + "Start" + defGuid})`} + markerEnd={`url(#${arrowEnd === "dot" ? arrowEnd + defGuid : arrowEnd + "End" + defGuid})`} /> - {/* {addables} */} </svg>); } |