plotboilerplate 1.18.0 → 1.20.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.
Files changed (155) hide show
  1. package/README.md +1 -1
  2. package/dist/index.esm.js +244 -63
  3. package/dist/index.esm.js.map +1 -1
  4. package/dist/index.esm.min.js +1 -1
  5. package/dist/index.esm.min.js.map +1 -1
  6. package/dist/plotboilerplate.browser.min.js +1 -1
  7. package/dist/plotboilerplate.browser.min.js.map +1 -1
  8. package/dist/plotboilerplate.js +243 -74
  9. package/dist/plotboilerplate.min.js +1 -1
  10. package/package.json +1 -1
  11. package/src/cjs/Bounds.d.ts +14 -5
  12. package/src/cjs/Bounds.js +18 -8
  13. package/src/cjs/Bounds.js.map +1 -1
  14. package/src/cjs/CubicBezierCurve.d.ts +20 -3
  15. package/src/cjs/CubicBezierCurve.js +25 -2
  16. package/src/cjs/CubicBezierCurve.js.map +1 -1
  17. package/src/cjs/Line.d.ts +46 -4
  18. package/src/cjs/Line.js +60 -3
  19. package/src/cjs/Line.js.map +1 -1
  20. package/src/cjs/PlotBoilerplate.d.ts +5 -2
  21. package/src/cjs/PlotBoilerplate.js +52 -30
  22. package/src/cjs/PlotBoilerplate.js.map +1 -1
  23. package/src/cjs/Polygon.js +1 -1
  24. package/src/cjs/Polygon.js.map +1 -1
  25. package/src/cjs/VEllipseSector.d.ts +4 -3
  26. package/src/cjs/VEllipseSector.js +15 -8
  27. package/src/cjs/VEllipseSector.js.map +1 -1
  28. package/src/cjs/Vector.d.ts +14 -3
  29. package/src/cjs/Vector.js +21 -2
  30. package/src/cjs/Vector.js.map +1 -1
  31. package/src/cjs/Vertex.d.ts +33 -1
  32. package/src/cjs/Vertex.js +43 -1
  33. package/src/cjs/Vertex.js.map +1 -1
  34. package/src/cjs/drawutilssvg.d.ts +2 -1
  35. package/src/cjs/drawutilssvg.js +7 -19
  36. package/src/cjs/drawutilssvg.js.map +1 -1
  37. package/src/cjs/entry.js +1 -0
  38. package/src/cjs/interfaces/additionals.d.ts +95 -0
  39. package/src/cjs/interfaces/additionals.js +3 -0
  40. package/src/cjs/interfaces/additionals.js.map +1 -0
  41. package/src/cjs/interfaces/core.d.ts +7 -0
  42. package/src/cjs/interfaces/core.js +2 -0
  43. package/src/cjs/interfaces/core.js.map +1 -1
  44. package/src/cjs/interfaces/index.d.ts +1 -0
  45. package/src/cjs/interfaces/index.js +1 -0
  46. package/src/cjs/interfaces/index.js.map +1 -1
  47. package/src/cjs/utils/algorithms/arrayShuffle.d.ts +8 -0
  48. package/src/cjs/utils/algorithms/arrayShuffle.js +15 -0
  49. package/src/cjs/utils/algorithms/arrayShuffle.js.map +1 -0
  50. package/src/cjs/utils/algorithms/detectPaths.d.ts +21 -0
  51. package/src/cjs/utils/algorithms/detectPaths.js +169 -0
  52. package/src/cjs/utils/algorithms/detectPaths.js.map +1 -0
  53. package/src/cjs/utils/creategui.js +7 -0
  54. package/src/cjs/utils/datastructures/Color.d.ts +1 -1
  55. package/src/cjs/utils/datastructures/Color.js +4 -2
  56. package/src/cjs/utils/datastructures/Color.js.map +1 -1
  57. package/src/cjs/utils/datastructures/GenericPath.d.ts +75 -0
  58. package/src/cjs/utils/datastructures/GenericPath.js +105 -0
  59. package/src/cjs/utils/datastructures/GenericPath.js.map +1 -0
  60. package/src/cjs/utils/datastructures/GirihTile.d.ts +1 -1
  61. package/src/cjs/utils/io/FileDrop.d.ts +11 -1
  62. package/src/cjs/utils/io/FileDrop.js +41 -10
  63. package/src/cjs/utils/io/FileDrop.js.map +1 -1
  64. package/src/cjs/utils/parsers/svg/parseSVGPathData.d.ts +26 -0
  65. package/src/cjs/utils/parsers/svg/parseSVGPathData.js +463 -0
  66. package/src/cjs/utils/parsers/svg/parseSVGPathData.js.map +1 -0
  67. package/src/cjs/utils/parsers/svg/splitSVGPathData.d.ts +20 -0
  68. package/src/cjs/utils/parsers/svg/splitSVGPathData.js +49 -0
  69. package/src/cjs/utils/parsers/svg/splitSVGPathData.js.map +1 -0
  70. package/src/cjs/utils/parsers/svg/types.d.ts +43 -0
  71. package/src/cjs/utils/parsers/svg/types.js +16 -0
  72. package/src/cjs/utils/parsers/svg/types.js.map +1 -0
  73. package/src/esm/Bounds.d.ts +14 -5
  74. package/src/esm/Bounds.js +18 -8
  75. package/src/esm/Bounds.js.map +1 -1
  76. package/src/esm/CubicBezierCurve.d.ts +20 -3
  77. package/src/esm/CubicBezierCurve.js +25 -2
  78. package/src/esm/CubicBezierCurve.js.map +1 -1
  79. package/src/esm/Line.d.ts +46 -4
  80. package/src/esm/Line.js +60 -3
  81. package/src/esm/Line.js.map +1 -1
  82. package/src/esm/PlotBoilerplate.d.ts +5 -2
  83. package/src/esm/PlotBoilerplate.js +52 -30
  84. package/src/esm/PlotBoilerplate.js.map +1 -1
  85. package/src/esm/Polygon.js +1 -1
  86. package/src/esm/Polygon.js.map +1 -1
  87. package/src/esm/VEllipseSector.d.ts +4 -3
  88. package/src/esm/VEllipseSector.js +15 -8
  89. package/src/esm/VEllipseSector.js.map +1 -1
  90. package/src/esm/Vector.d.ts +13 -2
  91. package/src/esm/Vector.js +23 -4
  92. package/src/esm/Vector.js.map +1 -1
  93. package/src/esm/Vertex.d.ts +33 -1
  94. package/src/esm/Vertex.js +43 -1
  95. package/src/esm/Vertex.js.map +1 -1
  96. package/src/esm/drawutilssvg.d.ts +2 -1
  97. package/src/esm/drawutilssvg.js +7 -19
  98. package/src/esm/drawutilssvg.js.map +1 -1
  99. package/src/esm/entry.js +1 -0
  100. package/src/esm/interfaces/additionals.d.ts +95 -0
  101. package/src/esm/interfaces/additionals.js +2 -0
  102. package/src/esm/interfaces/additionals.js.map +1 -0
  103. package/src/esm/interfaces/core.d.ts +7 -0
  104. package/src/esm/interfaces/core.js +2 -0
  105. package/src/esm/interfaces/core.js.map +1 -1
  106. package/src/esm/interfaces/index.d.ts +1 -0
  107. package/src/esm/interfaces/index.js +1 -0
  108. package/src/esm/interfaces/index.js.map +1 -1
  109. package/src/esm/utils/algorithms/arrayShuffle.d.ts +8 -0
  110. package/src/esm/utils/algorithms/arrayShuffle.js +11 -0
  111. package/src/esm/utils/algorithms/arrayShuffle.js.map +1 -0
  112. package/src/esm/utils/algorithms/detectPaths.d.ts +21 -0
  113. package/src/esm/utils/algorithms/detectPaths.js +165 -0
  114. package/src/esm/utils/algorithms/detectPaths.js.map +1 -0
  115. package/src/esm/utils/datastructures/Color.d.ts +1 -1
  116. package/src/esm/utils/datastructures/Color.js +4 -2
  117. package/src/esm/utils/datastructures/Color.js.map +1 -1
  118. package/src/esm/utils/datastructures/GenericPath.d.ts +75 -0
  119. package/src/esm/utils/datastructures/GenericPath.js +100 -0
  120. package/src/esm/utils/datastructures/GenericPath.js.map +1 -0
  121. package/src/esm/utils/datastructures/GirihTile.d.ts +1 -1
  122. package/src/esm/utils/io/FileDrop.d.ts +11 -1
  123. package/src/esm/utils/io/FileDrop.js +41 -10
  124. package/src/esm/utils/io/FileDrop.js.map +1 -1
  125. package/src/esm/utils/parsers/svg/parseSVGPathData.d.ts +26 -0
  126. package/src/esm/utils/parsers/svg/parseSVGPathData.js +459 -0
  127. package/src/esm/utils/parsers/svg/parseSVGPathData.js.map +1 -0
  128. package/src/esm/utils/parsers/svg/splitSVGPathData.d.ts +20 -0
  129. package/src/esm/utils/parsers/svg/splitSVGPathData.js +45 -0
  130. package/src/esm/utils/parsers/svg/splitSVGPathData.js.map +1 -0
  131. package/src/esm/utils/parsers/svg/types.d.ts +43 -0
  132. package/src/esm/utils/parsers/svg/types.js +15 -0
  133. package/src/esm/utils/parsers/svg/types.js.map +1 -0
  134. package/src/ts/Bounds.ts +19 -8
  135. package/src/ts/CubicBezierCurve.ts +29 -4
  136. package/src/ts/Line.ts +70 -6
  137. package/src/ts/PlotBoilerplate.ts +57 -35
  138. package/src/ts/Polygon.ts +1 -1
  139. package/src/ts/VEllipseSector.ts +22 -15
  140. package/src/ts/Vector.ts +24 -4
  141. package/src/ts/Vertex.ts +46 -1
  142. package/src/ts/drawutilssvg.ts +8 -19
  143. package/src/ts/interfaces/additionals.ts +105 -0
  144. package/src/ts/interfaces/core.ts +5 -0
  145. package/src/ts/interfaces/index.ts +1 -0
  146. package/src/ts/utils/algorithms/arrayShuffle.ts +11 -0
  147. package/src/ts/utils/algorithms/detectPaths.ts +195 -0
  148. package/src/ts/utils/datastructures/Color.ts +8 -4
  149. package/src/ts/utils/datastructures/GenericPath.ts +113 -0
  150. package/src/ts/utils/datastructures/GirihTile.ts +1 -1
  151. package/src/ts/utils/io/FileDrop.ts +51 -10
  152. package/src/ts/utils/parsers/svg/parseSVGPathData.ts +572 -0
  153. package/src/ts/utils/parsers/svg/splitSVGPathData.ts +50 -0
  154. package/src/ts/utils/parsers/svg/types.ts +70 -0
  155. package/changelog.md +0 -731
