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.
Files changed (117) hide show
  1. package/README.md +63 -6
  2. package/dist/index.esm.js +278 -60
  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 +276 -58
  9. package/dist/plotboilerplate.min.js +1 -1
  10. package/package.json +1 -1
  11. package/src/cjs/Bounds.d.ts +11 -1
  12. package/src/cjs/Bounds.js +13 -1
  13. package/src/cjs/Bounds.js.map +1 -1
  14. package/src/cjs/Circle.d.ts +36 -2
  15. package/src/cjs/Circle.js +81 -1
  16. package/src/cjs/Circle.js.map +1 -1
  17. package/src/cjs/CubicBezierCurve.d.ts +20 -3
  18. package/src/cjs/CubicBezierCurve.js +25 -2
  19. package/src/cjs/CubicBezierCurve.js.map +1 -1
  20. package/src/cjs/Line.d.ts +46 -4
  21. package/src/cjs/Line.js +60 -3
  22. package/src/cjs/Line.js.map +1 -1
  23. package/src/cjs/MouseHandler.d.ts +3 -2
  24. package/src/cjs/MouseHandler.js +16 -14
  25. package/src/cjs/MouseHandler.js.map +1 -1
  26. package/src/cjs/PlotBoilerplate.d.ts +4 -2
  27. package/src/cjs/PlotBoilerplate.js +44 -28
  28. package/src/cjs/PlotBoilerplate.js.map +1 -1
  29. package/src/cjs/Polygon.js +1 -1
  30. package/src/cjs/Polygon.js.map +1 -1
  31. package/src/cjs/Vector.d.ts +14 -3
  32. package/src/cjs/Vector.js +21 -2
  33. package/src/cjs/Vector.js.map +1 -1
  34. package/src/cjs/draw.d.ts +4 -1
  35. package/src/cjs/draw.js +15 -6
  36. package/src/cjs/draw.js.map +1 -1
  37. package/src/cjs/interfaces/additionals.d.ts +95 -0
  38. package/src/cjs/interfaces/additionals.js +3 -0
  39. package/src/cjs/interfaces/additionals.js.map +1 -0
  40. package/src/cjs/interfaces/core.d.ts +4 -0
  41. package/src/cjs/interfaces/core.js +1 -0
  42. package/src/cjs/interfaces/core.js.map +1 -1
  43. package/src/cjs/interfaces/index.d.ts +1 -0
  44. package/src/cjs/interfaces/index.js +1 -0
  45. package/src/cjs/interfaces/index.js.map +1 -1
  46. package/src/cjs/utils/algorithms/arrayShuffle.d.ts +8 -0
  47. package/src/cjs/utils/algorithms/arrayShuffle.js +15 -0
  48. package/src/cjs/utils/algorithms/arrayShuffle.js.map +1 -0
  49. package/src/cjs/utils/algorithms/detectPaths.d.ts +20 -0
  50. package/src/cjs/utils/algorithms/detectPaths.js +169 -0
  51. package/src/cjs/utils/algorithms/detectPaths.js.map +1 -0
  52. package/src/cjs/utils/datastructures/GenericPath.d.ts +75 -0
  53. package/src/cjs/utils/datastructures/GenericPath.js +105 -0
  54. package/src/cjs/utils/datastructures/GenericPath.js.map +1 -0
  55. package/src/cjs/utils/datastructures/GirihTile.d.ts +1 -1
  56. package/src/esm/Bounds.d.ts +11 -1
  57. package/src/esm/Bounds.js +13 -1
  58. package/src/esm/Bounds.js.map +1 -1
  59. package/src/esm/Circle.d.ts +36 -2
  60. package/src/esm/Circle.js +81 -1
  61. package/src/esm/Circle.js.map +1 -1
  62. package/src/esm/CubicBezierCurve.d.ts +20 -3
  63. package/src/esm/CubicBezierCurve.js +25 -2
  64. package/src/esm/CubicBezierCurve.js.map +1 -1
  65. package/src/esm/Line.d.ts +46 -4
  66. package/src/esm/Line.js +60 -3
  67. package/src/esm/Line.js.map +1 -1
  68. package/src/esm/MouseHandler.d.ts +3 -2
  69. package/src/esm/MouseHandler.js +16 -14
  70. package/src/esm/MouseHandler.js.map +1 -1
  71. package/src/esm/PlotBoilerplate.d.ts +4 -2
  72. package/src/esm/PlotBoilerplate.js +44 -28
  73. package/src/esm/PlotBoilerplate.js.map +1 -1
  74. package/src/esm/Polygon.js +1 -1
  75. package/src/esm/Polygon.js.map +1 -1
  76. package/src/esm/Vector.d.ts +13 -2
  77. package/src/esm/Vector.js +23 -4
  78. package/src/esm/Vector.js.map +1 -1
  79. package/src/esm/draw.d.ts +4 -1
  80. package/src/esm/draw.js +15 -6
  81. package/src/esm/draw.js.map +1 -1
  82. package/src/esm/interfaces/additionals.d.ts +95 -0
  83. package/src/esm/interfaces/additionals.js +2 -0
  84. package/src/esm/interfaces/additionals.js.map +1 -0
  85. package/src/esm/interfaces/core.d.ts +4 -0
  86. package/src/esm/interfaces/core.js +1 -0
  87. package/src/esm/interfaces/core.js.map +1 -1
  88. package/src/esm/interfaces/index.d.ts +1 -0
  89. package/src/esm/interfaces/index.js +1 -0
  90. package/src/esm/interfaces/index.js.map +1 -1
  91. package/src/esm/utils/algorithms/arrayShuffle.d.ts +8 -0
  92. package/src/esm/utils/algorithms/arrayShuffle.js +11 -0
  93. package/src/esm/utils/algorithms/arrayShuffle.js.map +1 -0
  94. package/src/esm/utils/algorithms/detectPaths.d.ts +20 -0
  95. package/src/esm/utils/algorithms/detectPaths.js +165 -0
  96. package/src/esm/utils/algorithms/detectPaths.js.map +1 -0
  97. package/src/esm/utils/datastructures/GenericPath.d.ts +75 -0
  98. package/src/esm/utils/datastructures/GenericPath.js +100 -0
  99. package/src/esm/utils/datastructures/GenericPath.js.map +1 -0
  100. package/src/esm/utils/datastructures/GirihTile.d.ts +1 -1
  101. package/src/ts/Bounds.ts +14 -1
  102. package/src/ts/Circle.ts +92 -2
  103. package/src/ts/CubicBezierCurve.ts +29 -4
  104. package/src/ts/Line.ts +70 -6
  105. package/src/ts/MouseHandler.ts +16 -15
  106. package/src/ts/PlotBoilerplate.ts +47 -32
  107. package/src/ts/Polygon.ts +1 -1
  108. package/src/ts/Vector.ts +24 -4
  109. package/src/ts/draw.ts +15 -6
  110. package/src/ts/interfaces/additionals.ts +105 -0
  111. package/src/ts/interfaces/core.ts +2 -0
  112. package/src/ts/interfaces/index.ts +1 -0
  113. package/src/ts/utils/algorithms/arrayShuffle.ts +11 -0
  114. package/src/ts/utils/algorithms/detectPaths.ts +195 -0
  115. package/src/ts/utils/datastructures/GenericPath.ts +113 -0
  116. package/src/ts/utils/datastructures/GirihTile.ts +1 -1
  117. package/changelog.md +0 -722
