UNPKG

4.41 kBJavaScriptView Raw
1/*
2* Copyright (C) 1998-2021 by Northwoods Software Corporation. All Rights Reserved.
3*/
4/*
5* This is an extension and not part of the main GoJS library.
6* Note that the API for this class may change with any version, even point releases.
7* If you intend to use an extension in production, you should copy the code to your own source directory.
8* Extensions can be found in the GoJS kit under the extensions or extensionsTS folders.
9* See the Extensions intro page (https://gojs.net/latest/intro/extensions.html) for more information.
10*/
11import * as go from '../release/go-module.js';
12/**
13 * This CurvedLinkReshapingTool class allows for a {@link Link}'s path to be modified by the user
14 * via the dragging of a single tool handle at the middle of the link.
15 * Dragging the handle changes the value of {@link Link#curviness}.
16 *
17 * If you want to experiment with this extension, try the <a href="../../extensionsJSM/CurvedLinkReshaping.html">Curved Link Reshaping</a> sample.
18 * @category Tool Extension
19 */
20export class CurvedLinkReshapingTool extends go.LinkReshapingTool {
21 constructor() {
22 super(...arguments);
23 this._originalCurviness = NaN;
24 }
25 /**
26 * @hidden @internal
27 */
28 makeAdornment(pathshape) {
29 const link = pathshape.part;
30 if (link !== null && link.curve === go.Link.Bezier && link.pointsCount === 4) {
31 const adornment = new go.Adornment();
32 adornment.type = go.Panel.Link;
33 const h = this.makeHandle(pathshape, 0);
34 this.setReshapingBehavior(h, go.LinkReshapingTool.All);
35 h.cursor = 'move';
36 adornment.add(h);
37 adornment.category = this.name;
38 adornment.adornedObject = pathshape;
39 return adornment;
40 }
41 else {
42 return super.makeAdornment(pathshape);
43 }
44 }
45 /**
46 * Start reshaping, if {@link #findToolHandleAt} finds a reshape handle at the mouse down point.
47 *
48 * If successful this sets {@link #handle} to be the reshape handle that it finds
49 * and {@link #adornedLink} to be the {@link Link} being routed.
50 * It also remembers the original link route (a list of Points) and curviness in case this tool is cancelled.
51 * And it starts a transaction.
52 */
53 doActivate() {
54 super.doActivate();
55 if (this.adornedLink !== null)
56 this._originalCurviness = this.adornedLink.curviness;
57 }
58 /**
59 * Restore the link route to be the original points and curviness and stop this tool.
60 */
61 doCancel() {
62 if (this.adornedLink !== null)
63 this.adornedLink.curviness = this._originalCurviness;
64 super.doCancel();
65 }
66 /**
67 * Change the route of the {@link #adornedLink} by moving the point corresponding to the current
68 * {@link #handle} to be at the given {@link Point}.
69 * This is called by {@link #doMouseMove} and {@link #doMouseUp} with the result of calling
70 * {@link #computeReshape} to constrain the input point.
71 * @param {Point} newpt the value of the call to {@link #computeReshape}.
72 */
73 reshape(newpt) {
74 const link = this.adornedLink;
75 if (link !== null && link.curve === go.Link.Bezier && link.pointsCount === 4) {
76 const start = link.getPoint(0);
77 const end = link.getPoint(3);
78 const ang = start.directionPoint(end);
79 const mid = new go.Point((start.x + end.x) / 2, (start.y + end.y) / 2);
80 const a = new go.Point(9999, 0).rotate(ang + 90).add(mid);
81 const b = new go.Point(9999, 0).rotate(ang - 90).add(mid);
82 const q = newpt.copy().projectOntoLineSegmentPoint(a, b);
83 let curviness = Math.sqrt(mid.distanceSquaredPoint(q));
84 const port = link.fromPort;
85 if (port === link.toPort && port !== null) {
86 if (newpt.y < port.getDocumentPoint(go.Spot.Center).y)
87 curviness = -curviness;
88 }
89 else {
90 const diff = mid.directionPoint(q) - ang;
91 if ((diff > 0 && diff < 180) || (diff < -180))
92 curviness = -curviness;
93 }
94 link.curviness = curviness;
95 }
96 else {
97 super.reshape(newpt);
98 }
99 }
100}