package/src/ts/Bounds.ts CHANGED
@@ -6,7 +6,9 @@
6
6
  * @modified 2021-02-02 Added the `toPolygon` method.
7
7
  * @modified 2021-06-21 (mid-summer) Added `getCenter` method.
8
8
  * @modified 2022-02-01 Added the `toString` function.
9
- * @version 1.4.0
9
+ * @modified 2022-10-09 Added the `fromDimension` function.
10
+ * @modified 2022-11-28 Added the `clone` method.
11
+ * @version 1.6.0
10
12
  **/
11
13
 
12
14
  import { Polygon } from "./Polygon";
@@ -113,17 +115,14 @@ export class Bounds implements IBounds, XYDimension {
113
115
  /**
114
116
  * Clone this bounds object (create a deep clone).
115
117
  *
116
- * Note: the returned format might change in the future, so please do not
117
- * rely on the returned string format.
118
- *
119
118
  * @method clone
120
119
  * @instance
121
120
  * @memberof Bounds
122
- * @returns {string} Creates a deep clone of this bounds object. The returned object's `min` and `max` instances are `Vertex` instances.
121
+ * @returns {Bounds} Creates a deep clone of this bounds object.
123
122
  */
124
- // clone() {
125
- // return new Bounds(new Vertex(this.min.x, this.min.y), new Vertex(this.max.x, this.max.y));
126
- // }
123
+ clone() {
124
+ return new Bounds({ x: this.min.x, y: this.min.y }, { x: this.max.x, y: this.max.y });
125
+ }
127
126
 
128
127
  /**
129
128
  * Compute the minimal bounding box for a given set of vertices.
@@ -154,4 +153,16 @@ export class Bounds implements IBounds, XYDimension {
154
153
  }
155
154
  return new Bounds(new Vertex(xMin, yMin), new Vertex(xMax, yMax));
156
155
  }
156
+
157
+ /**
158
+ * Create a new `Bounds` instance just from `width` and `height`, located at (0,0) or the optionally given origin.
159
+ *
160
+ * @param {number} width - The width of the bounds
161
+ * @param {number} height - The height of the bounds
162
+ * @param {XYCoords={x:0,y:0}} origin - [optional] A origin to locate the new Bounds object at.
163
+ * @returns {Bounds} A new `Bounds` instance width given width and height, located at (0,0) or the given origin..
164
+ */
165
+ static fromDimension(width: number, height: number, origin?: XYCoords): Bounds {
166
+ return new Bounds(origin ?? { x: 0, y: 0 }, { x: (origin ? origin.x : 0) + width, y: (origin ? origin.y : 0) + height });
167
+ }
157
168
  } // END class bounds