package/dist/index.esm.js CHANGED
@@ -982,7 +982,7 @@ class Polygon {
982
982
  if (typeof vertices == "undefined")
983
983
  vertices = [];
984
984
  this.vertices = vertices;
985
- this.isOpen = isOpen;
985
+ this.isOpen = isOpen || false;
986
986
  }
987
987
  /**
988
988
  * Add a vertex to the end of the `vertices` array.
@@ -1412,7 +1412,8 @@ Polygon.utils = {
1412
1412
  * @modified 2021-02-02 Added the `toPolygon` method.
1413
1413
  * @modified 2021-06-21 (mid-summer) Added `getCenter` method.
1414
1414
  * @modified 2022-02-01 Added the `toString` function.
1415
- * @version 1.4.0
1415
+ * @modified 2022-10-09 Added the `fromDimension` function.
1416
+ * @version 1.5.0
1416
1417
  **/
1417
1418
  /**
1418
1419
  * @classdesc A bounds class with min and max values. Implementing IBounds.
@@ -1514,6 +1515,17 @@ class Bounds {
1514
1515
  }
1515
1516
  return new Bounds(new Vertex(xMin, yMin), new Vertex(xMax, yMax));
1516
1517
  }
1518
+ /**
1519
+ * Create a new `Bounds` instance just from `width` and `height`, located at (0,0) or the optionally given origin.
1520
+ *
1521
+ * @param {number} width - The width of the bounds
1522
+ * @param {number} height - The height of the bounds
1523
+ * @param {XYCoords={x:0,y:0}} origin - [optional] A origin to locate the new Bounds object at.
1524
+ * @returns {Bounds} A new `Bounds` instance width given width and height, located at (0,0) or the given origin..
1525
+ */
1526
+ static fromDimension(width, height, origin) {
1527
+ return new Bounds(origin !== null && origin !== void 0 ? origin : { x: 0, y: 0 }, { x: (origin ? origin.x : 0) + width, y: (origin ? origin.y : 0) + height });
1528
+ }
1517
1529
  } // END class bounds
1518
1530
 
1519
1531
  /**
@@ -1831,7 +1843,8 @@ VertTuple.vtutils = {
1831
1843
  * @modified 2021-01-20 Added UID.
1832
1844
  * @modified 2022-02-02 Added the `destroy` method.
1833
1845
  * @modified 2022-02-02 Cleared the `Vector.toSVGString` function (deprecated). Use `drawutilssvg` instead.
1834
- * @version 1.4.0
1846
+ * @modified 2022-10-25 Added the `getOrthogonal` method.
1847
+ * @version 1.5.0
1835
1848
  *
1836
1849
  * @file Vector
1837
1850
  * @public
@@ -1877,7 +1890,7 @@ class Vector extends VertTuple {
1877
1890
  return v;
1878
1891
  }
1879
1892
  /**
1880
- * The inverse of a vector is a vector witht the same magnitude but oppose direction.
1893
+ * The inverse of a vector is a vector with the same magnitude but oppose direction.
1881
1894
  *
1882
1895
  * Please not that the origin of this vector changes here: a->b becomes b->a.
1883
1896
  *
@@ -1923,6 +1936,24 @@ class Vector extends VertTuple {
1923
1936
  // if we cast these lines infinitely in both directions, they intersect here:
1924
1937
  return new Vertex(this.a.x + a * (this.b.x - this.a.x), this.a.y + a * (this.b.y - this.a.y));
1925
1938
  }
1939
+ /**
1940
+ * Get the orthogonal "vector" of this vector (rotated by 90° clockwise).
1941
+ *
1942
+ * @name getOrthogonal
1943
+ * @method getOrthogonal
1944
+ * @return {Vector} A new vector with the same length that stands on this vector's point a.
1945
+ * @instance
1946
+ * @memberof Vector
1947
+ **/
1948
+ getOrthogonal() {
1949
+ // Orthogonal of vector (0,0)->(x,y) is (0,0)->(-y,x)
1950
+ const linePoint = this.a.clone();
1951
+ const startPoint = this.b.clone().sub(this.a);
1952
+ const tmp = startPoint.x;
1953
+ startPoint.x = -startPoint.y;
1954
+ startPoint.y = tmp;
1955
+ return new Vector(linePoint, startPoint.add(this.a));
1956
+ }
1926
1957
  }
