plotboilerplate 1.17.1 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -6
- package/dist/index.esm.js +278 -60
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/dist/plotboilerplate.browser.min.js +1 -1
- package/dist/plotboilerplate.browser.min.js.map +1 -1
- package/dist/plotboilerplate.js +276 -58
- package/dist/plotboilerplate.min.js +1 -1
- package/package.json +1 -1
- package/src/cjs/Bounds.d.ts +11 -1
- package/src/cjs/Bounds.js +13 -1
- package/src/cjs/Bounds.js.map +1 -1
- package/src/cjs/Circle.d.ts +36 -2
- package/src/cjs/Circle.js +81 -1
- package/src/cjs/Circle.js.map +1 -1
- package/src/cjs/CubicBezierCurve.d.ts +20 -3
- package/src/cjs/CubicBezierCurve.js +25 -2
- package/src/cjs/CubicBezierCurve.js.map +1 -1
- package/src/cjs/Line.d.ts +46 -4
- package/src/cjs/Line.js +60 -3
- package/src/cjs/Line.js.map +1 -1
- package/src/cjs/MouseHandler.d.ts +3 -2
- package/src/cjs/MouseHandler.js +16 -14
- package/src/cjs/MouseHandler.js.map +1 -1
- package/src/cjs/PlotBoilerplate.d.ts +4 -2
- package/src/cjs/PlotBoilerplate.js +44 -28
- package/src/cjs/PlotBoilerplate.js.map +1 -1
- package/src/cjs/Polygon.js +1 -1
- package/src/cjs/Polygon.js.map +1 -1
- package/src/cjs/Vector.d.ts +14 -3
- package/src/cjs/Vector.js +21 -2
- package/src/cjs/Vector.js.map +1 -1
- package/src/cjs/draw.d.ts +4 -1
- package/src/cjs/draw.js +15 -6
- package/src/cjs/draw.js.map +1 -1
- package/src/cjs/interfaces/additionals.d.ts +95 -0
- package/src/cjs/interfaces/additionals.js +3 -0
- package/src/cjs/interfaces/additionals.js.map +1 -0
- package/src/cjs/interfaces/core.d.ts +4 -0
- package/src/cjs/interfaces/core.js +1 -0
- package/src/cjs/interfaces/core.js.map +1 -1
- package/src/cjs/interfaces/index.d.ts +1 -0
- package/src/cjs/interfaces/index.js +1 -0
- package/src/cjs/interfaces/index.js.map +1 -1
- package/src/cjs/utils/algorithms/arrayShuffle.d.ts +8 -0
- package/src/cjs/utils/algorithms/arrayShuffle.js +15 -0
- package/src/cjs/utils/algorithms/arrayShuffle.js.map +1 -0
- package/src/cjs/utils/algorithms/detectPaths.d.ts +20 -0
- package/src/cjs/utils/algorithms/detectPaths.js +169 -0
- package/src/cjs/utils/algorithms/detectPaths.js.map +1 -0
- package/src/cjs/utils/datastructures/GenericPath.d.ts +75 -0
- package/src/cjs/utils/datastructures/GenericPath.js +105 -0
- package/src/cjs/utils/datastructures/GenericPath.js.map +1 -0
- package/src/cjs/utils/datastructures/GirihTile.d.ts +1 -1
- package/src/esm/Bounds.d.ts +11 -1
- package/src/esm/Bounds.js +13 -1
- package/src/esm/Bounds.js.map +1 -1
- package/src/esm/Circle.d.ts +36 -2
- package/src/esm/Circle.js +81 -1
- package/src/esm/Circle.js.map +1 -1
- package/src/esm/CubicBezierCurve.d.ts +20 -3
- package/src/esm/CubicBezierCurve.js +25 -2
- package/src/esm/CubicBezierCurve.js.map +1 -1
- package/src/esm/Line.d.ts +46 -4
- package/src/esm/Line.js +60 -3
- package/src/esm/Line.js.map +1 -1
- package/src/esm/MouseHandler.d.ts +3 -2
- package/src/esm/MouseHandler.js +16 -14
- package/src/esm/MouseHandler.js.map +1 -1
- package/src/esm/PlotBoilerplate.d.ts +4 -2
- package/src/esm/PlotBoilerplate.js +44 -28
- package/src/esm/PlotBoilerplate.js.map +1 -1
- package/src/esm/Polygon.js +1 -1
- package/src/esm/Polygon.js.map +1 -1
- package/src/esm/Vector.d.ts +13 -2
- package/src/esm/Vector.js +23 -4
- package/src/esm/Vector.js.map +1 -1
- package/src/esm/draw.d.ts +4 -1
- package/src/esm/draw.js +15 -6
- package/src/esm/draw.js.map +1 -1
- package/src/esm/interfaces/additionals.d.ts +95 -0
- package/src/esm/interfaces/additionals.js +2 -0
- package/src/esm/interfaces/additionals.js.map +1 -0
- package/src/esm/interfaces/core.d.ts +4 -0
- package/src/esm/interfaces/core.js +1 -0
- package/src/esm/interfaces/core.js.map +1 -1
- package/src/esm/interfaces/index.d.ts +1 -0
- package/src/esm/interfaces/index.js +1 -0
- package/src/esm/interfaces/index.js.map +1 -1
- package/src/esm/utils/algorithms/arrayShuffle.d.ts +8 -0
- package/src/esm/utils/algorithms/arrayShuffle.js +11 -0
- package/src/esm/utils/algorithms/arrayShuffle.js.map +1 -0
- package/src/esm/utils/algorithms/detectPaths.d.ts +20 -0
- package/src/esm/utils/algorithms/detectPaths.js +165 -0
- package/src/esm/utils/algorithms/detectPaths.js.map +1 -0
- package/src/esm/utils/datastructures/GenericPath.d.ts +75 -0
- package/src/esm/utils/datastructures/GenericPath.js +100 -0
- package/src/esm/utils/datastructures/GenericPath.js.map +1 -0
- package/src/esm/utils/datastructures/GirihTile.d.ts +1 -1
- package/src/ts/Bounds.ts +14 -1
- package/src/ts/Circle.ts +92 -2
- package/src/ts/CubicBezierCurve.ts +29 -4
- package/src/ts/Line.ts +70 -6
- package/src/ts/MouseHandler.ts +16 -15
- package/src/ts/PlotBoilerplate.ts +47 -32
- package/src/ts/Polygon.ts +1 -1
- package/src/ts/Vector.ts +24 -4
- package/src/ts/draw.ts +15 -6
- package/src/ts/interfaces/additionals.ts +105 -0
- package/src/ts/interfaces/core.ts +2 -0
- package/src/ts/interfaces/index.ts +1 -0
- package/src/ts/utils/algorithms/arrayShuffle.ts +11 -0
- package/src/ts/utils/algorithms/detectPaths.ts +195 -0
- package/src/ts/utils/datastructures/GenericPath.ts +113 -0
- package/src/ts/utils/datastructures/GirihTile.ts +1 -1
- package/changelog.md +0 -722
package/src/ts/Line.ts
CHANGED
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
* @modified 2020-03-23 Ported to Typescript from JS.
|
|
14
14
|
* @modified 2020-12-04 The `intersection` function returns undefined if both lines are parallel.
|
|
15
15
|
* @modified 2022-02-02 Added the `destroy` method.
|
|
16
|
-
* @
|
|
16
|
+
* @modified 2022-10-09 Changed the actual return value of the `intersection` function to null (was undefined before).
|
|
17
|
+
* @modified 2022-10-17 Adding these methods from the `PathSegment` interface: getStartPoint, getEndPoint, revert.
|
|
18
|
+
* @version 2.3.0
|
|
17
19
|
*
|
|
18
20
|
* @file Line
|
|
19
21
|
* @public
|
|
@@ -21,7 +23,7 @@
|
|
|
21
23
|
|
|
22
24
|
import { VertTuple } from "./VertTuple";
|
|
23
25
|
import { Vertex } from "./Vertex";
|
|
24
|
-
import { SVGSerializable } from "./interfaces";
|
|
26
|
+
import { PathSegment, SVGSerializable } from "./interfaces";
|
|
25
27
|
|
|
26
28
|
/**
|
|
27
29
|
* @classdesc A line consists of two vertices a and b.<br>
|
|
@@ -31,7 +33,7 @@ import { SVGSerializable } from "./interfaces";
|
|
|
31
33
|
*
|
|
32
34
|
* @requires Vertex
|
|
33
35
|
*/
|
|
34
|
-
export class Line extends VertTuple<Line> implements SVGSerializable {
|
|
36
|
+
export class Line extends VertTuple<Line> implements SVGSerializable, PathSegment {
|
|
35
37
|
/**
|
|
36
38
|
* Required to generate proper CSS classes and other class related IDs.
|
|
37
39
|
**/
|
|
@@ -59,9 +61,11 @@ export class Line extends VertTuple<Line> implements SVGSerializable {
|
|
|
59
61
|
* @memberof Line
|
|
60
62
|
**/
|
|
61
63
|
// !!! DO NOT MOVE TO VertTuple
|
|
62
|
-
intersection(line: Line): Vertex |
|
|
64
|
+
intersection(line: Line): Vertex | null {
|
|
63
65
|
const denominator: number = this.denominator(line);
|
|
64
|
-
if (denominator == 0)
|
|
66
|
+
if (denominator == 0) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
65
69
|
|
|
66
70
|
let a: number = this.a.y - line.a.y;
|
|
67
71
|
let b: number = this.a.x - line.a.x;
|
|
@@ -75,10 +79,70 @@ export class Line extends VertTuple<Line> implements SVGSerializable {
|
|
|
75
79
|
const y: number = this.a.y + a * (this.b.y - this.a.y);
|
|
76
80
|
|
|
77
81
|
if (isNaN(a) || isNaN(x) || isNaN(y)) {
|
|
78
|
-
return
|
|
82
|
+
return null;
|
|
79
83
|
}
|
|
80
84
|
|
|
81
85
|
// if we cast these lines infinitely in both directions, they intersect here:
|
|
82
86
|
return new Vertex(x, y);
|
|
83
87
|
}
|
|
88
|
+
|
|
89
|
+
//--- Implement PathSegment ---
|
|
90
|
+
/**
|
|
91
|
+
* Get the start point of this path segment.
|
|
92
|
+
*
|
|
93
|
+
* @method getStartPoint
|
|
94
|
+
* @memberof PathSegment
|
|
95
|
+
* @return {Vertex} The start point of this path segment.
|
|
96
|
+
*/
|
|
97
|
+
getStartPoint(): Vertex {
|
|
98
|
+
return this.a;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Get the end point of this path segment.
|
|
103
|
+
*
|
|
104
|
+
* @method getEndPoint
|
|
105
|
+
* @memberof PathSegment
|
|
106
|
+
* @return {Vertex} The end point of this path segment.
|
|
107
|
+
*/
|
|
108
|
+
getEndPoint(): Vertex {
|
|
109
|
+
return this.b;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Get the tangent's end point at the start point of this segment.
|
|
114
|
+
*
|
|
115
|
+
* @method getStartTangent
|
|
116
|
+
* @memberof PathSegment
|
|
117
|
+
* @return {Vertex} The end point of the starting point's tangent.
|
|
118
|
+
*/
|
|
119
|
+
getStartTangent(): Vertex {
|
|
120
|
+
return this.b;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Get the tangent's end point at the end point of this segment.
|
|
125
|
+
*
|
|
126
|
+
* @method getEndTangent
|
|
127
|
+
* @memberof PathSegment
|
|
128
|
+
* @return {Vertex} The end point of the ending point's tangent.
|
|
129
|
+
*/
|
|
130
|
+
getEndTangent(): Vertex {
|
|
131
|
+
return this.a;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Inverse this path segment (in-place) and return this same instance (useful for chaining).
|
|
136
|
+
*
|
|
137
|
+
* @method reverse
|
|
138
|
+
* @memberof PathSegment
|
|
139
|
+
* @return {PathSegment} This path segment instance (for chaining).
|
|
140
|
+
*/
|
|
141
|
+
reverse(): Line {
|
|
142
|
+
var tmp = this.a;
|
|
143
|
+
this.a = this.b;
|
|
144
|
+
this.b = tmp;
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
//--- END Implement PathSegment ---
|
|
84
148
|
}
|
package/src/ts/MouseHandler.ts
CHANGED
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
* @modified 2020-10-04 Added extended JSDoc comments.
|
|
18
18
|
* @modified 2020-11-25 Added the `isTouchEvent` param.
|
|
19
19
|
* @modified 2021-01-10 The mouse handler is now also working with SVGElements.
|
|
20
|
-
* @
|
|
20
|
+
* @modified 2022-08-16 Fixed a bug in the mouse button detection.
|
|
21
|
+
* @version 1.2.1
|
|
21
22
|
*
|
|
22
23
|
* @file MouseHandler
|
|
23
24
|
* @public
|
|
@@ -58,7 +59,7 @@ export type XWheelCallback = (e: XWheelEvent) => void;
|
|
|
58
59
|
* @requires XYCoords
|
|
59
60
|
*/
|
|
60
61
|
export class MouseHandler {
|
|
61
|
-
private name: string;
|
|
62
|
+
private name: string | undefined;
|
|
62
63
|
private element: HTMLElement | SVGElement;
|
|
63
64
|
private mouseDownPos: { x: number; y: number } | undefined = undefined;
|
|
64
65
|
private mouseDragPos: { x: number; y: number } | undefined = undefined;
|
|
@@ -135,8 +136,8 @@ export class MouseHandler {
|
|
|
135
136
|
// +-------------------------------------------------
|
|
136
137
|
this.name = name;
|
|
137
138
|
this.element = element;
|
|
138
|
-
this.mouseDownPos =
|
|
139
|
-
this.mouseDragPos =
|
|
139
|
+
this.mouseDownPos = undefined;
|
|
140
|
+
this.mouseDragPos = undefined;
|
|
140
141
|
// this.mousePos = null;
|
|
141
142
|
this.mouseButton = -1;
|
|
142
143
|
this.listeners = {};
|
|
@@ -202,26 +203,26 @@ export class MouseHandler {
|
|
|
202
203
|
* @memberof MouseHandler
|
|
203
204
|
* @instance
|
|
204
205
|
* @private
|
|
205
|
-
* @param {MouseEvent}
|
|
206
|
+
* @param {MouseEvent} event - The mouse event to get the relative position for.
|
|
206
207
|
* @param {string} eventName - The name of the firing event.
|
|
207
208
|
* @return {XMouseEvent}
|
|
208
209
|
*/
|
|
209
|
-
private mkParams(
|
|
210
|
-
const rel: { x: number; y: number } = this.relPos(
|
|
211
|
-
const xEvent: XMouseEvent =
|
|
210
|
+
private mkParams(event: MouseEvent, eventName: string): XMouseEvent {
|
|
211
|
+
const rel: { x: number; y: number } = this.relPos(event);
|
|
212
|
+
const xEvent: XMouseEvent = event as unknown as XMouseEvent;
|
|
212
213
|
xEvent.params = {
|
|
213
214
|
element: this.element,
|
|
214
215
|
name: eventName,
|
|
215
216
|
isTouchEvent: false,
|
|
216
217
|
pos: rel,
|
|
217
|
-
button: this.mouseButton,
|
|
218
|
-
leftButton: this.mouseButton
|
|
219
|
-
middleButton: this.mouseButton
|
|
220
|
-
rightButton: this.mouseButton
|
|
221
|
-
mouseDownPos: this.mouseDownPos,
|
|
222
|
-
draggedFrom: this.mouseDragPos,
|
|
218
|
+
button: event.button, // this.mouseButton,
|
|
219
|
+
leftButton: event.button === 0, // this.mouseButton === 0,
|
|
220
|
+
middleButton: event.button === 1, // this.mouseButton === 1,
|
|
221
|
+
rightButton: event.button === 2, // this.mouseButton === 2,
|
|
222
|
+
mouseDownPos: this.mouseDownPos ?? { x: NaN, y: NaN },
|
|
223
|
+
draggedFrom: this.mouseDragPos ?? { x: NaN, y: NaN },
|
|
223
224
|
wasDragged: this.mouseDownPos != null && (this.mouseDownPos.x != rel.x || this.mouseDownPos.y != rel.y),
|
|
224
|
-
dragAmount: this.
|
|
225
|
+
dragAmount: this.mouseDragPos != null ? { x: rel.x - this.mouseDragPos.x, y: rel.y - this.mouseDragPos.y } : { x: 0, y: 0 }
|
|
225
226
|
};
|
|
226
227
|
return xEvent;
|
|
227
228
|
}
|
|
@@ -75,7 +75,9 @@
|
|
|
75
75
|
* @modified 2021-04-25 Extending `remove` to accept arrays of drawables.
|
|
76
76
|
* @modified 2021-11-16 Adding the `PBText` drawable.
|
|
77
77
|
* @modified 2022-08-01 Added `title` to the params.
|
|
78
|
-
* @
|
|
78
|
+
* @modified 2022-10-25 Added the `origin` to the default draw config.
|
|
79
|
+
* @modified 2022-11-06 Adding an XML declaration to the SVG export routine.
|
|
80
|
+
* @version 1.16.0
|
|
79
81
|
*
|
|
80
82
|
* @file PlotBoilerplate
|
|
81
83
|
* @fileoverview The main class.
|
|
@@ -270,7 +272,7 @@ export class PlotBoilerplate {
|
|
|
270
272
|
* @memberof PlotBoilerplate
|
|
271
273
|
* @instance
|
|
272
274
|
*/
|
|
273
|
-
selectPolygon: Polygon;
|
|
275
|
+
selectPolygon: Polygon | null;
|
|
274
276
|
|
|
275
277
|
/**
|
|
276
278
|
* @member {Array<IDraggable>}
|
|
@@ -532,6 +534,9 @@ export class PlotBoilerplate {
|
|
|
532
534
|
lineWidth: 1,
|
|
533
535
|
fill: true,
|
|
534
536
|
anchor: true
|
|
537
|
+
},
|
|
538
|
+
origin: {
|
|
539
|
+
color: "#000000"
|
|
535
540
|
}
|
|
536
541
|
}; // END drawConfig
|
|
537
542
|
|
|
@@ -554,14 +559,16 @@ export class PlotBoilerplate {
|
|
|
554
559
|
this.config.enableGL = false;
|
|
555
560
|
}
|
|
556
561
|
if (this.config.enableGL) {
|
|
557
|
-
|
|
562
|
+
// Override the case 'null' here. If GL is not supported, well then nothing works.
|
|
563
|
+
const ctx: WebGLRenderingContext = this.canvas.getContext("webgl") as WebGLRenderingContext; // webgl-experimental?
|
|
558
564
|
this.draw = new drawutilsgl(ctx, false);
|
|
559
565
|
// PROBLEM: same instance of fill and draw when using WebGL.
|
|
560
566
|
// Shader program cannot be duplicated on the same context.
|
|
561
567
|
this.fill = (this.draw as drawutilsgl).copyInstance(true);
|
|
562
568
|
console.warn("Initialized with experimental mode enableGL=true. Note that this is not yet fully implemented.");
|
|
563
569
|
} else {
|
|
564
|
-
|
|
570
|
+
// Override the case 'null' here. If context creation is not supported, well then nothing works.
|
|
571
|
+
const ctx: CanvasRenderingContext2D = this.canvas.getContext("2d") as CanvasRenderingContext2D;
|
|
565
572
|
this.draw = new drawutils(ctx, false);
|
|
566
573
|
this.fill = new drawutils(ctx, true);
|
|
567
574
|
}
|
|
@@ -599,8 +606,8 @@ export class PlotBoilerplate {
|
|
|
599
606
|
if (config.title) {
|
|
600
607
|
this.eventCatcher.setAttribute("title", config.title);
|
|
601
608
|
}
|
|
602
|
-
this.draw.scale.set(this.config.scaleX, this.config.scaleY);
|
|
603
|
-
this.fill.scale.set(this.config.scaleX, this.config.scaleY);
|
|
609
|
+
this.draw.scale.set(this.config.scaleX ?? 1.0, this.config.scaleY);
|
|
610
|
+
this.fill.scale.set(this.config.scaleX ?? 1.0, this.config.scaleY);
|
|
604
611
|
this.vertices = [];
|
|
605
612
|
this.selectPolygon = null;
|
|
606
613
|
this.draggedElements = [];
|
|
@@ -655,9 +662,13 @@ export class PlotBoilerplate {
|
|
|
655
662
|
|
|
656
663
|
tosvgDraw.beginDrawCycle(0);
|
|
657
664
|
tosvgFill.beginDrawCycle(0);
|
|
658
|
-
if (pb.config.preClear)
|
|
659
|
-
|
|
660
|
-
|
|
665
|
+
if (pb.config.preClear) {
|
|
666
|
+
pb.config.preClear();
|
|
667
|
+
}
|
|
668
|
+
tosvgDraw.clear(pb.config.backgroundColor || "white");
|
|
669
|
+
if (pb.config.preDraw) {
|
|
670
|
+
pb.config.preDraw(tosvgDraw, tosvgFill);
|
|
671
|
+
}
|
|
661
672
|
pb.drawAll(0, tosvgDraw, tosvgFill);
|
|
662
673
|
pb.drawVertices(0, tosvgDraw);
|
|
663
674
|
if (pb.config.postDraw) pb.config.postDraw(tosvgDraw, tosvgFill);
|
|
@@ -669,7 +680,8 @@ export class PlotBoilerplate {
|
|
|
669
680
|
var serializer = new XMLSerializer();
|
|
670
681
|
var svgCode = serializer.serializeToString(svgNode);
|
|
671
682
|
|
|
672
|
-
|
|
683
|
+
// Add: '<?xml version="1.0" encoding="utf-8"?>\n' ?
|
|
684
|
+
var blob = new Blob(['<?xml version="1.0" encoding="utf-8"?>\n' + svgCode], { type: "image/svg;charset=utf-8" });
|
|
673
685
|
// See documentation for FileSaver.js for usage.
|
|
674
686
|
// https://github.com/eligrey/FileSaver.js
|
|
675
687
|
if (typeof globalThis["saveAs"] !== "function")
|
|
@@ -751,9 +763,9 @@ export class PlotBoilerplate {
|
|
|
751
763
|
**/
|
|
752
764
|
private updateCSSscale() {
|
|
753
765
|
if (this.config.cssUniformScale) {
|
|
754
|
-
PlotBoilerplate.utils.setCSSscale(this.canvas, this.config.cssScaleX, this.config.cssScaleX);
|
|
766
|
+
PlotBoilerplate.utils.setCSSscale(this.canvas, this.config.cssScaleX ?? 1.0, this.config.cssScaleX ?? 1.0);
|
|
755
767
|
} else {
|
|
756
|
-
PlotBoilerplate.utils.setCSSscale(this.canvas, this.config.cssScaleX, this.config.cssScaleY);
|
|
768
|
+
PlotBoilerplate.utils.setCSSscale(this.canvas, this.config.cssScaleX ?? 1.0, this.config.cssScaleY ?? 1.0);
|
|
757
769
|
}
|
|
758
770
|
}
|
|
759
771
|
|
|
@@ -1011,7 +1023,7 @@ export class PlotBoilerplate {
|
|
|
1011
1023
|
getVertexNear(pixelPosition: XYCoords, pixelTolerance: number): Vertex | undefined {
|
|
1012
1024
|
var p: IDraggable | undefined = this.locatePointNear(
|
|
1013
1025
|
this.transformMousePosition(pixelPosition.x, pixelPosition.y),
|
|
1014
|
-
pixelTolerance / Math.min(this.config.cssScaleX, this.config.cssScaleY)
|
|
1026
|
+
pixelTolerance / Math.min(this.config.cssScaleX ?? 1.0, this.config.cssScaleY ?? 1.0)
|
|
1015
1027
|
);
|
|
1016
1028
|
if (p && p.typeName == "vertex") {
|
|
1017
1029
|
return this.vertices[p.vindex];
|
|
@@ -1095,7 +1107,7 @@ export class PlotBoilerplate {
|
|
|
1095
1107
|
drawOrigin(draw: DrawLib<any>) {
|
|
1096
1108
|
// Add a crosshair to mark the origin
|
|
1097
1109
|
draw.setCurrentId("origin");
|
|
1098
|
-
draw.crosshair({ x: 0, y: 0 }, 10,
|
|
1110
|
+
draw.crosshair({ x: 0, y: 0 }, 10, this.drawConfig.origin.color);
|
|
1099
1111
|
}
|
|
1100
1112
|
|
|
1101
1113
|
/**
|
|
@@ -1360,10 +1372,10 @@ export class PlotBoilerplate {
|
|
|
1360
1372
|
} else {
|
|
1361
1373
|
console.error("Cannot draw object. Unknown class.");
|
|
1362
1374
|
}
|
|
1363
|
-
draw.setCurrentClassName(
|
|
1364
|
-
draw.setCurrentId(
|
|
1365
|
-
fill.setCurrentClassName(
|
|
1366
|
-
fill.setCurrentId(
|
|
1375
|
+
draw.setCurrentClassName(undefined);
|
|
1376
|
+
draw.setCurrentId(undefined);
|
|
1377
|
+
fill.setCurrentClassName(undefined);
|
|
1378
|
+
fill.setCurrentId(undefined);
|
|
1367
1379
|
}
|
|
1368
1380
|
|
|
1369
1381
|
/**
|
|
@@ -1473,7 +1485,7 @@ export class PlotBoilerplate {
|
|
|
1473
1485
|
**/
|
|
1474
1486
|
clear() {
|
|
1475
1487
|
// Note that elements might have an alpha channel. Clear the scene first.
|
|
1476
|
-
this.draw.clear(this.config.backgroundColor);
|
|
1488
|
+
this.draw.clear(this.config.backgroundColor || "white");
|
|
1477
1489
|
}
|
|
1478
1490
|
|
|
1479
1491
|
/**
|
|
@@ -1505,7 +1517,10 @@ export class PlotBoilerplate {
|
|
|
1505
1517
|
viewport(): Bounds {
|
|
1506
1518
|
return new Bounds(
|
|
1507
1519
|
this.transformMousePosition(0, 0),
|
|
1508
|
-
this.transformMousePosition(
|
|
1520
|
+
this.transformMousePosition(
|
|
1521
|
+
this.canvasSize.width * (this.config.cssScaleX ?? 1.0),
|
|
1522
|
+
this.canvasSize.height * (this.config.cssScaleY ?? 1.0)
|
|
1523
|
+
)
|
|
1509
1524
|
);
|
|
1510
1525
|
}
|
|
1511
1526
|
|
|
@@ -1569,8 +1584,8 @@ export class PlotBoilerplate {
|
|
|
1569
1584
|
resizeCanvas() {
|
|
1570
1585
|
const _self: PlotBoilerplate = this;
|
|
1571
1586
|
const _setSize = (w: number, h: number) => {
|
|
1572
|
-
w *= _self.config.canvasWidthFactor;
|
|
1573
|
-
h *= _self.config.canvasHeightFactor;
|
|
1587
|
+
w *= _self.config.canvasWidthFactor ?? 1.0;
|
|
1588
|
+
h *= _self.config.canvasHeightFactor ?? 1.0;
|
|
1574
1589
|
_self.canvasSize.width = w;
|
|
1575
1590
|
_self.canvasSize.height = h;
|
|
1576
1591
|
if (_self.canvas instanceof HTMLCanvasElement) {
|
|
@@ -1597,8 +1612,8 @@ export class PlotBoilerplate {
|
|
|
1597
1612
|
var width: number = globalThis.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
|
|
1598
1613
|
var height: number = globalThis.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
|
|
1599
1614
|
_self.canvas.style.position = "absolute";
|
|
1600
|
-
_self.canvas.style.width = _self.config.canvasWidthFactor * width + "px";
|
|
1601
|
-
_self.canvas.style.height = _self.config.canvasWidthFactor * height + "px";
|
|
1615
|
+
_self.canvas.style.width = (_self.config.canvasWidthFactor ?? 1.0) * width + "px";
|
|
1616
|
+
_self.canvas.style.height = (_self.config.canvasWidthFactor ?? 1.0) * height + "px";
|
|
1602
1617
|
_self.canvas.style.top = "0px";
|
|
1603
1618
|
_self.canvas.style.left = "0px";
|
|
1604
1619
|
_setSize(width, height);
|
|
@@ -1606,15 +1621,15 @@ export class PlotBoilerplate {
|
|
|
1606
1621
|
// Set editor size
|
|
1607
1622
|
_self.canvas.style.position = "absolute";
|
|
1608
1623
|
const space: XYDimension = this.getAvailableContainerSpace();
|
|
1609
|
-
_self.canvas.style.width = _self.config.canvasWidthFactor * space.width + "px";
|
|
1610
|
-
_self.canvas.style.height = _self.config.canvasHeightFactor * space.height + "px";
|
|
1611
|
-
_self.canvas.style.top =
|
|
1612
|
-
_self.canvas.style.left =
|
|
1624
|
+
_self.canvas.style.width = (_self.config.canvasWidthFactor ?? 1.0) * space.width + "px";
|
|
1625
|
+
_self.canvas.style.height = (_self.config.canvasHeightFactor ?? 1.0) * space.height + "px";
|
|
1626
|
+
_self.canvas.style.top = "";
|
|
1627
|
+
_self.canvas.style.left = "";
|
|
1613
1628
|
_setSize(space.width, space.height);
|
|
1614
1629
|
} else {
|
|
1615
|
-
_self.canvas.style.width =
|
|
1616
|
-
_self.canvas.style.height =
|
|
1617
|
-
_setSize(_self.config.defaultCanvasWidth, _self.config.defaultCanvasHeight);
|
|
1630
|
+
_self.canvas.style.width = "";
|
|
1631
|
+
_self.canvas.style.height = "";
|
|
1632
|
+
_setSize(_self.config.defaultCanvasWidth ?? 1024, _self.config.defaultCanvasHeight ?? 768);
|
|
1618
1633
|
}
|
|
1619
1634
|
|
|
1620
1635
|
if (_self.config.redrawOnResize) _self.redraw();
|
|
@@ -2269,7 +2284,7 @@ export class PlotBoilerplate {
|
|
|
2269
2284
|
* @param {function} fallback - A default value if the key does not exist.
|
|
2270
2285
|
* @return {function}
|
|
2271
2286
|
**/
|
|
2272
|
-
func: (obj: any, key: string, fallback: (...args: any[]) => any) => {
|
|
2287
|
+
func: (obj: any, key: string, fallback: ((...args: any[]) => any) | null) => {
|
|
2273
2288
|
if (!obj.hasOwnProperty(key)) return fallback;
|
|
2274
2289
|
if (typeof obj[key] !== "function") return fallback;
|
|
2275
2290
|
return obj[key];
|
package/src/ts/Polygon.ts
CHANGED
package/src/ts/Vector.ts
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
* @modified 2021-01-20 Added UID.
|
|
12
12
|
* @modified 2022-02-02 Added the `destroy` method.
|
|
13
13
|
* @modified 2022-02-02 Cleared the `Vector.toSVGString` function (deprecated). Use `drawutilssvg` instead.
|
|
14
|
-
* @
|
|
14
|
+
* @modified 2022-10-25 Added the `getOrthogonal` method.
|
|
15
|
+
* @version 1.5.0
|
|
15
16
|
*
|
|
16
17
|
* @file Vector
|
|
17
18
|
* @public
|
|
@@ -65,7 +66,7 @@ export class Vector extends VertTuple<Vector> implements SVGSerializable {
|
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
/**
|
|
68
|
-
* The inverse of a vector is a vector
|
|
69
|
+
* The inverse of a vector is a vector with the same magnitude but oppose direction.
|
|
69
70
|
*
|
|
70
71
|
* Please not that the origin of this vector changes here: a->b becomes b->a.
|
|
71
72
|
*
|
|
@@ -116,6 +117,25 @@ export class Vector extends VertTuple<Vector> implements SVGSerializable {
|
|
|
116
117
|
return new Vertex(this.a.x + a * (this.b.x - this.a.x), this.a.y + a * (this.b.y - this.a.y));
|
|
117
118
|
}
|
|
118
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Get the orthogonal "vector" of this vector (rotated by 90° clockwise).
|
|
122
|
+
*
|
|
123
|
+
* @name getOrthogonal
|
|
124
|
+
* @method getOrthogonal
|
|
125
|
+
* @return {Vector} A new vector with the same length that stands on this vector's point a.
|
|
126
|
+
* @instance
|
|
127
|
+
* @memberof Vector
|
|
128
|
+
**/
|
|
129
|
+
getOrthogonal(): Vector {
|
|
130
|
+
// Orthogonal of vector (0,0)->(x,y) is (0,0)->(-y,x)
|
|
131
|
+
const linePoint = this.a.clone();
|
|
132
|
+
const startPoint = this.b.clone().sub(this.a);
|
|
133
|
+
const tmp = startPoint.x;
|
|
134
|
+
startPoint.x = -startPoint.y;
|
|
135
|
+
startPoint.y = tmp;
|
|
136
|
+
return new Vector(linePoint, startPoint.add(this.a));
|
|
137
|
+
}
|
|
138
|
+
|
|
119
139
|
static utils = {
|
|
120
140
|
/**
|
|
121
141
|
* Generate a four-point arrow head, starting at the vector end minus the
|
|
@@ -143,8 +163,8 @@ export class Vector extends VertTuple<Vector> implements SVGSerializable {
|
|
|
143
163
|
* @param {number} scaleY - the vertical scaling during draw.
|
|
144
164
|
**/
|
|
145
165
|
buildArrowHead: (zA: Vertex, zB: Vertex, headlen: number, scaleX: number, scaleY: number) => {
|
|
146
|
-
|
|
147
|
-
|
|
166
|
+
const angle = Math.atan2((zB.y - zA.y) * scaleY, (zB.x - zA.x) * scaleX);
|
|
167
|
+
const vertices: Array<Vertex> = [];
|
|
148
168
|
vertices.push(new Vertex(zB.x * scaleX - headlen * Math.cos(angle), zB.y * scaleY - headlen * Math.sin(angle)));
|
|
149
169
|
vertices.push(
|
|
150
170
|
new Vertex(
|
package/src/ts/draw.ts
CHANGED
|
@@ -44,7 +44,10 @@
|
|
|
44
44
|
* @modified 2022-03-27 Added the `texturedPoly` function.
|
|
45
45
|
* @modified 2022-06-01 Tweaked the `polyline` function; lineWidth now scales with scale.x.
|
|
46
46
|
* @modified 2022-07-26 Adding `alpha` to the `image(...)` function.
|
|
47
|
-
* @
|
|
47
|
+
* @modified 2022-08-23 Fixed a type issue in the `polyline` function.
|
|
48
|
+
* @modified 2022-08-23 Fixed a type issue in the `setConfiguration` function.
|
|
49
|
+
* @modified 2022-08-23 Fixed a type issue in the `path` function.
|
|
50
|
+
* @version 1.12.3
|
|
48
51
|
**/
|
|
49
52
|
|
|
50
53
|
import { CubicBezierCurve } from "./CubicBezierCurve";
|
|
@@ -141,7 +144,7 @@ export class drawutils implements DrawLib<void> {
|
|
|
141
144
|
* @param {DrawLibConfiguration} configuration - The new configuration settings to use for the next render methods.
|
|
142
145
|
*/
|
|
143
146
|
setConfiguration(configuration: DrawLibConfiguration): void {
|
|
144
|
-
this.ctx.globalCompositeOperation = configuration.blendMode;
|
|
147
|
+
this.ctx.globalCompositeOperation = configuration.blendMode || "source-over";
|
|
145
148
|
}
|
|
146
149
|
|
|
147
150
|
/**
|
|
@@ -1012,7 +1015,7 @@ export class drawutils implements DrawLib<void> {
|
|
|
1012
1015
|
}
|
|
1013
1016
|
this.ctx.save();
|
|
1014
1017
|
this.ctx.beginPath();
|
|
1015
|
-
this.ctx.lineWidth = lineWidth * this.scale.x
|
|
1018
|
+
this.ctx.lineWidth = (lineWidth || 1.0) * this.scale.x;
|
|
1016
1019
|
this.ctx.moveTo(this.offset.x + vertices[0].x * this.scale.x, this.offset.y + vertices[0].y * this.scale.y);
|
|
1017
1020
|
for (var i = 0; i < vertices.length; i++) {
|
|
1018
1021
|
this.ctx.lineTo(this.offset.x + vertices[i].x * this.scale.x, this.offset.y + vertices[i].y * this.scale.y);
|
|
@@ -1147,13 +1150,19 @@ export class drawutils implements DrawLib<void> {
|
|
|
1147
1150
|
path(pathData: SVGPathParams, color?: string, lineWidth?: number, options?: { inplace?: boolean }) {
|
|
1148
1151
|
const d: SVGPathParams = options && options.inplace ? pathData : drawutilssvg.copyPathData(pathData);
|
|
1149
1152
|
drawutilssvg.transformPathData(d, this.offset, this.scale);
|
|
1150
|
-
|
|
1153
|
+
if (color) {
|
|
1154
|
+
this.ctx.strokeStyle = color;
|
|
1155
|
+
}
|
|
1151
1156
|
this.ctx.lineWidth = lineWidth || 1;
|
|
1152
1157
|
if (this.fillShapes) {
|
|
1153
|
-
|
|
1158
|
+
if (color) {
|
|
1159
|
+
this.ctx.fillStyle = color;
|
|
1160
|
+
}
|
|
1154
1161
|
this.ctx.fill(new Path2D(d.join(" ")));
|
|
1155
1162
|
} else {
|
|
1156
|
-
|
|
1163
|
+
if (color) {
|
|
1164
|
+
this.ctx.strokeStyle = color;
|
|
1165
|
+
}
|
|
1157
1166
|
this.ctx.stroke(new Path2D(d.join(" ")));
|
|
1158
1167
|
}
|
|
1159
1168
|
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @date 2022-10-17
|
|
3
|
+
*/
|
|
4
|
+
import { Vertex } from "../Vertex";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A common interface for different kinds of path segments.
|
|
8
|
+
*/
|
|
9
|
+
export interface PathSegment {
|
|
10
|
+
/**
|
|
11
|
+
* Get the start point of this path segment.
|
|
12
|
+
*
|
|
13
|
+
* @method getStartPoint
|
|
14
|
+
* @memberof PathSegment
|
|
15
|
+
* @return {Vertex} The start point of this path segment.
|
|
16
|
+
*/
|
|
17
|
+
getStartPoint(): Vertex;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get the end point of this path segment.
|
|
21
|
+
*
|
|
22
|
+
* @method getEndPoint
|
|
23
|
+
* @memberof PathSegment
|
|
24
|
+
* @return {Vertex} The end point of this path segment.
|
|
25
|
+
*/
|
|
26
|
+
getEndPoint(): Vertex;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get the tangent's end point at the start point of this segment.
|
|
30
|
+
*
|
|
31
|
+
* @method getStartTangent
|
|
32
|
+
* @memberof PathSegment
|
|
33
|
+
* @return {Vertex} The end point of the starting point's tangent.
|
|
34
|
+
*/
|
|
35
|
+
getStartTangent(): Vertex;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get the tangent's end point at the end point of this segment.
|
|
39
|
+
*
|
|
40
|
+
* @method getEndTangent
|
|
41
|
+
* @memberof PathSegment
|
|
42
|
+
* @return {Vertex} The end point of the ending point's tangent.
|
|
43
|
+
*/
|
|
44
|
+
getEndTangent(): Vertex;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Create a deep clone of this path segment.
|
|
48
|
+
*
|
|
49
|
+
* @method clone
|
|
50
|
+
* @memberof PathSegment
|
|
51
|
+
* @return {PathSegment} A deep clone/copy of this path segment.
|
|
52
|
+
*/
|
|
53
|
+
clone: () => PathSegment;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Revserse this path segment (in-place) and return this same instance (useful for chaining).
|
|
57
|
+
* The new path segment has start and end point swapped.
|
|
58
|
+
*
|
|
59
|
+
* @method reverse
|
|
60
|
+
* @memberof PathSegment
|
|
61
|
+
* @return {PathSegment} This path segment instance (for chaining).
|
|
62
|
+
*/
|
|
63
|
+
reverse: () => PathSegment;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* A common interface for general path representations.
|
|
68
|
+
*/
|
|
69
|
+
export interface Path extends PathSegment {
|
|
70
|
+
/**
|
|
71
|
+
* Get the number of segments in this path.
|
|
72
|
+
*
|
|
73
|
+
* @method getSegmentCount
|
|
74
|
+
* @memberof Path
|
|
75
|
+
* @return {number} The number (integer) of path segments.
|
|
76
|
+
*/
|
|
77
|
+
getSegmentCount: () => number;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get the path segment at the given index.
|
|
81
|
+
*
|
|
82
|
+
* @method getSegmentAt
|
|
83
|
+
* @memberof Path
|
|
84
|
+
* @return {PathSegment} The paths segment at the given index.
|
|
85
|
+
*/
|
|
86
|
+
getSegmentAt: (index: number) => PathSegment;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Create a deep clone of this path.
|
|
90
|
+
*
|
|
91
|
+
* @method clone
|
|
92
|
+
* @memberof Path
|
|
93
|
+
* @return {Path} A deep clone/copy of this path.
|
|
94
|
+
*/
|
|
95
|
+
clone: () => Path;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Reverse this path (swap start and end and thus – the direction) in-place.
|
|
99
|
+
*
|
|
100
|
+
* @method revert
|
|
101
|
+
* @memberof Path
|
|
102
|
+
* @return {PathSegment} This path instance.
|
|
103
|
+
*/
|
|
104
|
+
reverse: () => Path;
|
|
105
|
+
}
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* @modified 2021-06-21 Added `IBounds.getCenter()`.
|
|
16
16
|
* @modified 2021-11-16 Added `text` options to the `DrawConfig`.
|
|
17
17
|
* @modified 2022-08-01 Added `title` param to the `PBParams` interface.
|
|
18
|
+
* @modified 2022-10-25 Added `origin` param to the `DrawConfig` interface.
|
|
18
19
|
**/
|
|
19
20
|
|
|
20
21
|
import { Vertex } from "../Vertex";
|
|
@@ -199,6 +200,7 @@ export interface DrawConfig {
|
|
|
199
200
|
fill?: boolean;
|
|
200
201
|
anchor?: boolean;
|
|
201
202
|
};
|
|
203
|
+
origin: { color: string };
|
|
202
204
|
}
|
|
203
205
|
|
|
204
206
|
/** This is a fix for the problem, that the constructor's "name" attribute is not
|