@@ -20,7 +20,8 @@
20
20
  * @modified 2021-01-20 Added UID.
21
21
  * @modified 2022-02-02 Added the `destroy` method.
22
22
  * @modified 2022-02-02 Cleared the `toSVGPathData` function (deprecated). Use `drawutilssvg` instead.
23
- * @version 2.6.0
23
+ * @modified 2022-10-17 The `CubicBezierCurve` class now implements the new `PathSegment` interface.
24
+ * @version 2.7.1
24
25
  *
25
26
  * @file CubicBezierCurve
26
27
  * @public
@@ -30,7 +31,7 @@ import { Bounds } from "./Bounds";
30
31
  import { UIDGenerator } from "./UIDGenerator";
31
32
  import { Vertex } from "./Vertex";
32
33
  import { Vector } from "./Vector";
33
- import { XYCoords, UID } from "./interfaces";
34
+ import { XYCoords, UID, PathSegment } from "./interfaces";
34
35
 
35
36
  /**
36
37
  * @classdesc A refactored cubic bezier curve class.
@@ -42,7 +43,7 @@ import { XYCoords, UID } from "./interfaces";
42
43
  * @requires UID
43
44
  * @requires UIDGenerator
44
45
  */
45
- export class CubicBezierCurve {
46
+ export class CubicBezierCurve implements PathSegment {
46
47
  /** @constant {number} */
47
48
  static readonly START_POINT: number = 0;
48
49
  /** @constant {number} */
@@ -157,7 +158,7 @@ export class CubicBezierCurve {
157
158
  // An array of floats
158
159
  this.segmentLengths = [];
159
160
  // float
160
- this.arcLength = null;
161
+ // this.arcLength = null;
161
162
 
162
163
  this.updateArcLengths();
163
164
  }
@@ -627,6 +628,30 @@ export class CubicBezierCurve {
627
628
  );
628
629
  }
629
630
 
631
+ //---BEGIN PathSegment-------------------------
632
+ /**
633
+ * Get the tangent's end point at the start point of this segment.
634
+ *
635
+ * @method getStartTangent
636
+ * @memberof PathSegment
637
+ * @return {Vertex} The end point of the starting point's tangent.
638
+ */
639
+ getStartTangent(): Vertex {
640
+ return this.startControlPoint;
641
+ }
642
+
643
+ /**
644
+ * Get the tangent's end point at the end point of this segment.
645
+ *
646
+ * @method getEndTangent
647
+ * @memberof PathSegment
648
+ * @return {Vertex} The end point of the ending point's tangent.
649
+ */
650
+ getEndTangent(): Vertex {
651
+ return this.endControlPoint;
652
+ }
653
+ //---END PathSegment-------------------------
654
+
630
655
  /**
631
656
  * Check if this and the specified curve are equal.<br>
632
657
  * <br>
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
- * @version 2.2.0
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 | undefined {
64
+ intersection(line: Line): Vertex | null {
63
65
  const denominator: number = this.denominator(line);
64
- if (denominator == 0) return null;
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 undefined;
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
  }
@@ -75,7 +75,10 @@
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
- * @version 1.15.1
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
+ * @modified 2022-11-23 Added the `drawRaster` (default=true) option to the config/drawconfig.
81
+ * @version 1.17.0
79
82
  *
80
83
  * @file PlotBoilerplate
81
84
  * @fileoverview The main class.
@@ -270,7 +273,7 @@ export class PlotBoilerplate {
270
273
  * @memberof PlotBoilerplate
271
274
  * @instance
272
275
  */
273
- selectPolygon: Polygon;
276
+ selectPolygon: Polygon | null;
274
277
 
275
278
  /**
276
279
  * @member {Array<IDraggable>}
@@ -411,6 +414,7 @@ export class PlotBoilerplate {
411
414
  offsetX: f.num(config, "offsetX", 0.0),
412
415
  offsetY: f.num(config, "offsetY", 0.0),
413
416
  rasterGrid: f.bool(config, "rasterGrid", true),
417
+ drawRaster: f.bool(config, "drawRaster", true),
414
418
  rasterScaleX: f.num(config, "rasterScaleX", 1.0),
415
419
  rasterScaleY: f.num(config, "rasterScaleY", 1.0),
416
420
  rasterAdjustFactor: f.num(config, "rasterAdjustdFactror", 2.0),
@@ -465,6 +469,7 @@ export class PlotBoilerplate {
465
469
  drawHandleLines: f.bool(config, "drawHandleLines", true),
466
470
  drawHandlePoints: f.bool(config, "drawHandlePoints", true),
467
471
  drawGrid: f.bool(config, "drawGrid", true),
472
+ drawRaster: f.bool(config, "drawRaster", true),
468
473
  bezier: {
469
474
  color: "#00a822",
470
475
  lineWidth: 2,
@@ -532,6 +537,9 @@ export class PlotBoilerplate {
532
537
  lineWidth: 1,
533
538
  fill: true,
534
539
  anchor: true
540
+ },
541
+ origin: {
542
+ color: "#000000"
535
543
  }
536
544
  }; // END drawConfig
537
545
 
@@ -554,14 +562,16 @@ export class PlotBoilerplate {
554
562
  this.config.enableGL = false;
555
563
  }
556
564
  if (this.config.enableGL) {
557
- const ctx: WebGLRenderingContext = this.canvas.getContext("webgl"); // webgl-experimental?
565
+ // Override the case 'null' here. If GL is not supported, well then nothing works.
566
+ const ctx: WebGLRenderingContext = this.canvas.getContext("webgl") as WebGLRenderingContext; // webgl-experimental?
558
567
  this.draw = new drawutilsgl(ctx, false);
559
568
  // PROBLEM: same instance of fill and draw when using WebGL.
560
569
  // Shader program cannot be duplicated on the same context.
561
570
  this.fill = (this.draw as drawutilsgl).copyInstance(true);
562
571
  console.warn("Initialized with experimental mode enableGL=true. Note that this is not yet fully implemented.");
563
572
  } else {
564
- const ctx: CanvasRenderingContext2D = this.canvas.getContext("2d");
573
+ // Override the case 'null' here. If context creation is not supported, well then nothing works.
574
+ const ctx: CanvasRenderingContext2D = this.canvas.getContext("2d") as CanvasRenderingContext2D;
565
575
  this.draw = new drawutils(ctx, false);
566
576
  this.fill = new drawutils(ctx, true);
567
577
  }
@@ -599,8 +609,8 @@ export class PlotBoilerplate {
599
609
  if (config.title) {
600
610
  this.eventCatcher.setAttribute("title", config.title);
601
611
  }
602
- this.draw.scale.set(this.config.scaleX, this.config.scaleY);
603
- this.fill.scale.set(this.config.scaleX, this.config.scaleY);
612
+ this.draw.scale.set(this.config.scaleX ?? 1.0, this.config.scaleY);
613
+ this.fill.scale.set(this.config.scaleX ?? 1.0, this.config.scaleY);
604
614
  this.vertices = [];
605
615
  this.selectPolygon = null;
606
616
  this.draggedElements = [];
@@ -655,9 +665,13 @@ export class PlotBoilerplate {
655
665
 
656
666
  tosvgDraw.beginDrawCycle(0);
657
667
  tosvgFill.beginDrawCycle(0);
658
- if (pb.config.preClear) pb.config.preClear();
659
- tosvgDraw.clear(pb.config.backgroundColor);
660
- if (pb.config.preDraw) pb.config.preDraw(tosvgDraw, tosvgFill);
668
+ if (pb.config.preClear) {
669
+ pb.config.preClear();
670
+ }
671
+ tosvgDraw.clear(pb.config.backgroundColor || "white");
672
+ if (pb.config.preDraw) {
673
+ pb.config.preDraw(tosvgDraw, tosvgFill);
674
+ }
661
675
  pb.drawAll(0, tosvgDraw, tosvgFill);
662
676
  pb.drawVertices(0, tosvgDraw);
663
677
  if (pb.config.postDraw) pb.config.postDraw(tosvgDraw, tosvgFill);
@@ -669,7 +683,8 @@ export class PlotBoilerplate {
669
683
  var serializer = new XMLSerializer();
670
684
  var svgCode = serializer.serializeToString(svgNode);
671
685
 
672
- var blob = new Blob([svgCode], { type: "image/svg;charset=utf-8" });
686
+ // Add: '<?xml version="1.0" encoding="utf-8"?>\n' ?
687
+ var blob = new Blob(['<?xml version="1.0" encoding="utf-8"?>\n' + svgCode], { type: "image/svg;charset=utf-8" });
673
688
  // See documentation for FileSaver.js for usage.
674
689
  // https://github.com/eligrey/FileSaver.js
675
690
  if (typeof globalThis["saveAs"] !== "function")
@@ -751,9 +766,9 @@ export class PlotBoilerplate {
751
766
  **/
752
767
  private updateCSSscale() {
753
768
  if (this.config.cssUniformScale) {
754
- PlotBoilerplate.utils.setCSSscale(this.canvas, this.config.cssScaleX, this.config.cssScaleX);
769
+ PlotBoilerplate.utils.setCSSscale(this.canvas, this.config.cssScaleX ?? 1.0, this.config.cssScaleX ?? 1.0);
755
770
  } else {
756
- PlotBoilerplate.utils.setCSSscale(this.canvas, this.config.cssScaleX, this.config.cssScaleY);
771
+ PlotBoilerplate.utils.setCSSscale(this.canvas, this.config.cssScaleX ?? 1.0, this.config.cssScaleY ?? 1.0);
757
772
  }
758
773
  }
759
774
 
@@ -1009,9 +1024,9 @@ export class PlotBoilerplate {
1009
1024
  * @return The vertex near the given position or undefined if none was found there.
1010
1025
  **/
1011
1026
  getVertexNear(pixelPosition: XYCoords, pixelTolerance: number): Vertex | undefined {
1012
- var p: IDraggable | undefined = this.locatePointNear(
1027
+ const p: IDraggable | null = this.locatePointNear(
1013
1028
  this.transformMousePosition(pixelPosition.x, pixelPosition.y),
1014
- pixelTolerance / Math.min(this.config.cssScaleX, this.config.cssScaleY)
1029
+ pixelTolerance / Math.min(this.config.cssScaleX ?? 1.0, this.config.cssScaleY ?? 1.0)
1015
1030
  );
1016
1031
  if (p && p.typeName == "vertex") {
1017
1032
  return this.vertices[p.vindex];
@@ -1095,7 +1110,7 @@ export class PlotBoilerplate {
1095
1110
  drawOrigin(draw: DrawLib<any>) {
1096
1111
  // Add a crosshair to mark the origin
1097
1112
  draw.setCurrentId("origin");
1098
- draw.crosshair({ x: 0, y: 0 }, 10, "#000000");
1113
+ draw.crosshair({ x: 0, y: 0 }, 10, this.drawConfig.origin.color);
1099
1114
  }
1100
1115
 
1101
1116
  /**
@@ -1360,10 +1375,10 @@ export class PlotBoilerplate {
1360
1375
  } else {
1361
1376
  console.error("Cannot draw object. Unknown class.");
1362
1377
  }
1363
- draw.setCurrentClassName(null);
1364
- draw.setCurrentId(null);
1365
- fill.setCurrentClassName(null);
1366
- fill.setCurrentId(null);
1378
+ draw.setCurrentClassName(undefined);
1379
+ draw.setCurrentId(undefined);
1380
+ fill.setCurrentClassName(undefined);
1381
+ fill.setCurrentId(undefined);
1367
1382
  }
1368
1383
 
1369
1384
  /**
@@ -1448,8 +1463,12 @@ export class PlotBoilerplate {
1448
1463
  * @return {void}
1449
1464
  **/
1450
1465
  drawAll(renderTime: number, draw: DrawLib<any>, fill: DrawLib<any>) {
1451
- this.drawGrid(draw);
1452
- if (this.config.drawOrigin) this.drawOrigin(draw);
1466
+ if (this.config.drawRaster) {
1467
+ this.drawGrid(draw);
1468
+ }
1469
+ if (this.config.drawOrigin) {
1470
+ this.drawOrigin(draw);
1471
+ }
1453
1472
  this.drawDrawables(renderTime, draw, fill);
1454
1473
  this.drawVertices(renderTime, draw);
1455
1474
  this.drawSelectPolygon(draw);
@@ -1473,7 +1492,7 @@ export class PlotBoilerplate {
1473
1492
  **/
1474
1493
  clear() {
1475
1494
  // Note that elements might have an alpha channel. Clear the scene first.
1476
- this.draw.clear(this.config.backgroundColor);
1495
+ this.draw.clear(this.config.backgroundColor || "white");
1477
1496
  }
1478
1497
 
1479
1498
  /**
@@ -1505,7 +1524,10 @@ export class PlotBoilerplate {
1505
1524
  viewport(): Bounds {
1506
1525
  return new Bounds(
1507
1526
  this.transformMousePosition(0, 0),
1508
- this.transformMousePosition(this.canvasSize.width * this.config.cssScaleX, this.canvasSize.height * this.config.cssScaleY)
1527
+ this.transformMousePosition(
1528
+ this.canvasSize.width * (this.config.cssScaleX ?? 1.0),
1529
+ this.canvasSize.height * (this.config.cssScaleY ?? 1.0)
1530
+ )
1509
1531
  );
1510
1532
  }
1511
1533
 
@@ -1569,8 +1591,8 @@ export class PlotBoilerplate {
1569
1591
  resizeCanvas() {
1570
1592
  const _self: PlotBoilerplate = this;
1571
1593
  const _setSize = (w: number, h: number) => {
1572
- w *= _self.config.canvasWidthFactor;
1573
- h *= _self.config.canvasHeightFactor;
1594
+ w *= _self.config.canvasWidthFactor ?? 1.0;
1595
+ h *= _self.config.canvasHeightFactor ?? 1.0;
1574
1596
  _self.canvasSize.width = w;
1575
1597
  _self.canvasSize.height = h;
1576
1598
  if (_self.canvas instanceof HTMLCanvasElement) {
@@ -1597,8 +1619,8 @@ export class PlotBoilerplate {
1597
1619
  var width: number = globalThis.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
1598
1620
  var height: number = globalThis.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
1599
1621
  _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";
1622
+ _self.canvas.style.width = (_self.config.canvasWidthFactor ?? 1.0) * width + "px";
1623
+ _self.canvas.style.height = (_self.config.canvasWidthFactor ?? 1.0) * height + "px";
1602
1624
  _self.canvas.style.top = "0px";
1603
1625
  _self.canvas.style.left = "0px";
1604
1626
  _setSize(width, height);
@@ -1606,15 +1628,15 @@ export class PlotBoilerplate {
1606
1628
  // Set editor size
1607
1629
  _self.canvas.style.position = "absolute";
1608
1630
  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 = null;
1612
- _self.canvas.style.left = null;
1631
+ _self.canvas.style.width = (_self.config.canvasWidthFactor ?? 1.0) * space.width + "px";
1632
+ _self.canvas.style.height = (_self.config.canvasHeightFactor ?? 1.0) * space.height + "px";
1633
+ _self.canvas.style.top = "";
1634
+ _self.canvas.style.left = "";
1613
1635
  _setSize(space.width, space.height);
1614
1636
  } else {
1615
- _self.canvas.style.width = null;
1616
- _self.canvas.style.height = null;
1617
- _setSize(_self.config.defaultCanvasWidth, _self.config.defaultCanvasHeight);
1637
+ _self.canvas.style.width = "";
1638
+ _self.canvas.style.height = "";
1639
+ _setSize(_self.config.defaultCanvasWidth ?? 1024, _self.config.defaultCanvasHeight ?? 768);
1618
1640
  }
1619
1641
 
1620
1642
  if (_self.config.redrawOnResize) _self.redraw();
@@ -2269,7 +2291,7 @@ export class PlotBoilerplate {
2269
2291
  * @param {function} fallback - A default value if the key does not exist.
2270
2292
  * @return {function}
2271
2293
  **/
2272
- func: (obj: any, key: string, fallback: (...args: any[]) => any) => {
2294
+ func: (obj: any, key: string, fallback: ((...args: any[]) => any) | null) => {
2273
2295
  if (!obj.hasOwnProperty(key)) return fallback;
2274
2296
  if (typeof obj[key] !== "function") return fallback;
2275
2297
  return obj[key];
package/src/ts/Polygon.ts CHANGED
@@ -99,7 +99,7 @@ export class Polygon implements SVGSerializable {
99
99
  this.uid = UIDGenerator.next();
100
100
  if (typeof vertices == "undefined") vertices = [];
101
101
  this.vertices = vertices;
102
- this.isOpen = isOpen;
102
+ this.isOpen = isOpen || false;
103
103
  }
104
104
 
105
105
  /**
@@ -2,10 +2,11 @@
2
2
  * Implementation of elliptic sectors.
3
3
  * Note that sectors are constructed in clockwise direction.
4
4
  *
5
- * @author Ikaros Kappler
6
- * @date 2021-02-26
5
+ * @author Ikaros Kappler
6
+ * @date 2021-02-26
7
7
  * @modified 2022-02-02 Added the `destroy` method.
8
- * @version 1.1.0
8
+ * @modified 2022-11-01 Tweaked the `endpointToCenterParameters` function to handle negative values, too, without errors.
9
+ * @version 1.1.1
9
10
  */
10
11
 
11
12
  import { CubicBezierCurve } from "./CubicBezierCurve";
@@ -139,19 +140,23 @@ export class VEllipseSector {
139
140
  curves.push(curve);
140
141
  } else {
141
142
  // Find intersection
142
- let intersection: Vertex | undefined = startTangent.intersection(endTangent);
143
+ let intersection: Vertex | null = startTangent.intersection(endTangent);
143
144
  // What if intersection is undefined?
144
145
  // --> This *can* not happen if segmentCount > 2 and height and width of the ellipse are not zero.
145
146
 
146
- let startDiff: Vertex = startPoint.difference(intersection);
147
- let endDiff: Vertex = endPoint.difference(intersection);
148
- let curve: CubicBezierCurve = new CubicBezierCurve(
149
- startPoint.clone(),
150
- endPoint.clone(),
151
- startPoint.clone().add(startDiff.scale(threshold)),
152
- endPoint.clone().add(endDiff.scale(threshold))
153
- );
154
- curves.push(curve);
147
+ if (intersection) {
148
+ // It's VERY LIKELY hat this ALWAYS happens; it's just a typesave variant.
149
+ // Intersection cannot be null.
150
+ let startDiff: Vertex = startPoint.difference(intersection);
151
+ let endDiff: Vertex = endPoint.difference(intersection);
152
+ let curve: CubicBezierCurve = new CubicBezierCurve(
153
+ startPoint.clone(),
154
+ endPoint.clone(),
155
+ startPoint.clone().add(startDiff.scale(threshold)),
156
+ endPoint.clone().add(endDiff.scale(threshold))
157
+ );
158
+ curves.push(curve);
159
+ }
155
160
  }
156
161
  startPoint = endPoint;
157
162
  curAngle = nextAngle;
@@ -268,7 +273,7 @@ export class VEllipseSector {
268
273
 
269
274
  // Bring all angles into the correct order
270
275
  // Idea: use splice or slice here?
271
- var angles = [];
276
+ var angles: Array<number> = [];
272
277
  for (var i = 0; i < ellipseAngles.length; i++) {
273
278
  angles.push(ellipseAngles[(startIndex + i) % ellipseAngles.length]);
274
279
  }
@@ -355,7 +360,8 @@ export class VEllipseSector {
355
360
 
356
361
  // Step 2 + 3: compute center
357
362
  const sign: number = fa === fs ? -1 : 1;
358
- const M: number = sqrt((prx * pry - prx * py - pry * px) / (prx * py + pry * px)) * sign;
363
+ // const M: number = sqrt((prx * pry - prx * py - pry * px) / (prx * py + pry * px)) * sign;
364
+ const M: number = sqrt(Math.abs((prx * pry - prx * py - pry * px) / (prx * py + pry * px))) * sign;
359
365
 
360
366
  const _cx: number = (M * (rx * y)) / ry;
361
367
  const _cy: number = (M * (-ry * x)) / rx;
@@ -367,6 +373,7 @@ export class VEllipseSector {
367
373
  const center: Vertex = new Vertex(cx, cy);
368
374
  const axis: Vertex = center.clone().addXY(rx, ry);
369
375
  const ellipse: VEllipse = new VEllipse(center, axis, 0);
376
+ // console.log("VELLIPSE::::::", ellipse);
370
377
  ellipse.rotate(phi);
371
378
 
372
379
  const startAngle: number = new Line(ellipse.center, new Vertex(x1, y1)).angle();
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
- * @version 1.4.0
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 witht the same magnitude but oppose direction.
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
- var angle = Math.atan2((zB.y - zA.y) * scaleY, (zB.x - zA.x) * scaleX);
147
- var vertices = [];
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/Vertex.ts CHANGED
@@ -28,7 +28,8 @@
28
28
  * @modified 2022-01-31 Added `Vertex.utils.arrayToJSON`.
29
29
  * @modified 2022-02-02 Added the `destroy` method.
30
30
  * @modified 2022-02-02 Cleared the `Vertex.toSVGString` function (deprecated). Use `drawutilssvg` instead.
31
- * @version 2.7.0
31
+ * @modified 2022-11-28 Added the `subXY`, `subX` and `subY` methods to the `Vertex` class.
32
+ * @version 2.8.0
32
33
  *
33
34
  * @file Vertex
34
35
  * @public
@@ -342,6 +343,50 @@ export class Vertex implements XYCoords, SVGSerializable {
342
343
  return this;
343
344
  }
344
345
 
346
+ /**
347
+ * Substract the passed amounts from the x- and y- components of this vertex.
348
+ *
349
+ * @method subXY
350
+ * @param {number} x - The amount to substract from x.
351
+ * @param {number} y - The amount to substract from y.
352
+ * @return {Vertex} this
353
+ * @instance
354
+ * @memberof Vertex
355
+ **/
356
+ subXY(amountX: number, amountY: number): Vertex {
357
+ this.x -= amountX;
358
+ this.y -= amountY;
359
+ return this;
360
+ }
361
+
362
+ /**
363
+ * Substract the passed amounts from the x-component of this vertex.
364
+ *
365
+ * @method addX
366
+ * @param {number} x - The amount to substract from x.
367
+ * @return {Vertex} this
368
+ * @instance
369
+ * @memberof Vertex
370
+ **/
371
+ subX(amountX: number): Vertex {
372
+ this.x -= amountX;
373
+ return this;
374
+ }
375
+
376
+ /**
377
+ * Substract the passed amounts from the y-component of this vertex.
378
+ *
379
+ * @method subY
380
+ * @param {number} y - The amount to substract from y.
381
+ * @return {Vertex} this
382
+ * @instance
383
+ * @memberof Vertex
384
+ **/
385
+ subY(amountY: number): Vertex {
386
+ this.y -= amountY;
387
+ return this;
388
+ }
389
+
345
390
  /**
346
391
  * Check if this vertex equals the passed one.
347
392
  * <br>