1927
1958
  Vector.utils = {
1928
1959
  /**
@@ -1951,8 +1982,8 @@ Vector.utils = {
1951
1982
  * @param {number} scaleY - the vertical scaling during draw.
1952
1983
  **/
1953
1984
  buildArrowHead: (zA, zB, headlen, scaleX, scaleY) => {
1954
- var angle = Math.atan2((zB.y - zA.y) * scaleY, (zB.x - zA.x) * scaleX);
1955
- var vertices = [];
1985
+ const angle = Math.atan2((zB.y - zA.y) * scaleY, (zB.x - zA.x) * scaleX);
1986
+ const vertices = [];
1956
1987
  vertices.push(new Vertex(zB.x * scaleX - headlen * Math.cos(angle), zB.y * scaleY - headlen * Math.sin(angle)));
1957
1988
  vertices.push(new Vertex(zB.x * scaleX - headlen * 1.35 * Math.cos(angle - Math.PI / 8), zB.y * scaleY - headlen * 1.35 * Math.sin(angle - Math.PI / 8)));
1958
1989
  vertices.push(new Vertex(zB.x * scaleX, zB.y * scaleY));
@@ -1983,7 +2014,8 @@ Vector.utils = {
1983
2014
  * @modified 2021-01-20 Added UID.
1984
2015
  * @modified 2022-02-02 Added the `destroy` method.
1985
2016
  * @modified 2022-02-02 Cleared the `toSVGPathData` function (deprecated). Use `drawutilssvg` instead.
1986
- * @version 2.6.0
2017
+ * @modified 2022-10-17 The `CubicBezierCurve` class now implements the new `PathSegment` interface.
2018
+ * @version 2.7.1
1987
2019
  *
1988
2020
  * @file CubicBezierCurve
1989
2021
  * @public
@@ -2029,7 +2061,7 @@ class CubicBezierCurve {
2029
2061
  // An array of floats
2030
2062
  this.segmentLengths = [];
2031
2063
  // float
2032
- this.arcLength = null;
2064
+ // this.arcLength = null;
2033
2065
  this.updateArcLengths();
2034
2066
  }
2035
2067
  /**
@@ -2461,6 +2493,28 @@ class CubicBezierCurve {
2461
2493
  clone() {
2462
2494
  return new CubicBezierCurve(this.getStartPoint().clone(), this.getEndPoint().clone(), this.getStartControlPoint().clone(), this.getEndControlPoint().clone());
2463
2495
  }
2496
+ //---BEGIN PathSegment-------------------------
2497
+ /**
2498
+ * Get the tangent's end point at the start point of this segment.
2499
+ *
2500
+ * @method getStartTangent
2501
+ * @memberof PathSegment
2502
+ * @return {Vertex} The end point of the starting point's tangent.
2503
+ */
2504
+ getStartTangent() {
2505
+ return this.startControlPoint;
2506
+ }
2507
+ /**
2508
+ * Get the tangent's end point at the end point of this segment.
2509
+ *
2510
+ * @method getEndTangent
2511
+ * @memberof PathSegment
2512
+ * @return {Vertex} The end point of the ending point's tangent.
2513
+ */
2514
+ getEndTangent() {
2515
+ return this.endControlPoint;
2516
+ }
2517
+ //---END PathSegment-------------------------
2464
2518
  /**
2465
2519
  * Check if this and the specified curve are equal.<br>
2466
2520
  * <br>
@@ -3874,7 +3928,9 @@ BezierPath.END_POINT = 3;
3874
3928
  * @modified 2020-03-23 Ported to Typescript from JS.
3875
3929
  * @modified 2020-12-04 The `intersection` function returns undefined if both lines are parallel.
3876
3930
  * @modified 2022-02-02 Added the `destroy` method.
3877
- * @version 2.2.0
3931
+ * @modified 2022-10-09 Changed the actual return value of the `intersection` function to null (was undefined before).
3932
+ * @modified 2022-10-17 Adding these methods from the `PathSegment` interface: getStartPoint, getEndPoint, revert.
3933
+ * @version 2.3.0
3878
3934
  *
3879
3935
  * @file Line
3880
3936
  * @public
@@ -3915,8 +3971,9 @@ class Line extends VertTuple {
3915
3971
  // !!! DO NOT MOVE TO VertTuple
3916
3972
  intersection(line) {
3917
3973
  const denominator = this.denominator(line);
3918
- if (denominator == 0)
3974
+ if (denominator == 0) {
3919
3975
  return null;
3976
+ }
3920
3977
  let a = this.a.y - line.a.y;
3921
3978
  let b = this.a.x - line.a.x;
3922
3979
  const numerator1 = (line.b.x - line.a.x) * a - (line.b.y - line.a.y) * b;
@@ -3927,11 +3984,65 @@ class Line extends VertTuple {
3927
3984
  const x = this.a.x + a * (this.b.x - this.a.x);
3928
3985
  const y = this.a.y + a * (this.b.y - this.a.y);
3929
3986
  if (isNaN(a) || isNaN(x) || isNaN(y)) {
3930
- return undefined;
3987
+ return null;
3931
3988
  }
3932
3989
  // if we cast these lines infinitely in both directions, they intersect here:
3933
3990
  return new Vertex(x, y);
3934
3991
  }
3992
+ //--- Implement PathSegment ---
3993
+ /**
3994
+ * Get the start point of this path segment.
3995
+ *
3996
+ * @method getStartPoint
3997
+ * @memberof PathSegment
3998
+ * @return {Vertex} The start point of this path segment.
3999
+ */
4000
+ getStartPoint() {
4001
+ return this.a;
4002
+ }
4003
+ /**
4004
+ * Get the end point of this path segment.
4005
+ *
4006
+ * @method getEndPoint
4007
+ * @memberof PathSegment
4008
+ * @return {Vertex} The end point of this path segment.
4009
+ */
4010
+ getEndPoint() {
4011
+ return this.b;
4012
+ }
4013
+ /**
4014
+ * Get the tangent's end point at the start point of this segment.
4015
+ *
4016
+ * @method getStartTangent
4017
+ * @memberof PathSegment
4018
+ * @return {Vertex} The end point of the starting point's tangent.
4019
+ */
4020
+ getStartTangent() {
4021
+ return this.b;
4022
+ }
4023
+ /**
4024
+ * Get the tangent's end point at the end point of this segment.
4025
+ *
4026
+ * @method getEndTangent
4027
+ * @memberof PathSegment
4028
+ * @return {Vertex} The end point of the ending point's tangent.
4029
+ */
4030
+ getEndTangent() {
4031
+ return this.a;
4032
+ }
4033
+ /**
4034
+ * Inverse this path segment (in-place) and return this same instance (useful for chaining).
4035
+ *
4036
+ * @method reverse
4037
+ * @memberof PathSegment
4038
+ * @return {PathSegment} This path segment instance (for chaining).
4039
+ */
4040
+ reverse() {
4041
+ var tmp = this.a;
4042
+ this.a = this.b;
4043
+ this.b = tmp;
4044
+ return this;
4045
+ }
3935
4046
  }
3936
4047
 
3937
4048
  /**
@@ -3945,7 +4056,10 @@ class Line extends VertTuple {
3945
4056
  * @modified 2021-01-20 Added UID.
3946
4057
  * @modified 2022-02-02 Added the `destroy` method.
3947
4058
  * @modified 2022-02-02 Cleared the `toSVGString` function (deprecated). Use `drawutilssvg` instead.
3948
- * @version 1.3.0
4059
+ * @modified 2022-08-15 Added the `containsPoint` function.
4060
+ * @modified 2022-08-23 Added the `lineIntersection` function.
4061
+ * @modified 2022-08-23 Added the `closestPoint` function.
4062
+ * @version 1.4.0
3949
4063
  **/
3950
4064
  /**
3951
4065
  * @classdesc A simple circle: center point and radius.
@@ -3976,6 +4090,18 @@ class Circle {
3976
4090
  this.center = center;
3977
4091
  this.radius = radius;
3978
4092
  }
4093
+ /**
4094
+ * Check if the given circle is fully contained inside this circle.
4095
+ *
4096
+ * @method containsPoint
4097
+ * @param {XYCoords} point - The point to check if it is contained in this circle.
4098
+ * @instance
4099
+ * @memberof Circle
4100
+ * @return {boolean} `true` if the given point is inside this circle.
4101
+ */
4102
+ containsPoint(point) {
4103
+ return this.center.distance(point) < this.radius;
4104
+ }
3979
4105
  /**
3980
4106
  * Check if the given circle is fully contained inside this circle.
3981
4107
  *
@@ -4087,6 +4213,71 @@ class Circle {
4087
4213
  var y4 = p2.y + (h * (p1.x - p0.x)) / d;
4088
4214
  return new Line(new Vertex(x3, y3), new Vertex(x4, y4));
4089
4215
  }
4216
+ /**
4217
+ * Calculate the intersection points (if exists) with the given infinite line (defined by two points).
4218
+ *
4219
+ * @method lineIntersection
4220
+ * @instance
4221
+ * @memberof Circle
4222
+ * @param {Vertex} a- The first of the two points defining the line.
4223
+ * @param {Vertex} b - The second of the two points defining the line.
4224
+ * @return {Line|null} The intersection points (as a line) or null if this circle does not intersect the line given.
4225
+ **/
4226
+ lineIntersection(a, b) {
4227
+ // Based on the math from
4228
+ // https://mathworld.wolfram.com/Circle-LineIntersection.html
4229
+ const interA = new Vertex();
4230
+ const interB = new Vertex();
4231
+ // First do a transformation, because the calculation is based on a cicle at (0,0)
4232
+ const transA = new Vertex(a).sub(this.center);
4233
+ const transB = new Vertex(b).sub(this.center);
4234
+ const diff = transA.difference(transB);
4235
+ // There is a special case if diff.y=0, where the intersection is not calcuatable.
4236
+ // Use an non-zero epsilon here to approximate this case.
4237
+ // TODO for the future: find a better solution
4238
+ if (Math.abs(diff.y) === 0) {
4239
+ diff.y = 0.000001;
4240
+ }
4241
+ const dist = transA.distance(transB);
4242
+ const det = transA.x * transB.y - transA.y * transB.x;
4243
+ const distSquared = dist * dist;
4244
+ const radiusSquared = this.radius * this.radius;
4245
+ // Check if circle and line have an intersection at all
4246
+ if (radiusSquared * distSquared - det * det < 0) {
4247
+ return null;
4248
+ }
4249
+ const belowSqrt = this.radius * this.radius * dist * dist - det * det;
4250
+ const sqrt = Math.sqrt(belowSqrt);
4251
+ interA.x = (det * diff.y + Math.sign(diff.y) * diff.x * sqrt) / distSquared;
4252
+ interB.x = (det * diff.y - Math.sign(diff.y) * diff.x * sqrt) / distSquared;
4253
+ interA.y = (-det * diff.x + Math.abs(diff.y) * sqrt) / distSquared;
4254
+ interB.y = (-det * diff.x - Math.abs(diff.y) * sqrt) / distSquared;
4255
+ return new Line(interA.add(this.center), interB.add(this.center));
4256
+ // return new Line(interA, interB);
4257
+ }
4258
+ /**
4259
+ * Calculate the closest point on the outline of this circle to the given point.
4260
+ *
4261
+ * @method closestPoint
4262
+ * @instance
4263
+ * @memberof Circle
4264
+ * @param {XYCoords} vert - The point to find the closest circle point for.
4265
+ * @return {Vertex} The closest point on this circle.
4266
+ **/
4267
+ closestPoint(vert) {
4268
+ const lineIntersection = this.lineIntersection(this.center, vert);
4269
+ if (!lineIntersection) {
4270
+ // Note: this case should not happen as a radial from the center always intersect this circle.
4271
+ return new Vertex();
4272
+ }
4273
+ // Return closed of both
4274
+ if (lineIntersection.a.distance(vert) < lineIntersection.b.distance(vert)) {
4275
+ return lineIntersection.a;
4276
+ }
4277
+ else {
4278
+ return lineIntersection.b;
4279
+ }
4280
+ }
4090
4281
  /**
4091
4282
  * This function should invalidate any installed listeners and invalidate this object.
4092
4283
  * After calling this function the object might not hold valid data any more and
@@ -5608,7 +5799,10 @@ drawutilssvg.HEAD_XML = [
5608
5799
  * @modified 2022-03-27 Added the `texturedPoly` function.
5609
5800
  * @modified 2022-06-01 Tweaked the `polyline` function; lineWidth now scales with scale.x.
5610
5801
  * @modified 2022-07-26 Adding `alpha` to the `image(...)` function.
5611
- * @version 1.12.2
5802
+ * @modified 2022-08-23 Fixed a type issue in the `polyline` function.
5803
+ * @modified 2022-08-23 Fixed a type issue in the `setConfiguration` function.
5804
+ * @modified 2022-08-23 Fixed a type issue in the `path` function.
5805
+ * @version 1.12.3
5612
5806
  **/
5613
5807
  // Todo: rename this class to Drawutils?
5614
5808
  /**
@@ -5662,7 +5856,7 @@ class drawutils {
5662
5856
  * @param {DrawLibConfiguration} configuration - The new configuration settings to use for the next render methods.
5663
5857
  */
5664
5858
  setConfiguration(configuration) {
5665
- this.ctx.globalCompositeOperation = configuration.blendMode;
5859
+ this.ctx.globalCompositeOperation = configuration.blendMode || "source-over";
5666
5860
  }
5667
5861
  /**
5668
5862
  * This method shouled be called each time the currently drawn `Drawable` changes.
@@ -6371,7 +6565,7 @@ class drawutils {
6371
6565
  }
6372
6566
  this.ctx.save();
6373
6567
  this.ctx.beginPath();
6374
- this.ctx.lineWidth = lineWidth * this.scale.x || 1.0;
6568
+ this.ctx.lineWidth = (lineWidth || 1.0) * this.scale.x;
6375
6569
  this.ctx.moveTo(this.offset.x + vertices[0].x * this.scale.x, this.offset.y + vertices[0].y * this.scale.y);
6376
6570
  for (var i = 0; i < vertices.length; i++) {
6377
6571
  this.ctx.lineTo(this.offset.x + vertices[i].x * this.scale.x, this.offset.y + vertices[i].y * this.scale.y);
@@ -6488,14 +6682,20 @@ class drawutils {
6488
6682
  path(pathData, color, lineWidth, options) {
6489
6683
  const d = options && options.inplace ? pathData : drawutilssvg.copyPathData(pathData);
6490
6684
  drawutilssvg.transformPathData(d, this.offset, this.scale);
6491
- this.ctx.strokeStyle = color;
6685
+ if (color) {
6686
+ this.ctx.strokeStyle = color;
6687
+ }
6492
6688
  this.ctx.lineWidth = lineWidth || 1;
6493
6689
  if (this.fillShapes) {
6494
- this.ctx.fillStyle = color;
6690
+ if (color) {
6691
+ this.ctx.fillStyle = color;
6692
+ }
6495
6693
  this.ctx.fill(new Path2D(d.join(" ")));
6496
6694
  }
6497
6695
  else {
6498
- this.ctx.strokeStyle = color;
6696
+ if (color) {
6697
+ this.ctx.strokeStyle = color;
6698
+ }
6499
6699
  this.ctx.stroke(new Path2D(d.join(" ")));
6500
6700
  }
6501
6701
  }
@@ -8280,7 +8480,8 @@ KeyHandler.KEY_CODES = {
8280
8480
  * @modified 2020-10-04 Added extended JSDoc comments.
8281
8481
  * @modified 2020-11-25 Added the `isTouchEvent` param.
8282
8482
  * @modified 2021-01-10 The mouse handler is now also working with SVGElements.
8283
- * @version 1.2.0
8483
+ * @modified 2022-08-16 Fixed a bug in the mouse button detection.
8484
+ * @version 1.2.1
8284
8485
  *
8285
8486
  * @file MouseHandler
8286
8487
  * @public
@@ -8370,8 +8571,8 @@ class MouseHandler {
8370
8571
  // +-------------------------------------------------
8371
8572
  this.name = name;
8372
8573
  this.element = element;
8373
- this.mouseDownPos = null;
8374
- this.mouseDragPos = null;
8574
+ this.mouseDownPos = undefined;
8575
+ this.mouseDragPos = undefined;
8375
8576
  // this.mousePos = null;
8376
8577
  this.mouseButton = -1;
8377
8578
  this.listeners = {};
@@ -8440,26 +8641,27 @@ class MouseHandler {
8440
8641
  * @memberof MouseHandler
8441
8642
  * @instance
8442
8643
  * @private
8443
- * @param {MouseEvent} e - The mouse event to get the relative position for.
8644
+ * @param {MouseEvent} event - The mouse event to get the relative position for.
8444
8645
  * @param {string} eventName - The name of the firing event.
8445
8646
  * @return {XMouseEvent}
8446
8647
  */
8447
- mkParams(e, eventName) {
8448
- const rel = this.relPos(e);
8449
- const xEvent = e;
8648
+ mkParams(event, eventName) {
8649
+ var _a, _b;
8650
+ const rel = this.relPos(event);
8651
+ const xEvent = event;
8450
8652
  xEvent.params = {
8451
8653
  element: this.element,
8452
8654
  name: eventName,
8453
8655
  isTouchEvent: false,
8454
8656
  pos: rel,
8455
- button: this.mouseButton,
8456
- leftButton: this.mouseButton == 0,
8457
- middleButton: this.mouseButton == 1,
8458
- rightButton: this.mouseButton == 2,
8459
- mouseDownPos: this.mouseDownPos,
8460
- draggedFrom: this.mouseDragPos,
8657
+ button: event.button,
8658
+ leftButton: event.button === 0,
8659
+ middleButton: event.button === 1,
8660
+ rightButton: event.button === 2,
8661
+ mouseDownPos: (_a = this.mouseDownPos) !== null && _a !== void 0 ? _a : { x: NaN, y: NaN },
8662
+ draggedFrom: (_b = this.mouseDragPos) !== null && _b !== void 0 ? _b : { x: NaN, y: NaN },
8461
8663
  wasDragged: this.mouseDownPos != null && (this.mouseDownPos.x != rel.x || this.mouseDownPos.y != rel.y),
8462
- dragAmount: this.mouseDownPos != null ? { x: rel.x - this.mouseDragPos.x, y: rel.y - this.mouseDragPos.y } : { x: 0, y: 0 }
8664
+ dragAmount: this.mouseDragPos != null ? { x: rel.x - this.mouseDragPos.x, y: rel.y - this.mouseDragPos.y } : { x: 0, y: 0 }
8463
8665
  };
8464
8666
  return xEvent;
8465
8667
  }
@@ -9893,7 +10095,9 @@ VEllipseSector.ellipseSectorUtils = {
9893
10095
  * @modified 2021-04-25 Extending `remove` to accept arrays of drawables.
9894
10096
  * @modified 2021-11-16 Adding the `PBText` drawable.
9895
10097
  * @modified 2022-08-01 Added `title` to the params.
9896
- * @version 1.15.1
10098
+ * @modified 2022-10-25 Added the `origin` to the default draw config.
10099
+ * @modified 2022-11-06 Adding an XML declaration to the SVG export routine.
10100
+ * @version 1.16.0
9897
10101
  *
9898
10102
  * @file PlotBoilerplate
9899
10103
  * @fileoverview The main class.
@@ -9989,6 +10193,7 @@ class PlotBoilerplate {
9989
10193
  * @param {string=} [config.title=null] - Specify any hover tile here. It will be attached as a `title` attribute to the most elevated element.
9990
10194
  */
9991
10195
  constructor(config) {
10196
+ var _a, _b;
9992
10197
  /**
9993
10198
  * A discrete timestamp to identify single render cycles.
9994
10199
  * Note that using system time milliseconds is not a safe way to identify render frames, as on modern powerful machines
@@ -10145,6 +10350,9 @@ class PlotBoilerplate {
10145
10350
  lineWidth: 1,
10146
10351
  fill: true,
10147
10352
  anchor: true
10353
+ },
10354
+ origin: {
10355
+ color: "#000000"
10148
10356
  }
10149
10357
  }; // END drawConfig
10150
10358
  // +---------------------------------------------------------------------------------
@@ -10163,6 +10371,7 @@ class PlotBoilerplate {
10163
10371
  this.config.enableGL = false;
10164
10372
  }
10165
10373
  if (this.config.enableGL) {
10374
+ // Override the case 'null' here. If GL is not supported, well then nothing works.
10166
10375
  const ctx = this.canvas.getContext("webgl"); // webgl-experimental?
10167
10376
  this.draw = new drawutilsgl(ctx, false);
10168
10377
  // PROBLEM: same instance of fill and draw when using WebGL.
@@ -10171,6 +10380,7 @@ class PlotBoilerplate {
10171
10380
  console.warn("Initialized with experimental mode enableGL=true. Note that this is not yet fully implemented.");
10172
10381
  }
10173
10382
  else {
10383
+ // Override the case 'null' here. If context creation is not supported, well then nothing works.
10174
10384
  const ctx = this.canvas.getContext("2d");
10175
10385
  this.draw = new drawutils(ctx, false);
10176
10386
  this.fill = new drawutils(ctx, true);
@@ -10207,8 +10417,8 @@ class PlotBoilerplate {
10207
10417
  if (config.title) {
10208
10418
  this.eventCatcher.setAttribute("title", config.title);
10209
10419
  }
10210
- this.draw.scale.set(this.config.scaleX, this.config.scaleY);
10211
- this.fill.scale.set(this.config.scaleX, this.config.scaleY);
10420
+ this.draw.scale.set((_a = this.config.scaleX) !== null && _a !== void 0 ? _a : 1.0, this.config.scaleY);
10421
+ this.fill.scale.set((_b = this.config.scaleX) !== null && _b !== void 0 ? _b : 1.0, this.config.scaleY);
10212
10422
  this.vertices = [];
10213
10423
  this.selectPolygon = null;
10214
10424
  this.draggedElements = [];
@@ -10253,11 +10463,13 @@ class PlotBoilerplate {
10253
10463
  var tosvgFill = tosvgDraw.copyInstance(true); // fillShapes=true
10254
10464
  tosvgDraw.beginDrawCycle(0);
10255
10465
  tosvgFill.beginDrawCycle(0);
10256
- if (pb.config.preClear)
10466
+ if (pb.config.preClear) {
10257
10467
  pb.config.preClear();
10258
- tosvgDraw.clear(pb.config.backgroundColor);
10259
- if (pb.config.preDraw)
10468
+ }
10469
+ tosvgDraw.clear(pb.config.backgroundColor || "white");
10470
+ if (pb.config.preDraw) {
10260
10471
  pb.config.preDraw(tosvgDraw, tosvgFill);
10472
+ }
10261
10473
  pb.drawAll(0, tosvgDraw, tosvgFill);
10262
10474
  pb.drawVertices(0, tosvgDraw);
10263
10475
  if (pb.config.postDraw)
@@ -10268,7 +10480,8 @@ class PlotBoilerplate {
10268
10480
  // https://caniuse.com/xml-serializer
10269
10481
  var serializer = new XMLSerializer();
10270
10482
  var svgCode = serializer.serializeToString(svgNode);
10271
- var blob = new Blob([svgCode], { type: "image/svg;charset=utf-8" });
10483
+ // Add: '<?xml version="1.0" encoding="utf-8"?>\n' ?
10484
+ var blob = new Blob(['<?xml version="1.0" encoding="utf-8"?>\n' + svgCode], { type: "image/svg;charset=utf-8" });
10272
10485
  // See documentation for FileSaver.js for usage.
10273
10486
  // https://github.com/eligrey/FileSaver.js
10274
10487
  if (typeof globalThis["saveAs"] !== "function")
@@ -10343,11 +10556,12 @@ class PlotBoilerplate {
10343
10556
  * @private
10344
10557
  **/
10345
10558
  updateCSSscale() {
10559
+ var _a, _b, _c, _d;
10346
10560
  if (this.config.cssUniformScale) {
10347
- PlotBoilerplate.utils.setCSSscale(this.canvas, this.config.cssScaleX, this.config.cssScaleX);
10561
+ PlotBoilerplate.utils.setCSSscale(this.canvas, (_a = this.config.cssScaleX) !== null && _a !== void 0 ? _a : 1.0, (_b = this.config.cssScaleX) !== null && _b !== void 0 ? _b : 1.0);
10348
10562
  }
10349
10563
  else {
10350
- PlotBoilerplate.utils.setCSSscale(this.canvas, this.config.cssScaleX, this.config.cssScaleY);
10564
+ PlotBoilerplate.utils.setCSSscale(this.canvas, (_c = this.config.cssScaleX) !== null && _c !== void 0 ? _c : 1.0, (_d = this.config.cssScaleY) !== null && _d !== void 0 ? _d : 1.0);
10351
10565
  }
10352
10566
  }
10353
10567
  /**
@@ -10620,7 +10834,8 @@ class PlotBoilerplate {
10620
10834
  * @return The vertex near the given position or undefined if none was found there.
10621
10835
  **/
10622
10836
  getVertexNear(pixelPosition, pixelTolerance) {
10623
- var p = this.locatePointNear(this.transformMousePosition(pixelPosition.x, pixelPosition.y), pixelTolerance / Math.min(this.config.cssScaleX, this.config.cssScaleY));
10837
+ var _a, _b;
10838
+ var p = this.locatePointNear(this.transformMousePosition(pixelPosition.x, pixelPosition.y), pixelTolerance / Math.min((_a = this.config.cssScaleX) !== null && _a !== void 0 ? _a : 1.0, (_b = this.config.cssScaleY) !== null && _b !== void 0 ? _b : 1.0));
10624
10839
  if (p && p.typeName == "vertex") {
10625
10840
  return this.vertices[p.vindex];
10626
10841
  }
@@ -10686,7 +10901,7 @@ class PlotBoilerplate {
10686
10901
  drawOrigin(draw) {
10687
10902
  // Add a crosshair to mark the origin
10688
10903
  draw.setCurrentId("origin");
10689
- draw.crosshair({ x: 0, y: 0 }, 10, "#000000");
10904
+ draw.crosshair({ x: 0, y: 0 }, 10, this.drawConfig.origin.color);
10690
10905
  }
10691
10906
  /**
10692
10907
  * This is just a tiny helper function to determine the render color of vertices.
@@ -10903,10 +11118,10 @@ class PlotBoilerplate {
10903
11118
  else {
10904
11119
  console.error("Cannot draw object. Unknown class.");
10905
11120
  }
10906
- draw.setCurrentClassName(null);
10907
- draw.setCurrentId(null);
10908
- fill.setCurrentClassName(null);
10909
- fill.setCurrentId(null);
11121
+ draw.setCurrentClassName(undefined);
11122
+ draw.setCurrentId(undefined);
11123
+ fill.setCurrentClassName(undefined);
11124
+ fill.setCurrentId(undefined);
10910
11125
  }
10911
11126
  /**
10912
11127
  * Draw the select-polygon (if there is one).
@@ -11009,7 +11224,7 @@ class PlotBoilerplate {
11009
11224
  **/
11010
11225
  clear() {
11011
11226
  // Note that elements might have an alpha channel. Clear the scene first.
11012
- this.draw.clear(this.config.backgroundColor);
11227
+ this.draw.clear(this.config.backgroundColor || "white");
11013
11228
  }
11014
11229
  /**
11015
11230
  * Clear the selection.<br>
@@ -11039,7 +11254,8 @@ class PlotBoilerplate {
11039
11254
  * @return {Bounds} The current viewport.
11040
11255
  **/
11041
11256
  viewport() {
11042
- return new Bounds(this.transformMousePosition(0, 0), this.transformMousePosition(this.canvasSize.width * this.config.cssScaleX, this.canvasSize.height * this.config.cssScaleY));
11257
+ var _a, _b;
11258
+ return new Bounds(this.transformMousePosition(0, 0), this.transformMousePosition(this.canvasSize.width * ((_a = this.config.cssScaleX) !== null && _a !== void 0 ? _a : 1.0), this.canvasSize.height * ((_b = this.config.cssScaleY) !== null && _b !== void 0 ? _b : 1.0)));
11043
11259
  }
11044
11260
  /**
11045
11261
  * Trigger the saveFile.hook.
@@ -11087,10 +11303,12 @@ class PlotBoilerplate {
11087
11303
  * @return {void}
11088
11304
  **/
11089
11305
  resizeCanvas() {
11306
+ var _a, _b, _c, _d, _e, _f;
11090
11307
  const _self = this;
11091
11308
  const _setSize = (w, h) => {
11092
- w *= _self.config.canvasWidthFactor;
11093
- h *= _self.config.canvasHeightFactor;
11309
+ var _a, _b;
11310
+ w *= (_a = _self.config.canvasWidthFactor) !== null && _a !== void 0 ? _a : 1.0;
11311
+ h *= (_b = _self.config.canvasHeightFactor) !== null && _b !== void 0 ? _b : 1.0;
11094
11312
  _self.canvasSize.width = w;
11095
11313
  _self.canvasSize.height = h;
11096
11314
  if (_self.canvas instanceof HTMLCanvasElement) {
@@ -11119,8 +11337,8 @@ class PlotBoilerplate {
11119
11337
  var width = globalThis.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
11120
11338
  var height = globalThis.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
11121
11339
  _self.canvas.style.position = "absolute";
11122
- _self.canvas.style.width = _self.config.canvasWidthFactor * width + "px";
11123
- _self.canvas.style.height = _self.config.canvasWidthFactor * height + "px";
11340
+ _self.canvas.style.width = ((_a = _self.config.canvasWidthFactor) !== null && _a !== void 0 ? _a : 1.0) * width + "px";
11341
+ _self.canvas.style.height = ((_b = _self.config.canvasWidthFactor) !== null && _b !== void 0 ? _b : 1.0) * height + "px";
11124
11342
  _self.canvas.style.top = "0px";
11125
11343
  _self.canvas.style.left = "0px";
11126
11344
  _setSize(width, height);
@@ -11129,16 +11347,16 @@ class PlotBoilerplate {
11129
11347
  // Set editor size
11130
11348
  _self.canvas.style.position = "absolute";
11131
11349
  const space = this.getAvailableContainerSpace();
11132
- _self.canvas.style.width = _self.config.canvasWidthFactor * space.width + "px";
11133
- _self.canvas.style.height = _self.config.canvasHeightFactor * space.height + "px";
11134
- _self.canvas.style.top = null;
11135
- _self.canvas.style.left = null;
11350
+ _self.canvas.style.width = ((_c = _self.config.canvasWidthFactor) !== null && _c !== void 0 ? _c : 1.0) * space.width + "px";
11351
+ _self.canvas.style.height = ((_d = _self.config.canvasHeightFactor) !== null && _d !== void 0 ? _d : 1.0) * space.height + "px";
11352
+ _self.canvas.style.top = "";
11353
+ _self.canvas.style.left = "";
11136
11354
  _setSize(space.width, space.height);
11137
11355
  }
11138
11356
  else {
11139
- _self.canvas.style.width = null;
11140
- _self.canvas.style.height = null;
11141
- _setSize(_self.config.defaultCanvasWidth, _self.config.defaultCanvasHeight);
11357
+ _self.canvas.style.width = "";
11358
+ _self.canvas.style.height = "";
11359
+ _setSize((_e = _self.config.defaultCanvasWidth) !== null && _e !== void 0 ? _e : 1024, (_f = _self.config.defaultCanvasHeight) !== null && _f !== void 0 ? _f : 768);
11142
11360
  }
11143
11361
  if (_self.config.redrawOnResize)
11144
11362
  _self.redraw();