plotboilerplate 1.14.0 → 1.17.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 (232) hide show
  1. package/README.md +2 -0
  2. package/changelog.md +57 -0
  3. package/dist/index.esm.js +856 -694
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.esm.min.js +1 -1
  6. package/dist/index.esm.min.js.map +1 -1
  7. package/dist/plotboilerplate.browser.min.js +1 -1
  8. package/dist/plotboilerplate.browser.min.js.map +1 -1
  9. package/dist/plotboilerplate.js +858 -598
  10. package/dist/plotboilerplate.min.js +1 -1
  11. package/package.json +1 -1
  12. package/src/cjs/BezierPath.d.ts +32 -14
  13. package/src/cjs/BezierPath.js +65 -24
  14. package/src/cjs/BezierPath.js.map +1 -1
  15. package/src/cjs/Bounds.d.ts +22 -1
  16. package/src/cjs/Bounds.js +24 -1
  17. package/src/cjs/Bounds.js.map +1 -1
  18. package/src/cjs/Circle.d.ts +15 -13
  19. package/src/cjs/Circle.js +16 -34
  20. package/src/cjs/Circle.js.map +1 -1
  21. package/src/cjs/CircleSector.d.ts +17 -16
  22. package/src/cjs/CircleSector.js +12 -24
  23. package/src/cjs/CircleSector.js.map +1 -1
  24. package/src/cjs/CubicBezierCurve.d.ts +16 -15
  25. package/src/cjs/CubicBezierCurve.js +57 -94
  26. package/src/cjs/CubicBezierCurve.js.map +1 -1
  27. package/src/cjs/KeyHandler.d.ts +10 -3
  28. package/src/cjs/KeyHandler.js +28 -23
  29. package/src/cjs/KeyHandler.js.map +1 -1
  30. package/src/cjs/Line.d.ts +2 -15
  31. package/src/cjs/Line.js +6 -31
  32. package/src/cjs/Line.js.map +1 -1
  33. package/src/cjs/MouseHandler.js +43 -53
  34. package/src/cjs/MouseHandler.js.map +1 -1
  35. package/src/cjs/PBImage.d.ts +15 -13
  36. package/src/cjs/PBImage.js +11 -15
  37. package/src/cjs/PBImage.js.map +1 -1
  38. package/src/cjs/PBText.d.ts +13 -12
  39. package/src/cjs/PBText.js +8 -12
  40. package/src/cjs/PBText.js.map +1 -1
  41. package/src/cjs/PlotBoilerplate.js +3 -2
  42. package/src/cjs/PlotBoilerplate.js.map +1 -1
  43. package/src/cjs/Polygon.d.ts +44 -14
  44. package/src/cjs/Polygon.js +116 -66
  45. package/src/cjs/Polygon.js.map +1 -1
  46. package/src/cjs/Triangle.d.ts +15 -13
  47. package/src/cjs/Triangle.js +23 -64
  48. package/src/cjs/Triangle.js.map +1 -1
  49. package/src/cjs/VEllipse.d.ts +14 -9
  50. package/src/cjs/VEllipse.js +10 -18
  51. package/src/cjs/VEllipse.js.map +1 -1
  52. package/src/cjs/VEllipseSector.d.ts +15 -1
  53. package/src/cjs/VEllipseSector.js +11 -1
  54. package/src/cjs/VEllipseSector.js.map +1 -1
  55. package/src/cjs/Vector.d.ts +3 -15
  56. package/src/cjs/Vector.js +9 -49
  57. package/src/cjs/Vector.js.map +1 -1
  58. package/src/cjs/VertTuple.d.ts +15 -1
  59. package/src/cjs/VertTuple.js +14 -19
  60. package/src/cjs/VertTuple.js.map +1 -1
  61. package/src/cjs/Vertex.d.ts +47 -13
  62. package/src/cjs/Vertex.js +62 -22
  63. package/src/cjs/Vertex.js.map +1 -1
  64. package/src/cjs/VertexListeners.d.ts +12 -8
  65. package/src/cjs/VertexListeners.js +18 -25
  66. package/src/cjs/VertexListeners.js.map +1 -1
  67. package/src/cjs/draw.d.ts +41 -2
  68. package/src/cjs/draw.js +140 -3
  69. package/src/cjs/draw.js.map +1 -1
  70. package/src/cjs/drawgl.d.ts +38 -2
  71. package/src/cjs/drawgl.js +41 -2
  72. package/src/cjs/drawgl.js.map +1 -1
  73. package/src/cjs/drawutilssvg.d.ts +66 -3
  74. package/src/cjs/drawutilssvg.js +140 -15
  75. package/src/cjs/drawutilssvg.js.map +1 -1
  76. package/src/cjs/index.d.ts +0 -1
  77. package/src/cjs/index.js +0 -1
  78. package/src/cjs/index.js.map +1 -1
  79. package/src/cjs/interfaces/DrawLib.d.ts +61 -26
  80. package/src/cjs/interfaces/DrawLib.js +2 -0
  81. package/src/cjs/interfaces/DrawLib.js.map +1 -1
  82. package/src/cjs/interfaces/core.d.ts +0 -12
  83. package/src/cjs/module.d.ts +1 -3
  84. package/src/cjs/module.js +2 -5
  85. package/src/cjs/module.js.map +1 -1
  86. package/src/cjs/utils/creategui.js +16 -2
  87. package/src/cjs/utils/datastructures/Girih.d.ts +5 -0
  88. package/src/cjs/utils/datastructures/Girih.js +18 -14
  89. package/src/cjs/utils/datastructures/Girih.js.map +1 -1
  90. package/src/cjs/utils/datastructures/GirihPenroseRhombus.js +42 -25
  91. package/src/cjs/utils/datastructures/GirihPenroseRhombus.js.map +1 -1
  92. package/src/cjs/utils/datastructures/GirihTile.js +2 -13
  93. package/src/cjs/utils/datastructures/GirihTile.js.map +1 -1
  94. package/src/cjs/utils/findInVertexArray.d.ts +19 -0
  95. package/src/cjs/utils/findInVertexArray.js +29 -0
  96. package/src/cjs/utils/findInVertexArray.js.map +1 -0
  97. package/src/cjs/utils/helpers/BezierPathInteractionHelper.d.ts +17 -1
  98. package/src/cjs/utils/helpers/BezierPathInteractionHelper.js +50 -32
  99. package/src/cjs/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
  100. package/src/cjs/utils/io/DndFileHandler.d.ts +63 -0
  101. package/src/cjs/utils/io/DndFileHandler.js +112 -0
  102. package/src/cjs/utils/io/DndFileHandler.js.map +1 -0
  103. package/src/cjs/utils/io/FileDrop.d.ts +98 -0
  104. package/src/cjs/utils/io/FileDrop.js +142 -0
  105. package/src/cjs/utils/io/FileDrop.js.map +1 -0
  106. package/src/esm/BezierPath.d.ts +32 -14
  107. package/src/esm/BezierPath.js +65 -24
  108. package/src/esm/BezierPath.js.map +1 -1
  109. package/src/esm/Bounds.d.ts +22 -1
  110. package/src/esm/Bounds.js +24 -1
  111. package/src/esm/Bounds.js.map +1 -1
  112. package/src/esm/Circle.d.ts +15 -13
  113. package/src/esm/Circle.js +16 -34
  114. package/src/esm/Circle.js.map +1 -1
  115. package/src/esm/CircleSector.d.ts +17 -16
  116. package/src/esm/CircleSector.js +12 -24
  117. package/src/esm/CircleSector.js.map +1 -1
  118. package/src/esm/CubicBezierCurve.d.ts +16 -15
  119. package/src/esm/CubicBezierCurve.js +57 -94
  120. package/src/esm/CubicBezierCurve.js.map +1 -1
  121. package/src/esm/KeyHandler.d.ts +10 -3
  122. package/src/esm/KeyHandler.js +28 -23
  123. package/src/esm/KeyHandler.js.map +1 -1
  124. package/src/esm/Line.d.ts +2 -15
  125. package/src/esm/Line.js +6 -31
  126. package/src/esm/Line.js.map +1 -1
  127. package/src/esm/MouseHandler.js +43 -53
  128. package/src/esm/MouseHandler.js.map +1 -1
  129. package/src/esm/PBImage.d.ts +15 -13
  130. package/src/esm/PBImage.js +11 -15
  131. package/src/esm/PBImage.js.map +1 -1
  132. package/src/esm/PBText.d.ts +13 -12
  133. package/src/esm/PBText.js +8 -12
  134. package/src/esm/PBText.js.map +1 -1
  135. package/src/esm/PlotBoilerplate.js +3 -2
  136. package/src/esm/PlotBoilerplate.js.map +1 -1
  137. package/src/esm/Polygon.d.ts +44 -14
  138. package/src/esm/Polygon.js +116 -66
  139. package/src/esm/Polygon.js.map +1 -1
  140. package/src/esm/Triangle.d.ts +15 -13
  141. package/src/esm/Triangle.js +23 -64
  142. package/src/esm/Triangle.js.map +1 -1
  143. package/src/esm/VEllipse.d.ts +14 -9
  144. package/src/esm/VEllipse.js +10 -18
  145. package/src/esm/VEllipse.js.map +1 -1
  146. package/src/esm/VEllipseSector.d.ts +15 -1
  147. package/src/esm/VEllipseSector.js +11 -1
  148. package/src/esm/VEllipseSector.js.map +1 -1
  149. package/src/esm/Vector.d.ts +3 -15
  150. package/src/esm/Vector.js +9 -49
  151. package/src/esm/Vector.js.map +1 -1
  152. package/src/esm/VertTuple.d.ts +15 -1
  153. package/src/esm/VertTuple.js +14 -19
  154. package/src/esm/VertTuple.js.map +1 -1
  155. package/src/esm/Vertex.d.ts +47 -13
  156. package/src/esm/Vertex.js +62 -22
  157. package/src/esm/Vertex.js.map +1 -1
  158. package/src/esm/VertexListeners.d.ts +12 -8
  159. package/src/esm/VertexListeners.js +18 -25
  160. package/src/esm/VertexListeners.js.map +1 -1
  161. package/src/esm/draw.d.ts +41 -2
  162. package/src/esm/draw.js +139 -3
  163. package/src/esm/draw.js.map +1 -1
  164. package/src/esm/drawgl.d.ts +38 -2
  165. package/src/esm/drawgl.js +41 -2
  166. package/src/esm/drawgl.js.map +1 -1
  167. package/src/esm/drawutilssvg.d.ts +66 -3
  168. package/src/esm/drawutilssvg.js +140 -15
  169. package/src/esm/drawutilssvg.js.map +1 -1
  170. package/src/esm/index.d.ts +0 -1
  171. package/src/esm/index.js +0 -1
  172. package/src/esm/index.js.map +1 -1
  173. package/src/esm/interfaces/DrawLib.d.ts +61 -26
  174. package/src/esm/interfaces/DrawLib.js +2 -0
  175. package/src/esm/interfaces/DrawLib.js.map +1 -1
  176. package/src/esm/interfaces/core.d.ts +0 -12
  177. package/src/esm/module.d.ts +1 -3
  178. package/src/esm/module.js +5 -4
  179. package/src/esm/module.js.map +1 -1
  180. package/src/esm/utils/datastructures/Girih.d.ts +5 -0
  181. package/src/esm/utils/datastructures/Girih.js +18 -14
  182. package/src/esm/utils/datastructures/Girih.js.map +1 -1
  183. package/src/esm/utils/datastructures/GirihPenroseRhombus.js +42 -25
  184. package/src/esm/utils/datastructures/GirihPenroseRhombus.js.map +1 -1
  185. package/src/esm/utils/datastructures/GirihTile.js +2 -13
  186. package/src/esm/utils/datastructures/GirihTile.js.map +1 -1
  187. package/src/esm/utils/findInVertexArray.d.ts +19 -0
  188. package/src/esm/utils/findInVertexArray.js +25 -0
  189. package/src/esm/utils/findInVertexArray.js.map +1 -0
  190. package/src/esm/utils/helpers/BezierPathInteractionHelper.d.ts +17 -1
  191. package/src/esm/utils/helpers/BezierPathInteractionHelper.js +49 -32
  192. package/src/esm/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
  193. package/src/esm/utils/io/DndFileHandler.d.ts +63 -0
  194. package/src/esm/utils/io/DndFileHandler.js +106 -0
  195. package/src/esm/utils/io/DndFileHandler.js.map +1 -0
  196. package/src/esm/utils/io/FileDrop.d.ts +98 -0
  197. package/src/esm/utils/io/FileDrop.js +136 -0
  198. package/src/esm/utils/io/FileDrop.js.map +1 -0
  199. package/src/ts/BezierPath.ts +78 -22
  200. package/src/ts/Bounds.ts +25 -1
  201. package/src/ts/Circle.ts +187 -200
  202. package/src/ts/CircleSector.ts +141 -141
  203. package/src/ts/CubicBezierCurve.ts +738 -810
  204. package/src/ts/KeyHandler.ts +221 -212
  205. package/src/ts/Line.ts +48 -80
  206. package/src/ts/MouseHandler.ts +356 -368
  207. package/src/ts/PBImage.ts +67 -69
  208. package/src/ts/PBText.ts +16 -14
  209. package/src/ts/PlotBoilerplate.ts +4 -2
  210. package/src/ts/Polygon.ts +493 -451
  211. package/src/ts/Triangle.ts +444 -489
  212. package/src/ts/VEllipse.ts +18 -17
  213. package/src/ts/VEllipseSector.ts +20 -1
  214. package/src/ts/Vector.ts +124 -160
  215. package/src/ts/VertTuple.ts +333 -338
  216. package/src/ts/Vertex.ts +75 -21
  217. package/src/ts/VertexListeners.ts +248 -266
  218. package/src/ts/draw.ts +192 -3
  219. package/src/ts/drawgl.ts +44 -2
  220. package/src/ts/drawutilssvg.ts +181 -15
  221. package/src/ts/index.ts +0 -1
  222. package/src/ts/interfaces/DrawLib.ts +69 -26
  223. package/src/ts/interfaces/core.ts +0 -11
  224. package/src/ts/module.ts +2 -4
  225. package/src/ts/utils/datastructures/Girih.ts +204 -209
  226. package/src/ts/utils/datastructures/GirihPenroseRhombus.ts +170 -152
  227. package/src/ts/utils/datastructures/GirihTile.ts +394 -419
  228. package/src/ts/utils/findInVertexArray.ts +28 -0
  229. package/src/ts/utils/helpers/BezierPathInteractionHelper.ts +56 -34
  230. package/src/ts/utils/io/FileDrop.ts +178 -0
  231. package/src/ts/SVGBuilder.ts +0 -109
  232. package/src/ts/utils/algorithms/sh-tmp.ts~ +0 -59
@@ -445,7 +445,10 @@ class AlloyFinger {
445
445
  * @modified 2020-07-24 Added the getClosestT(Vertex) function.
446
446
  * @modified 2020-12-29 Constructor is now private (no explicit use intended).
447
447
  * @modified 2021-05-25 Added BezierPath.fromReducedList( Array<number> ).
448
- * @version 2.3.1
448
+ * @modified 2022-01-31 Added `BezierPath.getEvenDistributionVertices(number)`.
449
+ * @modified 2022-02-02 Added the `destroy` method.
450
+ * @modified 2022-02-02 Cleared the `toSVGString` function (deprecated). Use `drawutilssvg` instead.
451
+ * @version 2.5.0
449
452
  *
450
453
  * @file BezierPath
451
454
  * @public
@@ -1342,6 +1345,59 @@ var BezierPath = /** @class */ (function () {
1342
1345
  }
1343
1346
  return new Bounds_1.Bounds(min, max);
1344
1347
  };
1348
+ /**
1349
+ * Get n 'equally' distributed vertices along this Bézier path.
1350
+ *
1351
+ * As the changing curvature of the B slines makes prediction of distances difficult, the
1352
+ * returned vertices' distances are only relatively equal:
1353
+ * - the distance grows where curvature is large.
1354
+ * - the distance shrinks where curvature is small.
1355
+ *
1356
+ * Only the distance mean of all consecutive is 1/n-th of the total arc length.
1357
+ *
1358
+ * Usually this approximation is good enough for most use cases.
1359
+ *
1360
+ * @param {number} pointCount - (must be at least 2) The number of desired points (start and end point included).
1361
+ * @return {Array<Vertex>}
1362
+ */
1363
+ BezierPath.prototype.getEvenDistributionVertices = function (pointCount) {
1364
+ if (pointCount < 2) {
1365
+ throw new Error("pointCount must be larger than one; is " + pointCount + ".");
1366
+ }
1367
+ var result = [];
1368
+ if (this.bezierCurves.length === 0) {
1369
+ return result;
1370
+ }
1371
+ // Fetch and add the start point from the source polygon
1372
+ var polygonPoint = new Vertex_1.Vertex(this.bezierCurves[0].startPoint);
1373
+ result.push(polygonPoint);
1374
+ // if (this.bezierCurves.length === 1) {
1375
+ // return result;
1376
+ // }
1377
+ var perimeter = this.totalArcLength;
1378
+ var stepSize = perimeter / (pointCount - 1);
1379
+ var n = this.bezierCurves.length;
1380
+ var curveIndex = 0;
1381
+ var segmentLength = this.bezierCurves[0].arcLength;
1382
+ var curSegmentU = stepSize;
1383
+ var i = 1;
1384
+ while (i < pointCount && curveIndex < n) {
1385
+ // Check if next eq point is inside this segment
1386
+ if (curSegmentU < segmentLength) {
1387
+ var newPoint = this.bezierCurves[curveIndex].getPoint(curSegmentU);
1388
+ result.push(newPoint);
1389
+ curSegmentU += stepSize;
1390
+ i++;
1391
+ }
1392
+ else {
1393
+ curveIndex++;
1394
+ curSegmentU = curSegmentU - segmentLength;
1395
+ segmentLength = curveIndex < n ? this.bezierCurves[curveIndex].arcLength : 0;
1396
+ }
1397
+ }
1398
+ result.push(new Vertex_1.Vertex(this.bezierCurves[n - 1].endPoint));
1399
+ return result;
1400
+ };
1345
1401
  /**
1346
1402
  * Clone this BezierPath (deep clone).
1347
1403
  *
@@ -1388,30 +1444,15 @@ var BezierPath = /** @class */ (function () {
1388
1444
  return true;
1389
1445
  };
1390
1446
  /**
1391
- * Create a <pre>&lt;path&gt;</pre> SVG representation of this bézier curve.
1392
- *
1393
- * @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
1394
- * @method toSVGString
1395
- * @param {object=} [options={}] - Like options.className
1396
- * @param {string=} [options.className] - The classname to use for the SVG item.
1397
- * @instance
1398
- * @memberof BezierPath
1399
- * @return {string} The SVG string.
1400
- **/
1401
- BezierPath.prototype.toSVGString = function (options) {
1402
- options = options || {};
1403
- var buffer = [];
1404
- buffer.push("<path");
1405
- if (options.className)
1406
- buffer.push(' class="' + options.className + '"');
1407
- buffer.push(' d="');
1408
- for (var c = 0; c < this.bezierCurves.length; c++) {
1409
- if (c > 0)
1410
- buffer.push(" ");
1411
- buffer.push(this.bezierCurves[c].toSVGPathData());
1447
+ * This function should invalidate any installed listeners and invalidate this object.
1448
+ * After calling this function the object might not hold valid data any more and
1449
+ * should not be used.
1450
+ */
1451
+ BezierPath.prototype.destroy = function () {
1452
+ for (var i = 0; i < this.bezierCurves.length; i++) {
1453
+ this.bezierCurves[i].destroy();
1412
1454
  }
1413
- buffer.push('" />');
1414
- return buffer.join("");
1455
+ this.isDestroyed = true;
1415
1456
  };
1416
1457
  /**
1417
1458
  * Create a JSON string representation of this bézier curve.
@@ -1640,7 +1681,8 @@ exports.BezierPath = BezierPath;
1640
1681
  * @modified 2020-11-19 Set min, max, width and height to private.
1641
1682
  * @modified 2021-02-02 Added the `toPolygon` method.
1642
1683
  * @modified 2021-06-21 (mid-summer) Added `getCenter` method.
1643
- * @version 1.3.0
1684
+ * @modified 2022-02-01 Added the `toString` function.
1685
+ * @version 1.4.0
1644
1686
  **/
1645
1687
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1646
1688
  exports.Bounds = void 0;
@@ -1679,9 +1721,31 @@ var Bounds = /** @class */ (function () {
1679
1721
  Bounds.prototype.toPolygon = function () {
1680
1722
  return new Polygon_1.Polygon([new Vertex_1.Vertex(this.min), new Vertex_1.Vertex(this.max.x, this.min.y), new Vertex_1.Vertex(this.max), new Vertex_1.Vertex(this.min.x, this.max.y)], false);
1681
1723
  };
1724
+ /**
1725
+ * Get the center of this boinding box.
1726
+ *
1727
+ * @method getCenter
1728
+ * @instance
1729
+ * @memberof Bounds
1730
+ * @returns {Vertex} The center of these bounds.
1731
+ */
1682
1732
  Bounds.prototype.getCenter = function () {
1683
1733
  return new Vertex_1.Vertex(this.min.x + (this.max.x - this.min.x) / 2.0, this.min.y + (this.max.y - this.min.y) / 2);
1684
1734
  };
1735
+ /**
1736
+ * Convert these bounds to a human readable form.
1737
+ *
1738
+ * Note: the returned format might change in the future, so please do not
1739
+ * rely on the returned string format.
1740
+ *
1741
+ * @method toString
1742
+ * @instance
1743
+ * @memberof Bounds
1744
+ * @returns {string} Get these bounds in a human readable form.
1745
+ */
1746
+ Bounds.prototype.toString = function () {
1747
+ return "{ min: " + this.min.toString() + ", max : " + this.max.toString() + ", width: " + this.width + ", height : " + this.height + " }";
1748
+ };
1685
1749
  /**
1686
1750
  * Compute the minimal bounding box for a given set of vertices.
1687
1751
  *
@@ -1730,7 +1794,9 @@ exports.Bounds = Bounds;
1730
1794
  * @modified 2020-09-07 Changed the vertAt function by switching sin and cos! The old version did not return the correct vertex (by angle) accoring to the assumed circle math.
1731
1795
  * @modified 2020-10-16 Added the containsCircle(...) function.
1732
1796
  * @modified 2021-01-20 Added UID.
1733
- * @version 1.2.0
1797
+ * @modified 2022-02-02 Added the `destroy` method.
1798
+ * @modified 2022-02-02 Cleared the `toSVGString` function (deprecated). Use `drawutilssvg` instead.
1799
+ * @version 1.3.0
1734
1800
  **/
1735
1801
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1736
1802
  exports.Circle = void 0;
@@ -1767,7 +1833,6 @@ var Circle = /** @class */ (function () {
1767
1833
  this.center = center;
1768
1834
  this.radius = radius;
1769
1835
  }
1770
- ;
1771
1836
  /**
1772
1837
  * Check if the given circle is fully contained inside this circle.
1773
1838
  *
@@ -1780,7 +1845,6 @@ var Circle = /** @class */ (function () {
1780
1845
  Circle.prototype.containsCircle = function (circle) {
1781
1846
  return this.center.distance(circle.center) + circle.radius < this.radius;
1782
1847
  };
1783
- ;
1784
1848
  /**
1785
1849
  * Calculate the distance from this circle to the given line.
1786
1850
  *
@@ -1799,7 +1863,6 @@ var Circle = /** @class */ (function () {
1799
1863
  var closestPointOnLine = line.getClosestPoint(this.center);
1800
1864
  return closestPointOnLine.distance(this.center) - this.radius;
1801
1865
  };
1802
- ;
1803
1866
  /**
1804
1867
  * Get the vertex on the this circle for the given angle.
1805
1868
  *
@@ -1813,7 +1876,6 @@ var Circle = /** @class */ (function () {
1813
1876
  // Find the point on the circle respective the angle. Then move relative to center.
1814
1877
  return Circle.circleUtils.vertAt(angle, this.radius).add(this.center);
1815
1878
  };
1816
- ;
1817
1879
  /**
1818
1880
  * Get a tangent line of this circle for a given angle.
1819
1881
  *
@@ -1830,7 +1892,6 @@ var Circle = /** @class */ (function () {
1830
1892
  // Construct the perpendicular of the line in point a. Then move relative to center.
1831
1893
  return new Vector_1.Vector(pointA, new Vertex_1.Vertex(0, 0)).add(this.center).perp();
1832
1894
  };
1833
- ;
1834
1895
  /**
1835
1896
  * Calculate the intersection points (if exists) with the given circle.
1836
1897
  *
@@ -1870,47 +1931,32 @@ var Circle = /** @class */ (function () {
1870
1931
  // x4 = P2.x - h*(P1.y - P0.y)/d;
1871
1932
  // y4 = P2.y + h*(P1.x - P0.x)/d;
1872
1933
  // return pair<Point, Point>(Point(x3, y3), Point(x4, y4));
1873
- // }
1934
+ // }
1874
1935
  var p0 = this.center;
1875
1936
  var p1 = circle.center;
1876
1937
  var d = p0.distance(p1);
1877
1938
  var a = (this.radius * this.radius - circle.radius * circle.radius + d * d) / (2 * d);
1878
1939
  var h = Math.sqrt(this.radius * this.radius - a * a);
1879
1940
  var p2 = p1.clone().scale(a / d, p0);
1880
- var x3 = p2.x + h * (p1.y - p0.y) / d;
1881
- var y3 = p2.y - h * (p1.x - p0.x) / d;
1882
- var x4 = p2.x - h * (p1.y - p0.y) / d;
1883
- var y4 = p2.y + h * (p1.x - p0.x) / d;
1941
+ var x3 = p2.x + (h * (p1.y - p0.y)) / d;
1942
+ var y3 = p2.y - (h * (p1.x - p0.x)) / d;
1943
+ var x4 = p2.x - (h * (p1.y - p0.y)) / d;
1944
+ var y4 = p2.y + (h * (p1.x - p0.x)) / d;
1884
1945
  return new Line_1.Line(new Vertex_1.Vertex(x3, y3), new Vertex_1.Vertex(x4, y4));
1885
1946
  };
1886
- ;
1887
1947
  /**
1888
- * Create an SVG representation of this circle.
1889
- *
1890
- * @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
1891
- * @method toSVGString
1892
- * @param {object=} options - An optional set of options, like 'className'.
1893
- * @return {string} A string representing the SVG code for this vertex.
1894
- * @instance
1895
- * @memberof Circle
1896
- */
1897
- Circle.prototype.toSVGString = function (options) {
1898
- options = options || {};
1899
- var buffer = [];
1900
- buffer.push('<circle');
1901
- if (options.className)
1902
- buffer.push(' class="' + options.className + '"');
1903
- buffer.push(' cx="' + this.center.x + '"');
1904
- buffer.push(' cy="' + this.center.y + '"');
1905
- buffer.push(' r="' + this.radius + '"');
1906
- buffer.push(' />');
1907
- return buffer.join('');
1948
+ * This function should invalidate any installed listeners and invalidate this object.
1949
+ * After calling this function the object might not hold valid data any more and
1950
+ * should not be used.
1951
+ */
1952
+ Circle.prototype.destroy = function () {
1953
+ this.center.destroy();
1954
+ this.isDestroyed = true;
1908
1955
  };
1909
- ;
1910
1956
  Circle.circleUtils = {
1911
1957
  vertAt: function (angle, radius) {
1912
1958
  /* return new Vertex( Math.sin(angle) * radius,
1913
- Math.cos(angle) * radius ); */
1959
+ Math.cos(angle) * radius ); */
1914
1960
  return new Vertex_1.Vertex(Math.cos(angle) * radius, Math.sin(angle) * radius);
1915
1961
  }
1916
1962
  };
@@ -1964,27 +2010,15 @@ var CircleSector = /** @class */ (function () {
1964
2010
  this.startAngle = startAngle;
1965
2011
  this.endAngle = endAngle;
1966
2012
  }
1967
- ;
1968
2013
  /**
1969
- * Create an SVG representation of this circle.
1970
- *
1971
- * @method toSVGString
1972
- * @param {object=} options - An optional set of options, like 'className'.
1973
- * @return {string} A string representing the SVG code for this vertex.
1974
- * @instance
1975
- * @memberof Circle
1976
- */
1977
- CircleSector.prototype.toSVGString = function (options) {
1978
- options = options || {};
1979
- var buffer = [];
1980
- buffer.push('<path ');
1981
- if (options.className)
1982
- buffer.push(' class="' + options.className + '"');
1983
- var data = CircleSector.circleSectorUtils.describeSVGArc(this.circle.center.x, this.circle.center.y, this.circle.radius, this.startAngle, this.endAngle);
1984
- buffer.push(' d="' + data.join(" ") + '" />');
1985
- return buffer.join('');
2014
+ * This function should invalidate any installed listeners and invalidate this object.
2015
+ * After calling this function the object might not hold valid data any more and
2016
+ * should not be used.
2017
+ */
2018
+ CircleSector.prototype.destroy = function () {
2019
+ this.circle.destroy();
2020
+ this.isDestroyed = true;
1986
2021
  };
1987
- ;
1988
2022
  CircleSector.circleSectorUtils = {
1989
2023
  /**
1990
2024
  * Helper function to convert polar circle coordinates to cartesian coordinates.
@@ -1992,11 +2026,11 @@ var CircleSector = /** @class */ (function () {
1992
2026
  * TODO: generalize for ellipses (two radii).
1993
2027
  *
1994
2028
  * @param {number} angle - The angle in radians.
1995
- */
2029
+ */
1996
2030
  polarToCartesian: function (centerX, centerY, radius, angle) {
1997
2031
  return {
1998
- x: centerX + (radius * Math.cos(angle)),
1999
- y: centerY + (radius * Math.sin(angle))
2032
+ x: centerX + radius * Math.cos(angle),
2033
+ y: centerY + radius * Math.sin(angle)
2000
2034
  };
2001
2035
  },
2002
2036
  /**
@@ -2009,7 +2043,7 @@ var CircleSector = /** @class */ (function () {
2009
2043
  * @return [ 'A', radiusx, radiusy, rotation=0, largeArcFlag=1|0, sweepFlag=0, endx, endy ]
2010
2044
  */
2011
2045
  describeSVGArc: function (x, y, radius, startAngle, endAngle, options) {
2012
- if (typeof options === 'undefined')
2046
+ if (typeof options === "undefined")
2013
2047
  options = { moveToStart: true };
2014
2048
  var end = CircleSector.circleSectorUtils.polarToCartesian(x, y, radius, endAngle);
2015
2049
  var start = CircleSector.circleSectorUtils.polarToCartesian(x, y, radius, startAngle);
@@ -2034,7 +2068,7 @@ var CircleSector = /** @class */ (function () {
2034
2068
  }
2035
2069
  var pathData = [];
2036
2070
  if (options.moveToStart) {
2037
- pathData.push('M', start.x, start.y);
2071
+ pathData.push("M", start.x, start.y);
2038
2072
  }
2039
2073
  pathData.push("A", radius, radius, 0, largeArcFlag, sweepFlag, end.x, end.y);
2040
2074
  return pathData;
@@ -2071,7 +2105,9 @@ exports.CircleSector = CircleSector;
2071
2105
  * @modified 2020-07-14 Changed the moveCurvePoint(...,Vertex) to moveCurvePoint(...,XYCoords), which is more generic.
2072
2106
  * @modified 2020-07-24 Added the getClosestT function and the helper function locateIntervalByDistance(...).
2073
2107
  * @modified 2021-01-20 Added UID.
2074
- * @version 2.5.0
2108
+ * @modified 2022-02-02 Added the `destroy` method.
2109
+ * @modified 2022-02-02 Cleared the `toSVGPathData` function (deprecated). Use `drawutilssvg` instead.
2110
+ * @version 2.6.0
2075
2111
  *
2076
2112
  * @file CubicBezierCurve
2077
2113
  * @public
@@ -2126,7 +2162,6 @@ var CubicBezierCurve = /** @class */ (function () {
2126
2162
  this.arcLength = null;
2127
2163
  this.updateArcLengths();
2128
2164
  }
2129
- ;
2130
2165
  /**
2131
2166
  * Move the given curve point (the start point, end point or one of the two
2132
2167
  * control points).
@@ -2163,7 +2198,6 @@ var CubicBezierCurve = /** @class */ (function () {
2163
2198
  if (updateArcLengths)
2164
2199
  this.updateArcLengths();
2165
2200
  };
2166
- ;
2167
2201
  /**
2168
2202
  * Translate the whole curve by the given {x,y} amount: moves all four points.
2169
2203
  *
@@ -2180,7 +2214,6 @@ var CubicBezierCurve = /** @class */ (function () {
2180
2214
  this.endPoint.add(amount);
2181
2215
  return this;
2182
2216
  };
2183
- ;
2184
2217
  /**
2185
2218
  * Reverse this curve, means swapping start- and end-point and swapping
2186
2219
  * start-control- and end-control-point.
@@ -2199,7 +2232,6 @@ var CubicBezierCurve = /** @class */ (function () {
2199
2232
  this.endControlPoint = tmp;
2200
2233
  return this;
2201
2234
  };
2202
- ;
2203
2235
  /**
2204
2236
  * Get the total curve length.<br>
2205
2237
  * <br>
@@ -2218,7 +2250,6 @@ var CubicBezierCurve = /** @class */ (function () {
2218
2250
  CubicBezierCurve.prototype.getLength = function () {
2219
2251
  return this.arcLength;
2220
2252
  };
2221
- ;
2222
2253
  /**
2223
2254
  * Uptate the internal arc segment buffer and their lengths.<br>
2224
2255
  * <br>
@@ -2256,7 +2287,6 @@ var CubicBezierCurve = /** @class */ (function () {
2256
2287
  }
2257
2288
  this.arcLength = newLength;
2258
2289
  };
2259
- ;
2260
2290
  /**
2261
2291
  * Get a 't' (relative position on curve) with the closest distance to point 'p'.
2262
2292
  *
@@ -2279,7 +2309,6 @@ var CubicBezierCurve = /** @class */ (function () {
2279
2309
  } while (iteration < 4 && this.getPointAt(result.tPrev).distance(this.getPointAt(result.tNext)) > desiredEpsilon);
2280
2310
  return result.t;
2281
2311
  };
2282
- ;
2283
2312
  /**
2284
2313
  * This helper function locates the 't' on a fixed step interval with the minimal distance
2285
2314
  * between the curve (at 't') and the given point.
@@ -2308,12 +2337,12 @@ var CubicBezierCurve = /** @class */ (function () {
2308
2337
  minDist = dist;
2309
2338
  }
2310
2339
  }
2311
- return { t: tStart + tDiff * (minIndex / stepCount),
2340
+ return {
2341
+ t: tStart + tDiff * (minIndex / stepCount),
2312
2342
  tPrev: tStart + tDiff * (Math.max(0, minIndex - 1) / stepCount),
2313
2343
  tNext: tStart + tDiff * (Math.min(stepCount, minIndex + 1) / stepCount)
2314
2344
  };
2315
2345
  };
2316
- ;
2317
2346
  /**
2318
2347
  * Get the bounds of this bezier curve.
2319
2348
  *
@@ -2335,7 +2364,6 @@ var CubicBezierCurve = /** @class */ (function () {
2335
2364
  }
2336
2365
  return new Bounds_1.Bounds(min, max);
2337
2366
  };
2338
- ;
2339
2367
  /**
2340
2368
  * Get the start point of the curve.<br>
2341
2369
  * <br>
@@ -2349,7 +2377,6 @@ var CubicBezierCurve = /** @class */ (function () {
2349
2377
  CubicBezierCurve.prototype.getStartPoint = function () {
2350
2378
  return this.startPoint;
2351
2379
  };
2352
- ;
2353
2380
  /**
2354
2381
  * Get the end point of the curve.<br>
2355
2382
  * <br>
@@ -2363,7 +2390,6 @@ var CubicBezierCurve = /** @class */ (function () {
2363
2390
  CubicBezierCurve.prototype.getEndPoint = function () {
2364
2391
  return this.endPoint;
2365
2392
  };
2366
- ;
2367
2393
  /**
2368
2394
  * Get the start control point of the curve.<br>
2369
2395
  * <br>
@@ -2377,7 +2403,6 @@ var CubicBezierCurve = /** @class */ (function () {
2377
2403
  CubicBezierCurve.prototype.getStartControlPoint = function () {
2378
2404
  return this.startControlPoint;
2379
2405
  };
2380
- ;
2381
2406
  /**
2382
2407
  * Get the end control point of the curve.<br>
2383
2408
  * <br>
@@ -2391,7 +2416,6 @@ var CubicBezierCurve = /** @class */ (function () {
2391
2416
  CubicBezierCurve.prototype.getEndControlPoint = function () {
2392
2417
  return this.endControlPoint;
2393
2418
  };
2394
- ;
2395
2419
  /**
2396
2420
  * Get one of the four curve points specified by the passt point ID.
2397
2421
  *
@@ -2412,7 +2436,6 @@ var CubicBezierCurve = /** @class */ (function () {
2412
2436
  return this.endControlPoint;
2413
2437
  throw new Error("Invalid point ID '" + id + "'.");
2414
2438
  };
2415
- ;
2416
2439
  /**
2417
2440
  * Get the curve point at a given position t, where t is in [0,1].<br>
2418
2441
  * <br>
@@ -2427,13 +2450,16 @@ var CubicBezierCurve = /** @class */ (function () {
2427
2450
  **/
2428
2451
  CubicBezierCurve.prototype.getPointAt = function (t) {
2429
2452
  // Perform some powerful math magic
2430
- var x = this.startPoint.x * Math.pow(1.0 - t, 3) + this.startControlPoint.x * 3 * t * Math.pow(1.0 - t, 2)
2431
- + this.endControlPoint.x * 3 * Math.pow(t, 2) * (1.0 - t) + this.endPoint.x * Math.pow(t, 3);
2432
- var y = this.startPoint.y * Math.pow(1.0 - t, 3) + this.startControlPoint.y * 3 * t * Math.pow(1.0 - t, 2)
2433
- + this.endControlPoint.y * 3 * Math.pow(t, 2) * (1.0 - t) + this.endPoint.y * Math.pow(t, 3);
2453
+ var x = this.startPoint.x * Math.pow(1.0 - t, 3) +
2454
+ this.startControlPoint.x * 3 * t * Math.pow(1.0 - t, 2) +
2455
+ this.endControlPoint.x * 3 * Math.pow(t, 2) * (1.0 - t) +
2456
+ this.endPoint.x * Math.pow(t, 3);
2457
+ var y = this.startPoint.y * Math.pow(1.0 - t, 3) +
2458
+ this.startControlPoint.y * 3 * t * Math.pow(1.0 - t, 2) +
2459
+ this.endControlPoint.y * 3 * Math.pow(t, 2) * (1.0 - t) +
2460
+ this.endPoint.y * Math.pow(t, 3);
2434
2461
  return new Vertex_1.Vertex(x, y);
2435
2462
  };
2436
- ;
2437
2463
  /**
2438
2464
  * Get the curve point at a given position u, where u is in [0,arcLength].<br>
2439
2465
  * <br>
@@ -2449,7 +2475,6 @@ var CubicBezierCurve = /** @class */ (function () {
2449
2475
  CubicBezierCurve.prototype.getPoint = function (u) {
2450
2476
  return this.getPointAt(u / this.arcLength);
2451
2477
  };
2452
- ;
2453
2478
  /**
2454
2479
  * Get the curve tangent vector at a given absolute curve position t in [0,1].<br>
2455
2480
  * <br>
@@ -2470,18 +2495,11 @@ var CubicBezierCurve = /** @class */ (function () {
2470
2495
  var t2 = t * t;
2471
2496
  // (1 - t)^2 = (1-t)*(1-t) = 1 - t - t + t^2 = 1 - 2*t + t^2
2472
2497
  var nt2 = 1 - 2 * t + t2;
2473
- var tX = -3 * a.x * nt2 +
2474
- b.x * (3 * nt2 - 6 * (t - t2)) +
2475
- c.x * (6 * (t - t2) - 3 * t2) +
2476
- 3 * d.x * t2;
2477
- var tY = -3 * a.y * nt2 +
2478
- b.y * (3 * nt2 - 6 * (t - t2)) +
2479
- c.y * (6 * (t - t2) - 3 * t2) +
2480
- 3 * d.y * t2;
2498
+ var tX = -3 * a.x * nt2 + b.x * (3 * nt2 - 6 * (t - t2)) + c.x * (6 * (t - t2) - 3 * t2) + 3 * d.x * t2;
2499
+ var tY = -3 * a.y * nt2 + b.y * (3 * nt2 - 6 * (t - t2)) + c.y * (6 * (t - t2) - 3 * t2) + 3 * d.y * t2;
2481
2500
  // Note: my implementation does NOT normalize tangent vectors!
2482
2501
  return new Vertex_1.Vertex(tX, tY);
2483
2502
  };
2484
- ;
2485
2503
  /**
2486
2504
  * Get a sub curve at the given start end end offsets (values between 0.0 and 1.0).
2487
2505
  *
@@ -2507,7 +2525,6 @@ var CubicBezierCurve = /** @class */ (function () {
2507
2525
  // pb.draw.cubicBezier( startVec.a, endVec.a, startVec.b, endVec.b, '#8800ff', 2 );
2508
2526
  return new CubicBezierCurve(startVec.a, endVec.a, startVec.b, endVec.b);
2509
2527
  };
2510
- ;
2511
2528
  /**
2512
2529
  * Convert a relative curve position u to the absolute curve position t.
2513
2530
  *
@@ -2518,9 +2535,8 @@ var CubicBezierCurve = /** @class */ (function () {
2518
2535
  * @return {number}
2519
2536
  **/
2520
2537
  CubicBezierCurve.prototype.convertU2T = function (u) {
2521
- return Math.max(0.0, Math.min(1.0, (u / this.arcLength)));
2538
+ return Math.max(0.0, Math.min(1.0, u / this.arcLength));
2522
2539
  };
2523
- ;
2524
2540
  /**
2525
2541
  * Get the curve tangent vector at a given relative position u in [0,arcLength].<br>
2526
2542
  * <br>
@@ -2535,7 +2551,6 @@ var CubicBezierCurve = /** @class */ (function () {
2535
2551
  CubicBezierCurve.prototype.getTangent = function (u) {
2536
2552
  return this.getTangentAt(this.convertU2T(u));
2537
2553
  };
2538
- ;
2539
2554
  /**
2540
2555
  * Get the curve perpendicular at a given relative position u in [0,arcLength] as a vector.<br>
2541
2556
  * <br>
@@ -2550,7 +2565,6 @@ var CubicBezierCurve = /** @class */ (function () {
2550
2565
  CubicBezierCurve.prototype.getPerpendicular = function (u) {
2551
2566
  return this.getPerpendicularAt(this.convertU2T(u));
2552
2567
  };
2553
- ;
2554
2568
  /**
2555
2569
  * Get the curve perpendicular at a given absolute position t in [0,1] as a vector.<br>
2556
2570
  * <br>
@@ -2566,7 +2580,6 @@ var CubicBezierCurve = /** @class */ (function () {
2566
2580
  var tangentVector = this.getTangentAt(t);
2567
2581
  return new Vertex_1.Vertex(tangentVector.y, -tangentVector.x);
2568
2582
  };
2569
- ;
2570
2583
  /**
2571
2584
  * Clone this Bézier curve (deep clone).
2572
2585
  *
@@ -2578,7 +2591,6 @@ var CubicBezierCurve = /** @class */ (function () {
2578
2591
  CubicBezierCurve.prototype.clone = function () {
2579
2592
  return new CubicBezierCurve(this.getStartPoint().clone(), this.getEndPoint().clone(), this.getStartControlPoint().clone(), this.getEndControlPoint().clone());
2580
2593
  };
2581
- ;
2582
2594
  /**
2583
2595
  * Check if this and the specified curve are equal.<br>
2584
2596
  * <br>
@@ -2597,17 +2609,25 @@ var CubicBezierCurve = /** @class */ (function () {
2597
2609
  // Let's see if this restricted version works out.
2598
2610
  if (!curve)
2599
2611
  return false;
2600
- if (!curve.startPoint ||
2601
- !curve.endPoint ||
2602
- !curve.startControlPoint ||
2603
- !curve.endControlPoint)
2612
+ if (!curve.startPoint || !curve.endPoint || !curve.startControlPoint || !curve.endControlPoint)
2604
2613
  return false;
2605
- return this.startPoint.equals(curve.startPoint)
2606
- && this.endPoint.equals(curve.endPoint)
2607
- && this.startControlPoint.equals(curve.startControlPoint)
2608
- && this.endControlPoint.equals(curve.endControlPoint);
2614
+ return (this.startPoint.equals(curve.startPoint) &&
2615
+ this.endPoint.equals(curve.endPoint) &&
2616
+ this.startControlPoint.equals(curve.startControlPoint) &&
2617
+ this.endControlPoint.equals(curve.endControlPoint));
2618
+ };
2619
+ /**
2620
+ * This function should invalidate any installed listeners and invalidate this object.
2621
+ * After calling this function the object might not hold valid data any more and
2622
+ * should not be used.
2623
+ */
2624
+ CubicBezierCurve.prototype.destroy = function () {
2625
+ this.startPoint.destroy();
2626
+ this.endPoint.destroy();
2627
+ this.startControlPoint.destroy();
2628
+ this.endControlPoint.destroy();
2629
+ this.isDestroyed = true;
2609
2630
  };
2610
- ;
2611
2631
  /**
2612
2632
  * Quick check for class instance.
2613
2633
  * Is there a better way?
@@ -2633,41 +2653,6 @@ var CubicBezierCurve = /** @class */ (function () {
2633
2653
  */
2634
2654
  return obj instanceof CubicBezierCurve;
2635
2655
  };
2636
- ;
2637
- /**
2638
- * Create an SVG path data representation of this bézier curve.
2639
- *
2640
- * Path data string format is:<br>
2641
- * <pre>'M x0 y1 C dx0 dy1 dx1 dy1 x1 x2'</pre><br>
2642
- * or in other words<br>
2643
- * <pre>'M startoint.x startPoint.y C startControlPoint.x startControlPoint.y endControlPoint.x endControlPoint.y endPoint.x endPoint.y'</pre>
2644
- *
2645
- * @method toSVGPathData
2646
- * @instance
2647
- * @memberof CubicBezierCurve
2648
- * @return {string} The SVG path data string.
2649
- **/
2650
- CubicBezierCurve.prototype.toSVGPathData = function () {
2651
- var buffer = [];
2652
- buffer.push('M ');
2653
- buffer.push(this.startPoint.x.toString());
2654
- buffer.push(' ');
2655
- buffer.push(this.startPoint.y.toString());
2656
- buffer.push(' C ');
2657
- buffer.push(this.startControlPoint.x.toString());
2658
- buffer.push(' ');
2659
- buffer.push(this.startControlPoint.y.toString());
2660
- buffer.push(' ');
2661
- buffer.push(this.endControlPoint.x.toString());
2662
- buffer.push(' ');
2663
- buffer.push(this.endControlPoint.y.toString());
2664
- buffer.push(' ');
2665
- buffer.push(this.endPoint.x.toString());
2666
- buffer.push(' ');
2667
- buffer.push(this.endPoint.y.toString());
2668
- return buffer.join('');
2669
- };
2670
- ;
2671
2656
  /**
2672
2657
  * Convert this curve to a JSON string.
2673
2658
  *
@@ -2680,18 +2665,33 @@ var CubicBezierCurve = /** @class */ (function () {
2680
2665
  CubicBezierCurve.prototype.toJSON = function (prettyFormat) {
2681
2666
  var jsonString = "{ " + // begin object
2682
2667
  (prettyFormat ? "\n\t" : "") +
2683
- "\"startPoint\" : [" + this.getStartPoint().x + "," + this.getStartPoint().y + "], " +
2668
+ '"startPoint" : [' +
2669
+ this.getStartPoint().x +
2670
+ "," +
2671
+ this.getStartPoint().y +
2672
+ "], " +
2684
2673
  (prettyFormat ? "\n\t" : "") +
2685
- "\"endPoint\" : [" + this.getEndPoint().x + "," + this.getEndPoint().y + "], " +
2674
+ '"endPoint" : [' +
2675
+ this.getEndPoint().x +
2676
+ "," +
2677
+ this.getEndPoint().y +
2678
+ "], " +
2686
2679
  (prettyFormat ? "\n\t" : "") +
2687
- "\"startControlPoint\": [" + this.getStartControlPoint().x + "," + this.getStartControlPoint().y + "], " +
2680
+ '"startControlPoint": [' +
2681
+ this.getStartControlPoint().x +
2682
+ "," +
2683
+ this.getStartControlPoint().y +
2684
+ "], " +
2688
2685
  (prettyFormat ? "\n\t" : "") +
2689
- "\"endControlPoint\" : [" + this.getEndControlPoint().x + "," + this.getEndControlPoint().y + "]" +
2686
+ '"endControlPoint" : [' +
2687
+ this.getEndControlPoint().x +
2688
+ "," +
2689
+ this.getEndControlPoint().y +
2690
+ "]" +
2690
2691
  (prettyFormat ? "\n\t" : "") +
2691
2692
  " }"; // end object
2692
2693
  return jsonString;
2693
2694
  };
2694
- ;
2695
2695
  /**
2696
2696
  * Parse a Bézier curve from the given JSON string.
2697
2697
  *
@@ -2706,7 +2706,6 @@ var CubicBezierCurve = /** @class */ (function () {
2706
2706
  var obj = JSON.parse(jsonString);
2707
2707
  return CubicBezierCurve.fromObject(obj);
2708
2708
  };
2709
- ;
2710
2709
  /**
2711
2710
  * Try to convert the passed object to a CubicBezierCurve.
2712
2711
  *
@@ -2721,16 +2720,15 @@ var CubicBezierCurve = /** @class */ (function () {
2721
2720
  if (typeof obj !== "object")
2722
2721
  throw "Can only build from object.";
2723
2722
  if (!obj.startPoint)
2724
- throw "Object member \"startPoint\" missing.";
2723
+ throw 'Object member "startPoint" missing.';
2725
2724
  if (!obj.endPoint)
2726
- throw "Object member \"endPoint\" missing.";
2725
+ throw 'Object member "endPoint" missing.';
2727
2726
  if (!obj.startControlPoint)
2728
- throw "Object member \"startControlPoint\" missing.";
2727
+ throw 'Object member "startControlPoint" missing.';
2729
2728
  if (!obj.endControlPoint)
2730
- throw "Object member \"endControlPoint\" missing.";
2729
+ throw 'Object member "endControlPoint" missing.';
2731
2730
  return new CubicBezierCurve(new Vertex_1.Vertex(obj.startPoint[0], obj.startPoint[1]), new Vertex_1.Vertex(obj.endPoint[0], obj.endPoint[1]), new Vertex_1.Vertex(obj.startControlPoint[0], obj.startControlPoint[1]), new Vertex_1.Vertex(obj.endControlPoint[0], obj.endControlPoint[1]));
2732
2731
  };
2733
- ;
2734
2732
  /**
2735
2733
  * Convert a 4-element array of vertices to a cubic bézier curve.
2736
2734
  *
@@ -2747,7 +2745,6 @@ var CubicBezierCurve = /** @class */ (function () {
2747
2745
  throw "Can only build from array with four elements.";
2748
2746
  return new CubicBezierCurve(arr[0], arr[1], arr[2], arr[3]);
2749
2747
  };
2750
- ;
2751
2748
  /** @constant {number} */
2752
2749
  CubicBezierCurve.START_POINT = 0;
2753
2750
  /** @constant {number} */
@@ -2870,7 +2867,8 @@ exports.Grid = Grid;
2870
2867
  * @modified 2020-07-28 Changed the `delete` key code from 8 to 46.
2871
2868
  * @modified 2020-10-04 Changed `window` to `globalThis`.
2872
2869
  * @modified 2020-10-04 Added extended JSDoc.
2873
- * @version 1.0.4
2870
+ * @modified 2022-02-02 Added the `destroy` method.
2871
+ * @version 1.1.0
2874
2872
  *
2875
2873
  * @file KeyHandler
2876
2874
  * @public
@@ -2903,7 +2901,7 @@ var KeyHandler = /** @class */ (function () {
2903
2901
  * @memberof KeyHandler
2904
2902
  * @param {HTMLElement} options.element (optional) The HTML element to listen on; if null then 'window' will be used.
2905
2903
  * @param {boolean} options.trackAll (optional) Set to true if you want to keep track of _all_ keys (keyStatus).
2906
- **/
2904
+ **/
2907
2905
  function KeyHandler(options) {
2908
2906
  this.downListeners = [];
2909
2907
  this.pressListeners = [];
@@ -2922,7 +2920,6 @@ var KeyHandler = /** @class */ (function () {
2922
2920
  // Install the listeners
2923
2921
  this.installListeners();
2924
2922
  }
2925
- ;
2926
2923
  /**
2927
2924
  * A helper function to fire key events from this KeyHandler.
2928
2925
  *
@@ -2940,7 +2937,6 @@ var KeyHandler = /** @class */ (function () {
2940
2937
  }
2941
2938
  return hasListener;
2942
2939
  };
2943
- ;
2944
2940
  /**
2945
2941
  * Internal function to fire a new keydown event to all listeners.
2946
2942
  * You should not call this function on your own unless you know what you do.
@@ -2956,10 +2952,9 @@ var KeyHandler = /** @class */ (function () {
2956
2952
  KeyHandler.prototype.fireDownEvent = function (e, handler) {
2957
2953
  if (handler.fireEvent(e, handler.downListeners) || handler.trackAllKeys) {
2958
2954
  // Down event has listeners. Update key state.
2959
- handler.keyStates[e.keyCode] = 'down';
2955
+ handler.keyStates[e.keyCode] = "down";
2960
2956
  }
2961
2957
  };
2962
- ;
2963
2958
  /**
2964
2959
  * Internal function to fire a new keypress event to all listeners.
2965
2960
  * You should not call this function on your own unless you know what you do.
@@ -2975,7 +2970,6 @@ var KeyHandler = /** @class */ (function () {
2975
2970
  KeyHandler.prototype.firePressEvent = function (e, handler) {
2976
2971
  handler.fireEvent(e, handler.pressListeners);
2977
2972
  };
2978
- ;
2979
2973
  /**
2980
2974
  * Internal function to fire a new keyup event to all listeners.
2981
2975
  * You should not call this function on your own unless you know what you do.
@@ -2994,20 +2988,18 @@ var KeyHandler = /** @class */ (function () {
2994
2988
  delete handler.keyStates[e.keyCode];
2995
2989
  }
2996
2990
  };
2997
- ;
2998
2991
  /**
2999
2992
  * Resolve the key/name code.
3000
2993
  */
3001
2994
  KeyHandler.key2code = function (key) {
3002
- if (typeof key == 'number')
2995
+ if (typeof key == "number")
3003
2996
  return key;
3004
- if (typeof key != 'string')
2997
+ if (typeof key != "string")
3005
2998
  throw "Unknown key name or key type (should be a string or integer): " + key;
3006
2999
  if (KeyHandler.KEY_CODES[key])
3007
3000
  return KeyHandler.KEY_CODES[key];
3008
3001
  throw "Unknown key (cannot resolve key code): " + key;
3009
3002
  };
3010
- ;
3011
3003
  /**
3012
3004
  * Install the required listeners into the initially passed element.
3013
3005
  *
@@ -3016,20 +3008,24 @@ var KeyHandler = /** @class */ (function () {
3016
3008
  */
3017
3009
  KeyHandler.prototype.installListeners = function () {
3018
3010
  var _self = this;
3019
- this.element.addEventListener('keydown', this._keyDownListener = function (e) { _self.fireDownEvent(e, _self); });
3020
- this.element.addEventListener('keypress', this._keyPressListener = function (e) { _self.firePressEvent(e, _self); });
3021
- this.element.addEventListener('keyup', this._keyUpListener = function (e) { _self.fireUpEvent(e, _self); });
3011
+ this.element.addEventListener("keydown", (this._keyDownListener = function (e) {
3012
+ _self.fireDownEvent(e, _self);
3013
+ }));
3014
+ this.element.addEventListener("keypress", (this._keyPressListener = function (e) {
3015
+ _self.firePressEvent(e, _self);
3016
+ }));
3017
+ this.element.addEventListener("keyup", (this._keyUpListener = function (e) {
3018
+ _self.fireUpEvent(e, _self);
3019
+ }));
3022
3020
  };
3023
- ;
3024
3021
  /**
3025
3022
  * Remove all installed event listeners from the underlying element.
3026
3023
  */
3027
3024
  KeyHandler.prototype.releaseListeners = function () {
3028
- this.element.removeEventListener('keydown', this._keyDownListener);
3029
- this.element.removeEventListener('keypress', this._keyPressListener);
3030
- this.element.removeEventListener('keyup', this._keyUpListener);
3025
+ this.element.removeEventListener("keydown", this._keyDownListener);
3026
+ this.element.removeEventListener("keypress", this._keyPressListener);
3027
+ this.element.removeEventListener("keyup", this._keyUpListener);
3031
3028
  };
3032
- ;
3033
3029
  /**
3034
3030
  * Listen for key down. This function allows chaining.
3035
3031
  *
@@ -3046,7 +3042,6 @@ var KeyHandler = /** @class */ (function () {
3046
3042
  this.downListeners.push({ key: key, keyCode: KeyHandler.key2code(key), listener: listener });
3047
3043
  return this;
3048
3044
  };
3049
- ;
3050
3045
  /**
3051
3046
  * Listen for key press.
3052
3047
  *
@@ -3063,7 +3058,6 @@ var KeyHandler = /** @class */ (function () {
3063
3058
  this.pressListeners.push({ key: key, keyCode: KeyHandler.key2code(key), listener: listener });
3064
3059
  return this;
3065
3060
  };
3066
- ;
3067
3061
  /**
3068
3062
  * Listen for key up.
3069
3063
  *
@@ -3080,22 +3074,30 @@ var KeyHandler = /** @class */ (function () {
3080
3074
  this.upListeners.push({ key: key, keyCode: KeyHandler.key2code(key), listener: listener });
3081
3075
  return this;
3082
3076
  };
3083
- ;
3084
3077
  /**
3085
3078
  * Check if a specific key is currently held pressed.
3086
3079
  *
3087
3080
  * @param {string|number} key - Any key identifier, key code or one from the KEY_CODES list.
3088
3081
  */
3089
3082
  KeyHandler.prototype.isDown = function (key) {
3090
- if (typeof key == 'number')
3083
+ if (typeof key == "number")
3091
3084
  return this.keyStates[key] ? true : false;
3092
3085
  else
3093
3086
  return this.keyStates[KeyHandler.key2code(key)] ? true : false;
3094
3087
  };
3088
+ /**
3089
+ * This function should invalidate any installed listeners and invalidate this object.
3090
+ * After calling this function the object might not hold valid data any more and
3091
+ * should not be used any more.
3092
+ */
3093
+ KeyHandler.prototype.destroy = function () {
3094
+ this.releaseListeners();
3095
+ };
3095
3096
  /**
3096
3097
  * Source:
3097
3098
  * https://keycode.info/
3098
3099
  */
3100
+ // prettier-ignore
3099
3101
  KeyHandler.KEY_CODES = {
3100
3102
  'break': 3,
3101
3103
  'backspace': 8,
@@ -3313,7 +3315,8 @@ exports.KeyHandler = KeyHandler;
3313
3315
  * @modified 2020-03-16 The Line.angle(Line) parameter is now optional. The baseline (x-axis) will be used if not defined.
3314
3316
  * @modified 2020-03-23 Ported to Typescript from JS.
3315
3317
  * @modified 2020-12-04 The `intersection` function returns undefined if both lines are parallel.
3316
- * @version 2.1.3
3318
+ * @modified 2022-02-02 Added the `destroy` method.
3319
+ * @version 2.2.0
3317
3320
  *
3318
3321
  * @file Line
3319
3322
  * @public
@@ -3377,45 +3380,19 @@ var Line = /** @class */ (function (_super) {
3377
3380
  return null;
3378
3381
  var a = this.a.y - line.a.y;
3379
3382
  var b = this.a.x - line.a.x;
3380
- var numerator1 = ((line.b.x - line.a.x) * a) - ((line.b.y - line.a.y) * b);
3381
- var numerator2 = ((this.b.x - this.a.x) * a) - ((this.b.y - this.a.y) * b);
3383
+ var numerator1 = (line.b.x - line.a.x) * a - (line.b.y - line.a.y) * b;
3384
+ var numerator2 = (this.b.x - this.a.x) * a - (this.b.y - this.a.y) * b;
3382
3385
  a = numerator1 / denominator; // NaN if parallel lines
3383
3386
  b = numerator2 / denominator;
3384
3387
  // Catch NaN?
3385
- var x = this.a.x + (a * (this.b.x - this.a.x));
3386
- var y = this.a.y + (a * (this.b.y - this.a.y));
3388
+ var x = this.a.x + a * (this.b.x - this.a.x);
3389
+ var y = this.a.y + a * (this.b.y - this.a.y);
3387
3390
  if (isNaN(a) || isNaN(x) || isNaN(y)) {
3388
3391
  return undefined;
3389
3392
  }
3390
3393
  // if we cast these lines infinitely in both directions, they intersect here:
3391
3394
  return new Vertex_1.Vertex(x, y);
3392
3395
  };
3393
- ;
3394
- /**
3395
- * Create an SVG representation of this line.
3396
- *
3397
- * @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
3398
- * @method toSVGString
3399
- * @param {options} p - A set of options, like the 'classname' to use
3400
- * for the line object.
3401
- * @return {string} The SVG string representing this line.
3402
- * @instance
3403
- * @memberof Line
3404
- **/
3405
- Line.prototype.toSVGString = function (options) {
3406
- options = options || {};
3407
- var buffer = [];
3408
- buffer.push('<line');
3409
- if (options.className)
3410
- buffer.push(' class="' + options.className + '"');
3411
- buffer.push(' x1="' + this.a.x + '"');
3412
- buffer.push(' y1="' + this.a.y + '"');
3413
- buffer.push(' x2="' + this.b.x + '"');
3414
- buffer.push(' y2="' + this.b.y + '"');
3415
- buffer.push(' />');
3416
- return buffer.join('');
3417
- };
3418
- ;
3419
3396
  return Line;
3420
3397
  }(VertTuple_1.VertTuple));
3421
3398
  exports.Line = Line;
@@ -3577,41 +3554,41 @@ var MouseHandler = /** @class */ (function () {
3577
3554
  // | drag offset, ...) to the callbacks.
3578
3555
  // +-------------------------------------------------
3579
3556
  var _self = this;
3580
- this.handlers['mousemove'] = function (e) {
3557
+ this.handlers["mousemove"] = function (e) {
3581
3558
  if (_self.listeners.mousemove)
3582
- _self.listeners.mousemove(_self.mkParams(e, 'mousemove'));
3559
+ _self.listeners.mousemove(_self.mkParams(e, "mousemove"));
3583
3560
  if (_self.mouseDragPos && _self.listeners.drag)
3584
- _self.listeners.drag(_self.mkParams(e, 'drag'));
3561
+ _self.listeners.drag(_self.mkParams(e, "drag"));
3585
3562
  if (_self.mouseDownPos)
3586
3563
  _self.mouseDragPos = _self.relPos(e);
3587
3564
  };
3588
- this.handlers['mouseup'] = function (e) {
3565
+ this.handlers["mouseup"] = function (e) {
3589
3566
  if (_self.listeners.mouseup)
3590
- _self.listeners.mouseup(_self.mkParams(e, 'mouseup'));
3567
+ _self.listeners.mouseup(_self.mkParams(e, "mouseup"));
3591
3568
  _self.mouseDragPos = undefined;
3592
3569
  _self.mouseDownPos = undefined;
3593
3570
  _self.mouseButton = -1;
3594
3571
  };
3595
- this.handlers['mousedown'] = function (e) {
3572
+ this.handlers["mousedown"] = function (e) {
3596
3573
  _self.mouseDragPos = _self.relPos(e);
3597
3574
  _self.mouseDownPos = _self.relPos(e);
3598
3575
  _self.mouseButton = e.button;
3599
3576
  if (_self.listeners.mousedown)
3600
- _self.listeners.mousedown(_self.mkParams(e, 'mousedown'));
3577
+ _self.listeners.mousedown(_self.mkParams(e, "mousedown"));
3601
3578
  };
3602
- this.handlers['click'] = function (e) {
3579
+ this.handlers["click"] = function (e) {
3603
3580
  if (_self.listeners.click)
3604
- _self.listeners.click(_self.mkParams(e, 'click'));
3581
+ _self.listeners.click(_self.mkParams(e, "click"));
3605
3582
  };
3606
- this.handlers['wheel'] = function (e) {
3583
+ this.handlers["wheel"] = function (e) {
3607
3584
  if (_self.listeners.wheel)
3608
- _self.listeners.wheel(_self.mkParams(e, 'wheel'));
3585
+ _self.listeners.wheel(_self.mkParams(e, "wheel"));
3609
3586
  };
3610
- this.element.addEventListener('mousemove', this.handlers['mousemove']);
3611
- this.element.addEventListener('mouseup', this.handlers['mouseup']);
3612
- this.element.addEventListener('mousedown', this.handlers['mousedown']);
3613
- this.element.addEventListener('click', this.handlers['click']);
3614
- this.element.addEventListener('wheel', this.handlers['wheel']);
3587
+ this.element.addEventListener("mousemove", this.handlers["mousemove"]);
3588
+ this.element.addEventListener("mouseup", this.handlers["mouseup"]);
3589
+ this.element.addEventListener("mousedown", this.handlers["mousedown"]);
3590
+ this.element.addEventListener("click", this.handlers["click"]);
3591
+ this.element.addEventListener("wheel", this.handlers["wheel"]);
3615
3592
  }
3616
3593
  /**
3617
3594
  * Get relative position from the given MouseEvent.
@@ -3624,11 +3601,8 @@ var MouseHandler = /** @class */ (function () {
3624
3601
  * @return {XYCoords} The relative mouse coordinates.
3625
3602
  */
3626
3603
  MouseHandler.prototype.relPos = function (e) {
3627
- return { x: e.offsetX,
3628
- y: e.offsetY
3629
- };
3604
+ return { x: e.offsetX, y: e.offsetY };
3630
3605
  };
3631
- ;
3632
3606
  /**
3633
3607
  * Build the extended event params.
3634
3608
  *
@@ -3654,8 +3628,8 @@ var MouseHandler = /** @class */ (function () {
3654
3628
  rightButton: this.mouseButton == 2,
3655
3629
  mouseDownPos: this.mouseDownPos,
3656
3630
  draggedFrom: this.mouseDragPos,
3657
- wasDragged: (this.mouseDownPos != null && (this.mouseDownPos.x != rel.x || this.mouseDownPos.y != rel.y)),
3658
- dragAmount: (this.mouseDownPos != null ? { x: rel.x - this.mouseDragPos.x, y: rel.y - this.mouseDragPos.y } : { x: 0, y: 0 })
3631
+ wasDragged: this.mouseDownPos != null && (this.mouseDownPos.x != rel.x || this.mouseDownPos.y != rel.y),
3632
+ dragAmount: this.mouseDownPos != null ? { x: rel.x - this.mouseDragPos.x, y: rel.y - this.mouseDragPos.y } : { x: 0, y: 0 }
3659
3633
  };
3660
3634
  return xEvent;
3661
3635
  };
@@ -3706,14 +3680,13 @@ var MouseHandler = /** @class */ (function () {
3706
3680
  */
3707
3681
  MouseHandler.prototype.drag = function (callback) {
3708
3682
  if (this.listeners.drag)
3709
- this.throwAlreadyInstalled('drag');
3683
+ this.throwAlreadyInstalled("drag");
3710
3684
  this.listeners.drag = callback;
3711
- this.listenFor('mousedown');
3712
- this.listenFor('mousemove');
3713
- this.listenFor('mouseup');
3685
+ this.listenFor("mousedown");
3686
+ this.listenFor("mousemove");
3687
+ this.listenFor("mouseup");
3714
3688
  return this;
3715
3689
  };
3716
- ;
3717
3690
  /**
3718
3691
  * Installer function to listen for a specific event: mouse-move.
3719
3692
  * Pass your callbacks here.
@@ -3728,12 +3701,11 @@ var MouseHandler = /** @class */ (function () {
3728
3701
  */
3729
3702
  MouseHandler.prototype.move = function (callback) {
3730
3703
  if (this.listeners.mousemove)
3731
- this.throwAlreadyInstalled('mousemove');
3732
- this.listenFor('mousemove');
3704
+ this.throwAlreadyInstalled("mousemove");
3705
+ this.listenFor("mousemove");
3733
3706
  this.listeners.mousemove = callback;
3734
3707
  return this;
3735
3708
  };
3736
- ;
3737
3709
  /**
3738
3710
  * Installer function to listen for a specific event: mouse-up.
3739
3711
  * Pass your callbacks here.
@@ -3748,12 +3720,11 @@ var MouseHandler = /** @class */ (function () {
3748
3720
  */
3749
3721
  MouseHandler.prototype.up = function (callback) {
3750
3722
  if (this.listeners.mouseup)
3751
- this.throwAlreadyInstalled('mouseup');
3752
- this.listenFor('mouseup');
3723
+ this.throwAlreadyInstalled("mouseup");
3724
+ this.listenFor("mouseup");
3753
3725
  this.listeners.mouseup = callback;
3754
3726
  return this;
3755
3727
  };
3756
- ;
3757
3728
  /**
3758
3729
  * Installer function to listen for a specific event: mouse-down.
3759
3730
  * Pass your callbacks here.
@@ -3768,12 +3739,11 @@ var MouseHandler = /** @class */ (function () {
3768
3739
  */
3769
3740
  MouseHandler.prototype.down = function (callback) {
3770
3741
  if (this.listeners.mousedown)
3771
- this.throwAlreadyInstalled('mousedown');
3772
- this.listenFor('mousedown');
3742
+ this.throwAlreadyInstalled("mousedown");
3743
+ this.listenFor("mousedown");
3773
3744
  this.listeners.mousedown = callback;
3774
3745
  return this;
3775
3746
  };
3776
- ;
3777
3747
  /**
3778
3748
  * Installer function to listen for a specific event: mouse-click.
3779
3749
  * Pass your callbacks here.
@@ -3788,12 +3758,11 @@ var MouseHandler = /** @class */ (function () {
3788
3758
  */
3789
3759
  MouseHandler.prototype.click = function (callback) {
3790
3760
  if (this.listeners.click)
3791
- this.throwAlreadyInstalled('click');
3792
- this.listenFor('click');
3761
+ this.throwAlreadyInstalled("click");
3762
+ this.listenFor("click");
3793
3763
  this.listeners.click = callback;
3794
3764
  return this;
3795
3765
  };
3796
- ;
3797
3766
  /**
3798
3767
  * Installer function to listen for a specific event: mouse-wheel.
3799
3768
  * Pass your callbacks here.
@@ -3808,12 +3777,11 @@ var MouseHandler = /** @class */ (function () {
3808
3777
  */
3809
3778
  MouseHandler.prototype.wheel = function (callback) {
3810
3779
  if (this.listeners.wheel)
3811
- this.throwAlreadyInstalled('wheel');
3812
- this.listenFor('wheel');
3780
+ this.throwAlreadyInstalled("wheel");
3781
+ this.listenFor("wheel");
3813
3782
  this.listeners.wheel = callback;
3814
3783
  return this;
3815
3784
  };
3816
- ;
3817
3785
  /**
3818
3786
  * An internal function to throw events.
3819
3787
  *
@@ -3827,7 +3795,6 @@ var MouseHandler = /** @class */ (function () {
3827
3795
  MouseHandler.prototype.throwAlreadyInstalled = function (name) {
3828
3796
  throw "This MouseHandler already has a '" + name + "' callback. To keep the code simple there is only room for one.";
3829
3797
  };
3830
- ;
3831
3798
  /**
3832
3799
  * Call this when your work is done.
3833
3800
  *
@@ -3840,16 +3807,16 @@ var MouseHandler = /** @class */ (function () {
3840
3807
  * @return {void}
3841
3808
  */
3842
3809
  MouseHandler.prototype.destroy = function () {
3843
- this.unlistenFor('mousedown');
3844
- this.unlistenFor('mousemove');
3845
- this.unlistenFor('moseup');
3846
- this.unlistenFor('click');
3847
- this.unlistenFor('wheel');
3848
- this.element.removeEventListener('mousemove', this.handlers['mousemove']);
3849
- this.element.removeEventListener('mouseup', this.handlers['mousedown']);
3850
- this.element.removeEventListener('mousedown', this.handlers['mousedown']);
3851
- this.element.removeEventListener('click', this.handlers['click']);
3852
- this.element.removeEventListener('wheel', this.handlers['wheel']);
3810
+ this.unlistenFor("mousedown");
3811
+ this.unlistenFor("mousemove");
3812
+ this.unlistenFor("moseup");
3813
+ this.unlistenFor("click");
3814
+ this.unlistenFor("wheel");
3815
+ this.element.removeEventListener("mousemove", this.handlers["mousemove"]);
3816
+ this.element.removeEventListener("mouseup", this.handlers["mousedown"]);
3817
+ this.element.removeEventListener("mousedown", this.handlers["mousedown"]);
3818
+ this.element.removeEventListener("click", this.handlers["click"]);
3819
+ this.element.removeEventListener("wheel", this.handlers["wheel"]);
3853
3820
  };
3854
3821
  return MouseHandler;
3855
3822
  }());
@@ -3868,7 +3835,9 @@ exports.MouseHandler = MouseHandler;
3868
3835
  * @modified 2019-03-23 Added JSDoc tags.
3869
3836
  * @modified 2020-03-25 Ported this class from vanilla-JS to Typescript.
3870
3837
  * @modified 2021-01-20 Added UID.
3871
- * @version 1.1.0
3838
+ * @modified 2022-02-02 Added the `destroy` method.
3839
+ * @modified 2022-02-02 Cleared the `PBImage.toSVGString` function (deprecated). Use `drawutilssvg` instead.
3840
+ * @version 1.2.0
3872
3841
  *
3873
3842
  * @file PBImage
3874
3843
  * @fileoverview As native Image objects have only a position and with
@@ -3906,22 +3875,16 @@ var PBImage = /** @class */ (function () {
3906
3875
  this.upperLeft = upperLeft;
3907
3876
  this.lowerRight = lowerRight;
3908
3877
  }
3909
- ;
3910
3878
  /**
3911
- * Convert this vertex to SVG code.
3912
- *
3913
- * @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
3914
- * @method toSVGString
3915
- * @param {object=} options - An optional set of options, like 'className'.
3916
- * @return {string} A string representing the SVG code for this vertex.
3917
- * @instance
3918
- * @memberof PBImage
3919
- **/
3920
- PBImage.prototype.toSVGString = function (options) {
3921
- console.warn("PBImage is not yet SVG serializable. Returning empty SVG string.");
3922
- return "";
3879
+ * This function should invalidate any installed listeners and invalidate this object.
3880
+ * After calling this function the object might not hold valid data any more and
3881
+ * should not be used.
3882
+ */
3883
+ PBImage.prototype.destroy = function () {
3884
+ this.upperLeft.destroy();
3885
+ this.lowerRight.destroy();
3886
+ this.isDestroyed = true;
3923
3887
  };
3924
- ;
3925
3888
  return PBImage;
3926
3889
  }());
3927
3890
  exports.PBImage = PBImage;
@@ -3936,7 +3899,8 @@ exports.PBImage = PBImage;
3936
3899
  /**
3937
3900
  * @author Ikaros Kappler
3938
3901
  * @date 2021-11-16
3939
- * @version 1.0.0
3902
+ * @modified 2022-02-02 Added the `destroy` method.
3903
+ * @version 1.1.0
3940
3904
  **/
3941
3905
  Object.defineProperty(exports, "__esModule", ({ value: true }));
3942
3906
  exports.PBText = void 0;
@@ -3981,18 +3945,13 @@ var PBText = /** @class */ (function () {
3981
3945
  this.rotation = options.rotation;
3982
3946
  }
3983
3947
  /**
3984
- * Create an SVG representation of this circle.
3985
- *
3986
- * @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
3987
- * @method toSVGString
3988
- * @param {object=} options - An optional set of options, like 'className'.
3989
- * @return {string} A string representing the SVG code for this vertex.
3990
- * @instance
3991
- * @memberof Circle
3948
+ * This function should invalidate any installed listeners and invalidate this object.
3949
+ * After calling this function the object might not hold valid data any more and
3950
+ * should not be used.
3992
3951
  */
3993
- PBText.prototype.toSVGString = function (options) {
3994
- console.warn("[PBText.toSVGString()] This function is not implemented as it defines a deprecated method. Use the 'drawutilssvg.text()' method instead.");
3995
- return "";
3952
+ PBText.prototype.destroy = function () {
3953
+ this.anchor.destroy();
3954
+ this.isDestroyed = true;
3996
3955
  };
3997
3956
  return PBText;
3998
3957
  }()); // END class
@@ -4714,7 +4673,7 @@ var PlotBoilerplate = /** @class */ (function () {
4714
4673
  }
4715
4674
  }
4716
4675
  for (var i = 0; i < this.drawables.length; i++) {
4717
- if (this.drawables[i] === drawable) {
4676
+ if (this.drawables[i] === drawable || this.drawables[i].uid === drawable.uid) {
4718
4677
  this.drawables.splice(i, 1);
4719
4678
  if (removeWithVertices) {
4720
4679
  // Check if some listeners need to be removed
@@ -4826,8 +4785,9 @@ var PlotBoilerplate = /** @class */ (function () {
4826
4785
  **/
4827
4786
  PlotBoilerplate.prototype.getVertexNear = function (pixelPosition, pixelTolerance) {
4828
4787
  var p = this.locatePointNear(this.transformMousePosition(pixelPosition.x, pixelPosition.y), pixelTolerance / Math.min(this.config.cssScaleX, this.config.cssScaleY));
4829
- if (p && p.typeName == "vertex")
4788
+ if (p && p.typeName == "vertex") {
4830
4789
  return this.vertices[p.vindex];
4790
+ }
4831
4791
  return undefined;
4832
4792
  };
4833
4793
  /**
@@ -6127,7 +6087,12 @@ __webpack_unused_export__ = PlotBoilerplate;
6127
6087
  * @modified 2021-01-29 Added the `isClockwise` function.
6128
6088
  * @modified 2021-01-29 Added the `area` function.
6129
6089
  * @modified 2021-01-29 Changed the param type for `containsVert` from Vertex to XYCoords.
6130
- * @version 1.7.0
6090
+ * @modified 2021-12-14 Added the `perimeter()` function.
6091
+ * @modified 2021-12-16 Added the `getEvenDistributionPolygon()` function.
6092
+ * @modified 2022-02-02 Added the `destroy` method.
6093
+ * @modified 2022-02-02 Cleared the `Polygon.toSVGString` function (deprecated). Use `drawutilssvg` instead.
6094
+ * @modified 2022-03-08 Added the `Polygon.clone()` function.
6095
+ * @version 1.10.0
6131
6096
  *
6132
6097
  * @file Polygon
6133
6098
  * @public
@@ -6164,12 +6129,11 @@ var Polygon = /** @class */ (function () {
6164
6129
  **/
6165
6130
  this.className = "Polygon";
6166
6131
  this.uid = UIDGenerator_1.UIDGenerator.next();
6167
- if (typeof vertices == 'undefined')
6132
+ if (typeof vertices == "undefined")
6168
6133
  vertices = [];
6169
6134
  this.vertices = vertices;
6170
6135
  this.isOpen = isOpen;
6171
6136
  }
6172
- ;
6173
6137
  /**
6174
6138
  * Add a vertex to the end of the `vertices` array.
6175
6139
  *
@@ -6181,7 +6145,6 @@ var Polygon = /** @class */ (function () {
6181
6145
  Polygon.prototype.addVertex = function (vert) {
6182
6146
  this.vertices.push(vert);
6183
6147
  };
6184
- ;
6185
6148
  /**
6186
6149
  * Get the polygon vertex at the given position (index).
6187
6150
  *
@@ -6204,7 +6167,6 @@ var Polygon = /** @class */ (function () {
6204
6167
  else
6205
6168
  return this.vertices[index % this.vertices.length];
6206
6169
  };
6207
- ;
6208
6170
  /**
6209
6171
  * Move the polygon's vertices by the given amount.
6210
6172
  *
@@ -6214,13 +6176,12 @@ var Polygon = /** @class */ (function () {
6214
6176
  * @memberof Polygon
6215
6177
  * @return {Polygon} this for chaining
6216
6178
  **/
6217
- Polygon.prototype.move = function (vert) {
6179
+ Polygon.prototype.move = function (amount) {
6218
6180
  for (var i in this.vertices) {
6219
- this.vertices[i].add(vert);
6181
+ this.vertices[i].add(amount);
6220
6182
  }
6221
6183
  return this;
6222
6184
  };
6223
- ;
6224
6185
  /**
6225
6186
  * Check if the given vertex is inside this polygon.<br>
6226
6187
  * <br>
@@ -6240,14 +6201,12 @@ var Polygon = /** @class */ (function () {
6240
6201
  for (var i = 0, j = this.vertices.length - 1; i < this.vertices.length; j = i++) {
6241
6202
  var xi = this.vertices[i].x, yi = this.vertices[i].y;
6242
6203
  var xj = this.vertices[j].x, yj = this.vertices[j].y;
6243
- var intersect = ((yi > vert.y) != (yj > vert.y))
6244
- && (vert.x < (xj - xi) * (vert.y - yi) / (yj - yi) + xi);
6204
+ var intersect = yi > vert.y != yj > vert.y && vert.x < ((xj - xi) * (vert.y - yi)) / (yj - yi) + xi;
6245
6205
  if (intersect)
6246
6206
  inside = !inside;
6247
6207
  }
6248
6208
  return inside;
6249
6209
  };
6250
- ;
6251
6210
  /**
6252
6211
  * Calculate the area of the given polygon (unsigned).
6253
6212
  *
@@ -6261,7 +6220,6 @@ var Polygon = /** @class */ (function () {
6261
6220
  Polygon.prototype.area = function () {
6262
6221
  return Polygon.utils.area(this.vertices);
6263
6222
  };
6264
- ;
6265
6223
  /**
6266
6224
  * Calulate the signed polyon area by interpreting the polygon as a matrix
6267
6225
  * and calculating its determinant.
@@ -6274,7 +6232,6 @@ var Polygon = /** @class */ (function () {
6274
6232
  Polygon.prototype.signedArea = function () {
6275
6233
  return Polygon.utils.signedArea(this.vertices);
6276
6234
  };
6277
- ;
6278
6235
  /**
6279
6236
  * Get the winding order of this polgon: clockwise or counterclockwise.
6280
6237
  *
@@ -6286,7 +6243,28 @@ var Polygon = /** @class */ (function () {
6286
6243
  Polygon.prototype.isClockwise = function () {
6287
6244
  return Polygon.utils.signedArea(this.vertices) < 0;
6288
6245
  };
6289
- ;
6246
+ /**
6247
+ * Get the perimeter of this polygon.
6248
+ * The perimeter is the absolute length of the outline.
6249
+ *
6250
+ * If this polygon is open then the last segment (connecting the first and the
6251
+ * last vertex) will be skipped.
6252
+ *
6253
+ * @method perimeter
6254
+ * @instance
6255
+ * @memberof Polygon
6256
+ * @return {number}
6257
+ */
6258
+ Polygon.prototype.perimeter = function () {
6259
+ var length = 0;
6260
+ for (var i = 1; i < this.vertices.length; i++) {
6261
+ length += this.vertices[i - 1].distance(this.vertices[i]);
6262
+ }
6263
+ if (!this.isOpen && this.vertices.length > 1) {
6264
+ length += this.vertices[0].distance(this.vertices[this.vertices.length - 1]);
6265
+ }
6266
+ return length;
6267
+ };
6290
6268
  /**
6291
6269
  * Scale the polygon relative to the given center.
6292
6270
  *
@@ -6299,14 +6277,13 @@ var Polygon = /** @class */ (function () {
6299
6277
  **/
6300
6278
  Polygon.prototype.scale = function (factor, center) {
6301
6279
  for (var i in this.vertices) {
6302
- if (typeof this.vertices[i].scale == 'function')
6280
+ if (typeof this.vertices[i].scale == "function")
6303
6281
  this.vertices[i].scale(factor, center);
6304
6282
  else
6305
- console.log('There seems to be a null vertex!', this.vertices[i]);
6283
+ console.log("There seems to be a null vertex!", this.vertices[i]);
6306
6284
  }
6307
6285
  return this;
6308
6286
  };
6309
- ;
6310
6287
  /**
6311
6288
  * Rotate the polygon around the given center.
6312
6289
  *
@@ -6323,7 +6300,52 @@ var Polygon = /** @class */ (function () {
6323
6300
  }
6324
6301
  return this;
6325
6302
  };
6326
- ;
6303
+ /**
6304
+ * Convert this polygon into a new polygon with n evenly distributed vertices.
6305
+ *
6306
+ * @param {number} pointCount - Must not be negative.
6307
+ */
6308
+ Polygon.prototype.getEvenDistributionPolygon = function (pointCount) {
6309
+ if (pointCount <= 0) {
6310
+ throw new Error("pointCount must be larger than zero; is " + pointCount + ".");
6311
+ }
6312
+ var result = new Polygon([], this.isOpen);
6313
+ if (this.vertices.length === 0) {
6314
+ return result;
6315
+ }
6316
+ // Fetch and add the start point from the source polygon
6317
+ var polygonPoint = new Vertex_1.Vertex(this.vertices[0]);
6318
+ result.vertices.push(polygonPoint);
6319
+ if (this.vertices.length === 1) {
6320
+ return result;
6321
+ }
6322
+ var perimeter = this.perimeter();
6323
+ var stepSize = perimeter / pointCount;
6324
+ var n = this.vertices.length;
6325
+ var polygonIndex = 1;
6326
+ var nextPolygonPoint = new Vertex_1.Vertex(this.vertices[1]);
6327
+ var segmentLength = polygonPoint.distance(nextPolygonPoint);
6328
+ var loopMax = this.isOpen ? n : n + 1;
6329
+ var curSegmentU = stepSize;
6330
+ var i = 1;
6331
+ while (i < pointCount && polygonIndex < loopMax) {
6332
+ // Check if next eq point is inside this segment
6333
+ if (curSegmentU < segmentLength) {
6334
+ var newPoint = polygonPoint.clone().lerpAbs(nextPolygonPoint, curSegmentU);
6335
+ result.vertices.push(newPoint);
6336
+ curSegmentU += stepSize;
6337
+ i++;
6338
+ }
6339
+ else {
6340
+ polygonIndex++;
6341
+ polygonPoint = nextPolygonPoint;
6342
+ nextPolygonPoint = new Vertex_1.Vertex(this.vertices[polygonIndex % n]);
6343
+ curSegmentU = curSegmentU - segmentLength;
6344
+ segmentLength = polygonPoint.distance(nextPolygonPoint);
6345
+ }
6346
+ }
6347
+ return result;
6348
+ };
6327
6349
  /**
6328
6350
  * Get the bounding box (bounds) of this polygon.
6329
6351
  *
@@ -6335,7 +6357,14 @@ var Polygon = /** @class */ (function () {
6335
6357
  Polygon.prototype.getBounds = function () {
6336
6358
  return Bounds_1.Bounds.computeFromVertices(this.vertices);
6337
6359
  };
6338
- ;
6360
+ /**
6361
+ * Create a deep copy of this polygon.
6362
+ *
6363
+ * @return {Polygon} The cloned polygon.
6364
+ */
6365
+ Polygon.prototype.clone = function () {
6366
+ return new Polygon(this.vertices.map(function (vert) { return vert.clone(); }), this.isOpen);
6367
+ };
6339
6368
  /**
6340
6369
  * Convert this polygon to a sequence of quadratic Bézier curves.<br>
6341
6370
  * <br>
@@ -6367,7 +6396,6 @@ var Polygon = /** @class */ (function () {
6367
6396
  }
6368
6397
  return qbezier;
6369
6398
  };
6370
- ;
6371
6399
  /**
6372
6400
  * Convert this polygon to a quadratic bezier curve, represented as an SVG data string.
6373
6401
  *
@@ -6380,13 +6408,12 @@ var Polygon = /** @class */ (function () {
6380
6408
  var qdata = this.toQuadraticBezierData();
6381
6409
  if (qdata.length == 0)
6382
6410
  return "";
6383
- var buffer = ['M ' + qdata[0].x + ' ' + qdata[0].y];
6411
+ var buffer = ["M " + qdata[0].x + " " + qdata[0].y];
6384
6412
  for (var i = 1; i < qdata.length; i += 2) {
6385
- buffer.push('Q ' + qdata[i].x + ' ' + qdata[i].y + ', ' + qdata[i + 1].x + ' ' + qdata[i + 1].y);
6413
+ buffer.push("Q " + qdata[i].x + " " + qdata[i].y + ", " + qdata[i + 1].x + " " + qdata[i + 1].y);
6386
6414
  }
6387
- return buffer.join(' ');
6415
+ return buffer.join(" ");
6388
6416
  };
6389
- ;
6390
6417
  /**
6391
6418
  * Convert this polygon to a sequence of cubic Bézier curves.<br>
6392
6419
  * <br>
@@ -6403,7 +6430,7 @@ var Polygon = /** @class */ (function () {
6403
6430
  * @memberof Polygon
6404
6431
  **/
6405
6432
  Polygon.prototype.toCubicBezierData = function (threshold) {
6406
- if (typeof threshold == 'undefined')
6433
+ if (typeof threshold == "undefined")
6407
6434
  threshold = 1.0;
6408
6435
  if (this.vertices.length < 3)
6409
6436
  return [];
@@ -6427,7 +6454,6 @@ var Polygon = /** @class */ (function () {
6427
6454
  }
6428
6455
  return cbezier;
6429
6456
  };
6430
- ;
6431
6457
  /**
6432
6458
  * Convert this polygon to a cubic bezier curve, represented as an SVG data string.
6433
6459
  *
@@ -6440,13 +6466,23 @@ var Polygon = /** @class */ (function () {
6440
6466
  var qdata = this.toCubicBezierData(threshold);
6441
6467
  if (qdata.length == 0)
6442
6468
  return "";
6443
- var buffer = ['M ' + qdata[0].x + ' ' + qdata[0].y];
6469
+ var buffer = ["M " + qdata[0].x + " " + qdata[0].y];
6444
6470
  for (var i = 1; i < qdata.length; i += 3) {
6445
- buffer.push('C ' + qdata[i].x + ' ' + qdata[i].y + ', ' + qdata[i + 1].x + ' ' + qdata[i + 1].y + ', ' + qdata[i + 2].x + ' ' + qdata[i + 2].y);
6446
- }
6447
- return buffer.join(' ');
6471
+ buffer.push("C " +
6472
+ qdata[i].x +
6473
+ " " +
6474
+ qdata[i].y +
6475
+ ", " +
6476
+ qdata[i + 1].x +
6477
+ " " +
6478
+ qdata[i + 1].y +
6479
+ ", " +
6480
+ qdata[i + 2].x +
6481
+ " " +
6482
+ qdata[i + 2].y);
6483
+ }
6484
+ return buffer.join(" ");
6448
6485
  };
6449
- ;
6450
6486
  /**
6451
6487
  * Convert this polygon to a cubic bezier path instance.
6452
6488
  *
@@ -6465,43 +6501,17 @@ var Polygon = /** @class */ (function () {
6465
6501
  }
6466
6502
  return BezierPath_1.BezierPath.fromArray(pathdata);
6467
6503
  };
6468
- ;
6469
6504
  /**
6470
- * Create an SVG representation of this polygon.
6471
- *
6472
- * @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
6473
- * @method toSVGString
6474
- * @param {object=} options - An optional set of options, like 'className'.
6475
- * @return {string} The SVG string.
6476
- * @instance
6477
- * @memberof Polygon
6478
- **/
6479
- Polygon.prototype.toSVGString = function (options) {
6480
- options = options || {};
6481
- var buffer = [];
6482
- buffer.push('<path');
6483
- if (options.className)
6484
- buffer.push(' class="' + options.className + '"');
6485
- buffer.push(' d="');
6486
- if (this.vertices.length > 0) {
6487
- buffer.push('M ');
6488
- buffer.push(this.vertices[0].x.toString());
6489
- buffer.push(' ');
6490
- buffer.push(this.vertices[0].y.toString());
6491
- for (var i = 1; i < this.vertices.length; i++) {
6492
- buffer.push(' L ');
6493
- buffer.push(this.vertices[i].x.toString());
6494
- buffer.push(' ');
6495
- buffer.push(this.vertices[i].y.toString());
6496
- }
6497
- if (!this.isOpen) {
6498
- buffer.push(' Z');
6499
- }
6505
+ * This function should invalidate any installed listeners and invalidate this object.
6506
+ * After calling this function the object might not hold valid data any more and
6507
+ * should not be used.
6508
+ */
6509
+ Polygon.prototype.destroy = function () {
6510
+ for (var i = 0; i < this.vertices.length; i++) {
6511
+ this.vertices[i].destroy();
6500
6512
  }
6501
- buffer.push('" />');
6502
- return buffer.join('');
6513
+ this.isDestroyed = true;
6503
6514
  };
6504
- ;
6505
6515
  Polygon.utils = {
6506
6516
  /**
6507
6517
  * Calculate the area of the given polygon (unsigned).
@@ -6520,8 +6530,8 @@ var Polygon = /** @class */ (function () {
6520
6530
  var addY = vertices[(i + 1) % l].y;
6521
6531
  var subX = vertices[(i + 1) % l].x;
6522
6532
  var subY = vertices[i].y;
6523
- total += (addX * addY * 0.5);
6524
- total -= (subX * subY * 0.5);
6533
+ total += addX * addY * 0.5;
6534
+ total -= subX * subY * 0.5;
6525
6535
  }
6526
6536
  return Math.abs(total);
6527
6537
  },
@@ -6574,7 +6584,9 @@ exports.Polygon = Polygon;
6574
6584
  * @modified 2020-12-28 Added the `getArea` function.
6575
6585
  * @modified 2021-01-20 Added UID.
6576
6586
  * @modified 2021-01-22 Always updating circumcircle when retieving it.
6577
- * @version 2.5.1
6587
+ * @modified 2022-02-02 Added the `destroy` method.
6588
+ * @modified 2022-02-02 Cleared the `Triangle.toSVGString` function (deprecated). Use `drawutilssvg` instead.
6589
+ * @version 2.6.0
6578
6590
  *
6579
6591
  * @file Triangle
6580
6592
  * @fileoverview A simple triangle class: three vertices.
@@ -6644,7 +6656,6 @@ var Triangle = /** @class */ (function () {
6644
6656
  throw "Cannot create triangle from array with less than three vertices (" + arr.length + ")";
6645
6657
  return new Triangle(arr[0], arr[1], arr[2]);
6646
6658
  };
6647
- ;
6648
6659
  /**
6649
6660
  * Get the area of this triangle. The returned area is never negative.
6650
6661
  *
@@ -6660,7 +6671,6 @@ var Triangle = /** @class */ (function () {
6660
6671
  Triangle.prototype.getArea = function () {
6661
6672
  return Math.abs(Triangle.utils.signedArea(this.a.x, this.a.y, this.b.x, this.b.y, this.c.x, this.c.y));
6662
6673
  };
6663
- ;
6664
6674
  /**
6665
6675
  * Get the centroid of this triangle.
6666
6676
  *
@@ -6674,7 +6684,6 @@ var Triangle = /** @class */ (function () {
6674
6684
  Triangle.prototype.getCentroid = function () {
6675
6685
  return new Vertex_1.Vertex((this.a.x + this.b.x + this.c.x) / 3, (this.a.y + this.b.y + this.c.y) / 3);
6676
6686
  };
6677
- ;
6678
6687
  /**
6679
6688
  * Scale the triangle towards its centroid.
6680
6689
  *
@@ -6691,7 +6700,6 @@ var Triangle = /** @class */ (function () {
6691
6700
  this.c.scale(factor, centroid);
6692
6701
  return this;
6693
6702
  };
6694
- ;
6695
6703
  /**
6696
6704
  * Get the circumcircle of this triangle.
6697
6705
  *
@@ -6708,11 +6716,10 @@ var Triangle = /** @class */ (function () {
6708
6716
  * @memberof Triangle
6709
6717
  */
6710
6718
  Triangle.prototype.getCircumcircle = function () {
6711
- // if( !this.center || !this.radius )
6719
+ // if( !this.center || !this.radius )
6712
6720
  this.calcCircumcircle();
6713
6721
  return new Circle_1.Circle(this.center.clone(), this.radius);
6714
6722
  };
6715
- ;
6716
6723
  /**
6717
6724
  * Check if this triangle and the passed triangle share an
6718
6725
  * adjacent edge.
@@ -6732,7 +6739,6 @@ var Triangle = /** @class */ (function () {
6732
6739
  var c = this.c.equals(tri.a) || this.c.equals(tri.b) || this.c.equals(tri.c);
6733
6740
  return (a && b) || (a && c) || (b && c);
6734
6741
  };
6735
- ;
6736
6742
  /**
6737
6743
  * Get that vertex of this triangle (a,b,c) that is not vert1 nor vert2 of
6738
6744
  * the passed two.
@@ -6745,14 +6751,13 @@ var Triangle = /** @class */ (function () {
6745
6751
  * @memberof Triangle
6746
6752
  */
6747
6753
  Triangle.prototype.getThirdVertex = function (vert1, vert2) {
6748
- if (this.a.equals(vert1) && this.b.equals(vert2) || this.a.equals(vert2) && this.b.equals(vert1))
6754
+ if ((this.a.equals(vert1) && this.b.equals(vert2)) || (this.a.equals(vert2) && this.b.equals(vert1)))
6749
6755
  return this.c;
6750
- if (this.b.equals(vert1) && this.c.equals(vert2) || this.b.equals(vert2) && this.c.equals(vert1))
6756
+ if ((this.b.equals(vert1) && this.c.equals(vert2)) || (this.b.equals(vert2) && this.c.equals(vert1)))
6751
6757
  return this.a;
6752
6758
  //if( this.c.equals(vert1) && this.a.equals(vert2) || this.c.equals(vert2) && this.a.equals(vert1) )
6753
6759
  return this.b;
6754
6760
  };
6755
- ;
6756
6761
  /**
6757
6762
  * Re-compute the circumcircle of this triangle (if the vertices
6758
6763
  * have changed).
@@ -6792,8 +6797,7 @@ var Triangle = /** @class */ (function () {
6792
6797
  }
6793
6798
  this.radius_squared = dx * dx + dy * dy;
6794
6799
  this.radius = Math.sqrt(this.radius_squared);
6795
- };
6796
- ; // END calcCircumcircle
6800
+ }; // END calcCircumcircle
6797
6801
  /**
6798
6802
  * Check if the passed vertex is inside this triangle's
6799
6803
  * circumcircle.
@@ -6808,9 +6812,8 @@ var Triangle = /** @class */ (function () {
6808
6812
  var dx = this.center.x - v.x;
6809
6813
  var dy = this.center.y - v.y;
6810
6814
  var dist_squared = dx * dx + dy * dy;
6811
- return (dist_squared <= this.radius_squared);
6815
+ return dist_squared <= this.radius_squared;
6812
6816
  };
6813
- ;
6814
6817
  /**
6815
6818
  * Get the rectangular bounds for this triangle.
6816
6819
  *
@@ -6822,7 +6825,6 @@ var Triangle = /** @class */ (function () {
6822
6825
  Triangle.prototype.bounds = function () {
6823
6826
  return new Bounds_1.Bounds(new Vertex_1.Vertex(Triangle.utils.min3(this.a.x, this.b.x, this.c.x), Triangle.utils.min3(this.a.y, this.b.y, this.c.y)), new Vertex_1.Vertex(Triangle.utils.max3(this.a.x, this.b.x, this.c.x), Triangle.utils.max3(this.a.y, this.b.y, this.c.y)));
6824
6827
  };
6825
- ;
6826
6828
  /**
6827
6829
  * Convert this triangle to a polygon instance.
6828
6830
  *
@@ -6836,7 +6838,6 @@ var Triangle = /** @class */ (function () {
6836
6838
  Triangle.prototype.toPolygon = function () {
6837
6839
  return new Polygon_1.Polygon([this.a, this.b, this.c]);
6838
6840
  };
6839
- ;
6840
6841
  /**
6841
6842
  * Get the determinant of this triangle.
6842
6843
  *
@@ -6849,7 +6850,6 @@ var Triangle = /** @class */ (function () {
6849
6850
  // (b.y - a.y)*(c.x - b.x) - (c.y - b.y)*(b.x - a.x);
6850
6851
  return (this.b.y - this.a.y) * (this.c.x - this.b.x) - (this.c.y - this.b.y) * (this.b.x - this.a.x);
6851
6852
  };
6852
- ;
6853
6853
  /**
6854
6854
  * Checks if the passed vertex (p) is inside this triangle.
6855
6855
  *
@@ -6864,7 +6864,6 @@ var Triangle = /** @class */ (function () {
6864
6864
  Triangle.prototype.containsPoint = function (p) {
6865
6865
  return Triangle.utils.pointIsInTriangle(p.x, p.y, this.a.x, this.a.y, this.b.x, this.b.y, this.c.x, this.c.y);
6866
6866
  };
6867
- ;
6868
6867
  /**
6869
6868
  * Get that inner triangle which defines the maximal incircle.
6870
6869
  *
@@ -6883,7 +6882,6 @@ var Triangle = /** @class */ (function () {
6883
6882
  var circleIntersC = lineC.getClosestPoint(intersection);
6884
6883
  return new Triangle(circleIntersA, circleIntersB, circleIntersC);
6885
6884
  };
6886
- ;
6887
6885
  /**
6888
6886
  * Get the incircle of this triangle. That is the circle that touches each side
6889
6887
  * of this triangle in exactly one point.
@@ -6895,7 +6893,6 @@ var Triangle = /** @class */ (function () {
6895
6893
  Triangle.prototype.getIncircle = function () {
6896
6894
  return this.getIncircularTriangle().getCircumcircle();
6897
6895
  };
6898
- ;
6899
6896
  /**
6900
6897
  * Get the incenter of this triangle (which is the center of the circumcircle).
6901
6898
  *
@@ -6909,7 +6906,6 @@ var Triangle = /** @class */ (function () {
6909
6906
  this.calcCircumcircle();
6910
6907
  return this.center.clone();
6911
6908
  };
6912
- ;
6913
6909
  /**
6914
6910
  * Converts this triangle into a human-readable string.
6915
6911
  *
@@ -6919,46 +6915,19 @@ var Triangle = /** @class */ (function () {
6919
6915
  * @memberof Triangle
6920
6916
  */
6921
6917
  Triangle.prototype.toString = function () {
6922
- return '{ a : ' + this.a.toString() + ', b : ' + this.b.toString() + ', c : ' + this.c.toString() + '}';
6918
+ return "{ a : " + this.a.toString() + ", b : " + this.b.toString() + ", c : " + this.c.toString() + "}";
6923
6919
  };
6924
- ;
6925
6920
  /**
6926
- * Create an SVG representation of this triangle.
6927
- *
6928
- * @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
6929
- * @method toSVGString
6930
- * @param {object=} options - An optional set of options, like 'className'.
6931
- * @return {string} The SVG string.
6932
- * @instance
6933
- * @memberof Triangle
6934
- **/
6935
- Triangle.prototype.toSVGString = function (options) {
6936
- options = options || {};
6937
- var buffer = [];
6938
- buffer.push('<path');
6939
- if (options.className)
6940
- buffer.push(' class="' + options.className + '"');
6941
- buffer.push(' d="');
6942
- var vertices = [this.a, this.b, this.c];
6943
- if (vertices.length > 0) {
6944
- buffer.push('M ');
6945
- buffer.push(vertices[0].x);
6946
- buffer.push(' ');
6947
- buffer.push(vertices[0].y);
6948
- for (var i = 1; i < vertices.length; i++) {
6949
- buffer.push(' L ');
6950
- buffer.push(vertices[i].x);
6951
- buffer.push(' ');
6952
- buffer.push(vertices[i].y);
6953
- }
6954
- //if( !this.isOpen ) {
6955
- buffer.push(' Z');
6956
- //}
6957
- }
6958
- buffer.push('" />');
6959
- return buffer.join('');
6921
+ * This function should invalidate any installed listeners and invalidate this object.
6922
+ * After calling this function the object might not hold valid data any more and
6923
+ * should not be used.
6924
+ */
6925
+ Triangle.prototype.destroy = function () {
6926
+ this.a.destroy();
6927
+ this.b.destroy();
6928
+ this.c.destroy();
6929
+ this.isDestroyed = true;
6960
6930
  };
6961
- ;
6962
6931
  /**
6963
6932
  * An epsilon for comparison.
6964
6933
  * This should be the same epsilon as in Vertex.
@@ -6969,10 +6938,10 @@ var Triangle = /** @class */ (function () {
6969
6938
  Triangle.utils = {
6970
6939
  // Used in the bounds() function.
6971
6940
  max3: function (a, b, c) {
6972
- return (a >= b && a >= c) ? a : (b >= a && b >= c) ? b : c;
6941
+ return a >= b && a >= c ? a : b >= a && b >= c ? b : c;
6973
6942
  },
6974
6943
  min3: function (a, b, c) {
6975
- return (a <= b && a <= c) ? a : (b <= a && b <= c) ? b : c;
6944
+ return a <= b && a <= c ? a : b <= a && b <= c ? b : c;
6976
6945
  },
6977
6946
  signedArea: function (p0x, p0y, p1x, p1y, p2x, p2y) {
6978
6947
  return 0.5 * (-p1y * p2x + p0y * (-p1x + p2x) + p0x * (p1y - p2y) + p1x * p2y);
@@ -6988,9 +6957,9 @@ var Triangle = /** @class */ (function () {
6988
6957
  // http://stackoverflow.com/questions/2049582/how-to-determine-a-point-in-a-2d-triangle
6989
6958
  // var area : number = 1/2*(-p1y*p2x + p0y*(-p1x + p2x) + p0x*(p1y - p2y) + p1x*p2y);
6990
6959
  var area = Triangle.utils.signedArea(p0x, p0y, p1x, p1y, p2x, p2y);
6991
- var s = 1 / (2 * area) * (p0y * p2x - p0x * p2y + (p2y - p0y) * px + (p0x - p2x) * py);
6992
- var t = 1 / (2 * area) * (p0x * p1y - p0y * p1x + (p0y - p1y) * px + (p1x - p0x) * py);
6993
- return s > 0 && t > 0 && (1 - s - t) > 0;
6960
+ var s = (1 / (2 * area)) * (p0y * p2x - p0x * p2y + (p2y - p0y) * px + (p0x - p2x) * py);
6961
+ var t = (1 / (2 * area)) * (p0x * p1y - p0y * p1x + (p0y - p1y) * px + (p1x - p0x) * py);
6962
+ return s > 0 && t > 0 && 1 - s - t > 0;
6994
6963
  }
6995
6964
  };
6996
6965
  return Triangle;
@@ -7046,7 +7015,9 @@ exports.UIDGenerator = UIDGenerator;
7046
7015
  * @modified 2021-03-10 Added the `toCubicBezier` method.
7047
7016
  * @modified 2021-03-15 Added `VEllipse.quarterSegmentCount` and `VEllipse.scale` functions.
7048
7017
  * @modified 2021-03-19 Added the `VEllipse.rotate` function.
7049
- * @version 1.2.2
7018
+ * @modified 2022-02-02 Added the `destroy` method.
7019
+ * @modified 2022-02-02 Cleared the `VEllipse.toSVGString` function (deprecated). Use `drawutilssvg` instead.
7020
+ * @version 1.3.0
7050
7021
  *
7051
7022
  * @file VEllipse
7052
7023
  * @fileoverview Ellipses with a center and an x- and a y-axis (stored as a vertex).
@@ -7372,24 +7343,14 @@ var VEllipse = /** @class */ (function () {
7372
7343
  return curves;
7373
7344
  };
7374
7345
  /**
7375
- * Create an SVG representation of this ellipse.
7376
- *
7377
- * @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
7378
- * @param {object} options { className?:string }
7379
- * @return string The SVG string
7346
+ * This function should invalidate any installed listeners and invalidate this object.
7347
+ * After calling this function the object might not hold valid data any more and
7348
+ * should not be used.
7380
7349
  */
7381
- VEllipse.prototype.toSVGString = function (options) {
7382
- options = options || {};
7383
- var buffer = [];
7384
- buffer.push("<ellipse");
7385
- if (options.className)
7386
- buffer.push(' class="' + options.className + '"');
7387
- buffer.push(' cx="' + this.center.x + '"');
7388
- buffer.push(' cy="' + this.center.y + '"');
7389
- buffer.push(' rx="' + this.axis.x + '"');
7390
- buffer.push(' ry="' + this.axis.y + '"');
7391
- buffer.push(" />");
7392
- return buffer.join("");
7350
+ VEllipse.prototype.destroy = function () {
7351
+ this.center.destroy();
7352
+ this.axis.destroy();
7353
+ this.isDestroyed = true;
7393
7354
  };
7394
7355
  /**
7395
7356
  * A static collection of ellipse-related helper functions.
@@ -7465,7 +7426,8 @@ exports.VEllipse = VEllipse;
7465
7426
  *
7466
7427
  * @author Ikaros Kappler
7467
7428
  * @date 2021-02-26
7468
- * @version 1.0.0
7429
+ * @modified 2022-02-02 Added the `destroy` method.
7430
+ * @version 1.1.0
7469
7431
  */
7470
7432
  Object.defineProperty(exports, "__esModule", ({ value: true }));
7471
7433
  exports.VEllipseSector = void 0;
@@ -7559,6 +7521,15 @@ var VEllipseSector = /** @class */ (function () {
7559
7521
  }
7560
7522
  return curves;
7561
7523
  };
7524
+ /**
7525
+ * This function should invalidate any installed listeners and invalidate this object.
7526
+ * After calling this function the object might not hold valid data any more and
7527
+ * should not be used.
7528
+ */
7529
+ VEllipseSector.prototype.destroy = function () {
7530
+ this.ellipse.destroy();
7531
+ this.isDestroyed = true;
7532
+ };
7562
7533
  VEllipseSector.ellipseSectorUtils = {
7563
7534
  /**
7564
7535
  * Helper function to convert an elliptic section to SVG arc params (for the `d` attribute).
@@ -7743,7 +7714,9 @@ exports.VEllipseSector = VEllipseSector;
7743
7714
  * @modified 2019-12-04 Added the Vector.inv() function.
7744
7715
  * @modified 2020-03-23 Ported to Typescript from JS.
7745
7716
  * @modified 2021-01-20 Added UID.
7746
- * @version 1.3.0
7717
+ * @modified 2022-02-02 Added the `destroy` method.
7718
+ * @modified 2022-02-02 Cleared the `Vector.toSVGString` function (deprecated). Use `drawutilssvg` instead.
7719
+ * @version 1.4.0
7747
7720
  *
7748
7721
  * @file Vector
7749
7722
  * @public
@@ -7793,7 +7766,6 @@ var Vector = /** @class */ (function (_super) {
7793
7766
  _this.className = "Vector";
7794
7767
  return _this;
7795
7768
  }
7796
- ;
7797
7769
  /**
7798
7770
  * Get the perpendicular of this vector which is located at a.
7799
7771
  *
@@ -7808,7 +7780,6 @@ var Vector = /** @class */ (function (_super) {
7808
7780
  v.b.add(this.a);
7809
7781
  return v;
7810
7782
  };
7811
- ;
7812
7783
  /**
7813
7784
  * The inverse of a vector is a vector witht the same magnitude but oppose direction.
7814
7785
  *
@@ -7822,7 +7793,6 @@ var Vector = /** @class */ (function (_super) {
7822
7793
  this.b = tmp;
7823
7794
  return this;
7824
7795
  };
7825
- ;
7826
7796
  /**
7827
7797
  * This function computes the inverse of the vector, which means 'a' stays untouched.
7828
7798
  *
@@ -7833,7 +7803,6 @@ var Vector = /** @class */ (function (_super) {
7833
7803
  this.b.y = this.a.y - (this.b.y - this.a.y);
7834
7804
  return this;
7835
7805
  };
7836
- ;
7837
7806
  /**
7838
7807
  * Get the intersection if this vector and the specified vector.
7839
7808
  *
@@ -7849,53 +7818,15 @@ var Vector = /** @class */ (function (_super) {
7849
7818
  return null;
7850
7819
  var a = this.a.y - line.a.y;
7851
7820
  var b = this.a.x - line.a.x;
7852
- var numerator1 = ((line.b.x - line.a.x) * a) - ((line.b.y - line.a.y) * b);
7853
- var numerator2 = ((this.b.x - this.a.x) * a) - ((this.b.y - this.a.y) * b);
7821
+ var numerator1 = (line.b.x - line.a.x) * a - (line.b.y - line.a.y) * b;
7822
+ var numerator2 = (this.b.x - this.a.x) * a - (this.b.y - this.a.y) * b;
7854
7823
  a = numerator1 / denominator; // NaN if parallel lines
7855
7824
  b = numerator2 / denominator;
7856
7825
  // TODO:
7857
7826
  // FOR A VECTOR THE LINE-INTERSECTION MUST BE ON BOTH VECTORS
7858
7827
  // if we cast these lines infinitely in both directions, they intersect here:
7859
- return new Vertex_1.Vertex(this.a.x + (a * (this.b.x - this.a.x)), this.a.y + (a * (this.b.y - this.a.y)));
7828
+ return new Vertex_1.Vertex(this.a.x + a * (this.b.x - this.a.x), this.a.y + a * (this.b.y - this.a.y));
7860
7829
  };
7861
- ;
7862
- /**
7863
- * Create an SVG representation of this line.
7864
- *
7865
- * @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
7866
- * @method toSVGString
7867
- * @override
7868
- * @param {object=} options - A set of options, like 'className'.
7869
- * @return {string} The SVG string representation.
7870
- * @instance
7871
- * @memberof Vector
7872
- **/
7873
- Vector.prototype.toSVGString = function (options) {
7874
- options = options || {};
7875
- var buffer = [];
7876
- var vertices = Vector.utils.buildArrowHead(this.a, this.b, 8, 1.0, 1.0);
7877
- buffer.push('<g');
7878
- if (options.className)
7879
- buffer.push(' class="' + options.className + '"');
7880
- buffer.push('>');
7881
- buffer.push(' <line');
7882
- buffer.push(' x1="' + this.a.x + '"');
7883
- buffer.push(' y1="' + this.a.y + '"');
7884
- buffer.push(' x2="' + vertices[0].x + '"');
7885
- buffer.push(' y2="' + vertices[0].y + '"');
7886
- buffer.push(' />');
7887
- // Add arrow head
7888
- buffer.push(' <polygon points="');
7889
- for (var i = 0; i < vertices.length; i++) {
7890
- if (i > 0)
7891
- buffer.push(' ');
7892
- buffer.push('' + vertices[i].x + ',' + vertices[i].y);
7893
- }
7894
- buffer.push('"/>');
7895
- buffer.push('</g>');
7896
- return buffer.join('');
7897
- };
7898
- ;
7899
7830
  Vector.utils = {
7900
7831
  /**
7901
7832
  * Generate a four-point arrow head, starting at the vector end minus the
@@ -7925,10 +7856,10 @@ var Vector = /** @class */ (function (_super) {
7925
7856
  buildArrowHead: function (zA, zB, headlen, scaleX, scaleY) {
7926
7857
  var angle = Math.atan2((zB.y - zA.y) * scaleY, (zB.x - zA.x) * scaleX);
7927
7858
  var vertices = [];
7928
- vertices.push(new Vertex_1.Vertex(zB.x * scaleX - (headlen) * Math.cos(angle), zB.y * scaleY - (headlen) * Math.sin(angle)));
7929
- vertices.push(new Vertex_1.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)));
7859
+ vertices.push(new Vertex_1.Vertex(zB.x * scaleX - headlen * Math.cos(angle), zB.y * scaleY - headlen * Math.sin(angle)));
7860
+ vertices.push(new Vertex_1.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)));
7930
7861
  vertices.push(new Vertex_1.Vertex(zB.x * scaleX, zB.y * scaleY));
7931
- vertices.push(new Vertex_1.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)));
7862
+ vertices.push(new Vertex_1.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)));
7932
7863
  return vertices;
7933
7864
  }
7934
7865
  };
@@ -7953,7 +7884,8 @@ exports.Vector = Vector;
7953
7884
  * @modified 2020-12-04 Changed `getClosestT` param from `Vertex` to `XYCoords` (generalized).
7954
7885
  * @modified 2020-12-04 Added the `hasPoint(XYCoords)` function.
7955
7886
  * @modified 2021-01-20 Added UID.
7956
- * @version 1.1.0
7887
+ * @modified 2022-02-02 Added the `destroy` method.
7888
+ * @version 1.2.0
7957
7889
  */
7958
7890
  Object.defineProperty(exports, "__esModule", ({ value: true }));
7959
7891
  exports.VertTuple = void 0;
@@ -7991,7 +7923,6 @@ var VertTuple = /** @class */ (function () {
7991
7923
  VertTuple.prototype.length = function () {
7992
7924
  return Math.sqrt(Math.pow(this.b.x - this.a.x, 2) + Math.pow(this.b.y - this.a.y, 2));
7993
7925
  };
7994
- ;
7995
7926
  /**
7996
7927
  * Set the length of this vector to the given amount. This only works if this
7997
7928
  * vector is not a null vector.
@@ -8004,7 +7935,6 @@ var VertTuple = /** @class */ (function () {
8004
7935
  VertTuple.prototype.setLength = function (length) {
8005
7936
  return this.scale(length / this.length());
8006
7937
  };
8007
- ;
8008
7938
  /**
8009
7939
  * Substract the given vertex from this line's end points.
8010
7940
  *
@@ -8019,7 +7949,6 @@ var VertTuple = /** @class */ (function () {
8019
7949
  this.b.sub(amount);
8020
7950
  return this;
8021
7951
  };
8022
- ;
8023
7952
  /**
8024
7953
  * Add the given vertex to this line's end points.
8025
7954
  *
@@ -8034,7 +7963,6 @@ var VertTuple = /** @class */ (function () {
8034
7963
  this.b.add(amount);
8035
7964
  return this;
8036
7965
  };
8037
- ;
8038
7966
  /**
8039
7967
  * Normalize this line (set to length 1).
8040
7968
  *
@@ -8047,7 +7975,6 @@ var VertTuple = /** @class */ (function () {
8047
7975
  this.b.set(this.a.x + (this.b.x - this.a.x) / this.length(), this.a.y + (this.b.y - this.a.y) / this.length());
8048
7976
  return this;
8049
7977
  };
8050
- ;
8051
7978
  /**
8052
7979
  * Scale this line by the given factor.
8053
7980
  *
@@ -8061,7 +7988,6 @@ var VertTuple = /** @class */ (function () {
8061
7988
  this.b.set(this.a.x + (this.b.x - this.a.x) * factor, this.a.y + (this.b.y - this.a.y) * factor);
8062
7989
  return this;
8063
7990
  };
8064
- ;
8065
7991
  /**
8066
7992
  * Move this line to a new location.
8067
7993
  *
@@ -8077,7 +8003,6 @@ var VertTuple = /** @class */ (function () {
8077
8003
  this.b.add(diff);
8078
8004
  return this;
8079
8005
  };
8080
- ;
8081
8006
  /**
8082
8007
  * Get the angle between this and the passed line (in radians).
8083
8008
  *
@@ -8088,7 +8013,7 @@ var VertTuple = /** @class */ (function () {
8088
8013
  * @memberof VertTuple
8089
8014
  **/
8090
8015
  VertTuple.prototype.angle = function (line) {
8091
- if (line == null || typeof line == 'undefined') {
8016
+ if (line == null || typeof line == "undefined") {
8092
8017
  line = this.factory(new Vertex_1.Vertex(0, 0), new Vertex_1.Vertex(100, 0));
8093
8018
  }
8094
8019
  // Compute the angle from x axis and the return the difference :)
@@ -8098,7 +8023,6 @@ var VertTuple = /** @class */ (function () {
8098
8023
  // The result might be negative, but isn't it usually nicer to determine angles in positive values only?
8099
8024
  return Math.atan2(v1.x, v1.y) - Math.atan2(v0.x, v0.y);
8100
8025
  };
8101
- ;
8102
8026
  /**
8103
8027
  * Get line point at position t in [0 ... 1]:<br>
8104
8028
  * <pre>[P(0)]=[A]--------------------[P(t)]------[B]=[P(1)]</pre><br>
@@ -8114,7 +8038,6 @@ var VertTuple = /** @class */ (function () {
8114
8038
  VertTuple.prototype.vertAt = function (t) {
8115
8039
  return new Vertex_1.Vertex(this.a.x + (this.b.x - this.a.x) * t, this.a.y + (this.b.y - this.a.y) * t);
8116
8040
  };
8117
- ;
8118
8041
  /**
8119
8042
  * Get the denominator of this and the given line.
8120
8043
  *
@@ -8128,9 +8051,8 @@ var VertTuple = /** @class */ (function () {
8128
8051
  **/
8129
8052
  VertTuple.prototype.denominator = function (line) {
8130
8053
  // http://jsfiddle.net/justin_c_rounds/Gd2S2/
8131
- return ((line.b.y - line.a.y) * (this.b.x - this.a.x)) - ((line.b.x - line.a.x) * (this.b.y - this.a.y));
8054
+ return (line.b.y - line.a.y) * (this.b.x - this.a.x) - (line.b.x - line.a.x) * (this.b.y - this.a.y);
8132
8055
  };
8133
- ;
8134
8056
  /**
8135
8057
  * Checks if this and the given line are co-linear.
8136
8058
  *
@@ -8145,7 +8067,6 @@ var VertTuple = /** @class */ (function () {
8145
8067
  VertTuple.prototype.colinear = function (line) {
8146
8068
  return Math.abs(this.denominator(line)) < Vertex_1.Vertex.EPSILON;
8147
8069
  };
8148
- ;
8149
8070
  /**
8150
8071
  * Get the closest position T from this line to the specified point.
8151
8072
  *
@@ -8168,7 +8089,6 @@ var VertTuple = /** @class */ (function () {
8168
8089
  // t = Math.max(0, Math.min(1, t));
8169
8090
  return t;
8170
8091
  };
8171
- ;
8172
8092
  /**
8173
8093
  * Check if the given point is located on this line. Optionally also check if
8174
8094
  * that point is located between point `a` and `b`.
@@ -8204,7 +8124,6 @@ var VertTuple = /** @class */ (function () {
8204
8124
  var t = this.getClosestT(p);
8205
8125
  return this.vertAt(t);
8206
8126
  };
8207
- ;
8208
8127
  /**
8209
8128
  * The the minimal distance between this line and the specified point.
8210
8129
  *
@@ -8219,7 +8138,6 @@ var VertTuple = /** @class */ (function () {
8219
8138
  // https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
8220
8139
  return Math.sqrt(VertTuple.vtutils.dist2(p, this.vertAt(this.getClosestT(p))));
8221
8140
  };
8222
- ;
8223
8141
  /**
8224
8142
  * Create a deep clone of this instance.
8225
8143
  *
@@ -8231,7 +8149,6 @@ var VertTuple = /** @class */ (function () {
8231
8149
  VertTuple.prototype.clone = function () {
8232
8150
  return this.factory(this.a.clone(), this.b.clone());
8233
8151
  };
8234
- ;
8235
8152
  /**
8236
8153
  * Create a string representation of this line.
8237
8154
  *
@@ -8243,7 +8160,16 @@ var VertTuple = /** @class */ (function () {
8243
8160
  VertTuple.prototype.toString = function () {
8244
8161
  return "{ a : " + this.a.toString() + ", b : " + this.b.toString() + " }";
8245
8162
  };
8246
- ;
8163
+ /**
8164
+ * This function should invalidate any installed listeners and invalidate this object.
8165
+ * After calling this function the object might not hold valid data any more and
8166
+ * should not be used.
8167
+ */
8168
+ VertTuple.prototype.destroy = function () {
8169
+ this.a.destroy();
8170
+ this.b.destroy();
8171
+ this.isDestroyed = true;
8172
+ };
8247
8173
  /**
8248
8174
  * @private
8249
8175
  **/
@@ -8289,7 +8215,11 @@ exports.VertTuple = VertTuple;
8289
8215
  * @modified 2021-03-01 Changed the second param `center` in the `rotate` function from Vertex to XYCoords.
8290
8216
  * @modified 2021-12-01 Changed the type of param of `scale` to XYCoords.
8291
8217
  * @modified 2021-12-01 Added function `scaleXY` for non uniform scaling.
8292
- * @version 2.5.0
8218
+ * @modified 2021-12-17 Added the functions `lerp` and `lerpAbs` for linear interpolations.
8219
+ * @modified 2022-01-31 Added `Vertex.utils.arrayToJSON`.
8220
+ * @modified 2022-02-02 Added the `destroy` method.
8221
+ * @modified 2022-02-02 Cleared the `Vertex.toSVGString` function (deprecated). Use `drawutilssvg` instead.
8222
+ * @version 2.7.0
8293
8223
  *
8294
8224
  * @file Vertex
8295
8225
  * @public
@@ -8647,6 +8577,43 @@ var Vertex = /** @class */ (function () {
8647
8577
  Vertex.prototype.scale = function (factor, center) {
8648
8578
  return this.scaleXY({ x: factor, y: factor }, center);
8649
8579
  };
8580
+ /**
8581
+ * Perform a linear interpolation towards the given target vertex.
8582
+ * The amount value `t` is relative, `t=0.0` means no change, `t=1.0`
8583
+ * means this point will be moved to the exact target position.
8584
+ *
8585
+ * `t=0.5` will move this point to the middle of the connecting
8586
+ * linear segment.
8587
+ *
8588
+ * @param {XYCoords} target - The target position to lerp this vertex to.
8589
+ * @param {number} t - The relative amount, usually in [0..1], but other values will work, too.
8590
+ * @returns
8591
+ */
8592
+ Vertex.prototype.lerp = function (target, t) {
8593
+ var diff = this.difference(target);
8594
+ // return new Vertex(this.x + diff.x * t, this.y + diff.y * t);
8595
+ this.x += diff.x * t;
8596
+ this.y += diff.y * t;
8597
+ return this;
8598
+ };
8599
+ /**
8600
+ * Perform a linear interpolation towards the given target vertex (absolute variant).
8601
+ * The amount value `t` is absolute, which means the lerp amount is a direct distance
8602
+ * value. This point will have move the amount of the passed distance `u`.
8603
+ *
8604
+ * @param {XYCoords} target - The target position to lerp this vertex to.
8605
+ * @param {number} t - The absolute move amount to use to lerping.
8606
+ * @returns
8607
+ */
8608
+ Vertex.prototype.lerpAbs = function (target, u) {
8609
+ var dist = this.distance(target);
8610
+ var diff = this.difference(target);
8611
+ var step = { x: diff.x / dist, y: diff.y / dist };
8612
+ // return new Vertex(this.x + step.x * u, this.y + step.y * u);
8613
+ this.x += step.x * u;
8614
+ this.y += step.y * u;
8615
+ return this;
8616
+ };
8650
8617
  /**
8651
8618
  * This is a vector-like behavior and 'scales' this vertex
8652
8619
  * towards/from a given center by two independent x- and y- scale factors.
@@ -8744,28 +8711,14 @@ var Vertex = /** @class */ (function () {
8744
8711
  return "(" + this.x + "," + this.y + ")";
8745
8712
  };
8746
8713
  /**
8747
- * Convert this vertex to SVG code.
8748
- *
8749
- * @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
8750
- * @method toSVGString
8751
- * @param {object=} options - An optional set of options, like 'className'.
8752
- * @return {string} A string representing the SVG code for this vertex.
8753
- * @instance
8754
- * @memberof Vertex
8755
- **/
8756
- Vertex.prototype.toSVGString = function (options) {
8757
- options = options || {};
8758
- var buffer = [];
8759
- buffer.push("<circle");
8760
- if (options.className)
8761
- buffer.push(' class="' + options.className + '"');
8762
- buffer.push(' cx="' + this.x + '"');
8763
- buffer.push(' cy="' + this.y + '"');
8764
- buffer.push(' r="2"');
8765
- buffer.push(" />");
8766
- return buffer.join("");
8714
+ * This function should invalidate any installed listeners and invalidate this object.
8715
+ * After calling this function the object might not hold valid data any more and
8716
+ * should not be used.
8717
+ */
8718
+ Vertex.prototype.destroy = function () {
8719
+ this.listeners.removeAllListeners();
8720
+ this.isDestroyed = true;
8767
8721
  };
8768
- // END Vertex
8769
8722
  /**
8770
8723
  * Create a new random vertex inside the given viewport.
8771
8724
  *
@@ -8819,6 +8772,19 @@ var Vertex = /** @class */ (function () {
8819
8772
  vertices.push(new Vertex(zB.x * scaleX, zB.y * scaleY));
8820
8773
  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)));
8821
8774
  return vertices;
8775
+ },
8776
+ /**
8777
+ * Convert the given vertices (array) to a JSON string.
8778
+ *
8779
+ * @param {number?} precision - (optional) The numeric precision to be used (number of precision digits).
8780
+ * @returns {string}
8781
+ */
8782
+ arrayToJSON: function (vertices, precision) {
8783
+ return JSON.stringify(vertices.map(function (vert) {
8784
+ return typeof precision === undefined
8785
+ ? { x: vert.x, y: vert.y }
8786
+ : { x: Number(vert.x.toFixed(precision)), y: Number(vert.y.toFixed(precision)) };
8787
+ }));
8822
8788
  }
8823
8789
  };
8824
8790
  return Vertex;
@@ -8932,7 +8898,6 @@ var VertexListeners = /** @class */ (function () {
8932
8898
  this.dragEnd = [];
8933
8899
  this.vertex = vertex;
8934
8900
  }
8935
- ;
8936
8901
  /**
8937
8902
  * Add a click listener.
8938
8903
  *
@@ -8946,7 +8911,6 @@ var VertexListeners = /** @class */ (function () {
8946
8911
  VertexListeners._addListener(this.click, listener);
8947
8912
  return this;
8948
8913
  };
8949
- ;
8950
8914
  /**
8951
8915
  * The click listener is a function with a single drag event param.
8952
8916
  * @callback VertexListeners~clickListener
@@ -8965,7 +8929,6 @@ var VertexListeners = /** @class */ (function () {
8965
8929
  this.click = VertexListeners._removeListener(this.click, listener);
8966
8930
  return this;
8967
8931
  };
8968
- ;
8969
8932
  /**
8970
8933
  * The click listener is a function with a single drag event param.
8971
8934
  * @callback VertexListeners~clickListener
@@ -8984,7 +8947,6 @@ var VertexListeners = /** @class */ (function () {
8984
8947
  VertexListeners._addListener(this.drag, listener);
8985
8948
  return this;
8986
8949
  };
8987
- ;
8988
8950
  /**
8989
8951
  * The drag listener is a function with a single drag event param.
8990
8952
  * @callback VertexListeners~dragListener
@@ -9003,7 +8965,6 @@ var VertexListeners = /** @class */ (function () {
9003
8965
  this.drag = VertexListeners._removeListener(this.drag, listener);
9004
8966
  return this;
9005
8967
  };
9006
- ;
9007
8968
  /**
9008
8969
  * Add a dragStart listener.
9009
8970
  *
@@ -9017,7 +8978,6 @@ var VertexListeners = /** @class */ (function () {
9017
8978
  VertexListeners._addListener(this.dragStart, listener);
9018
8979
  return this;
9019
8980
  };
9020
- ;
9021
8981
  /**
9022
8982
  * The drag-start listener is a function with a single drag event param.
9023
8983
  * @callback VertexListeners~dragStartListener
@@ -9036,7 +8996,6 @@ var VertexListeners = /** @class */ (function () {
9036
8996
  this.dragStart = VertexListeners._removeListener(this.dragStart, listener);
9037
8997
  return this;
9038
8998
  };
9039
- ;
9040
8999
  /**
9041
9000
  * Add a dragEnd listener.
9042
9001
  *
@@ -9051,27 +9010,25 @@ var VertexListeners = /** @class */ (function () {
9051
9010
  VertexListeners._addListener(this.dragEnd, listener);
9052
9011
  return this;
9053
9012
  };
9054
- ;
9055
9013
  /**
9056
9014
  * The drag-end listener is a function with a single drag event param.
9057
9015
  * @callback VertexListeners~dragEndListener
9058
9016
  * @param {Event} e - The (extended) drag event.
9059
9017
  */
9060
9018
  /**
9061
- * Remove a drag listener.
9062
- *
9063
- * @method removeDragEndListener
9064
- * @param {VertexListeners~clickListener} listener - The drag listener to remove (a callback).
9065
- * @return {VertexListeners} this (for chaining)
9066
- * @instance
9067
- * @memberof VertexListeners
9068
- **/
9019
+ * Remove a drag listener.
9020
+ *
9021
+ * @method removeDragEndListener
9022
+ * @param {VertexListeners~clickListener} listener - The drag listener to remove (a callback).
9023
+ * @return {VertexListeners} this (for chaining)
9024
+ * @instance
9025
+ * @memberof VertexListeners
9026
+ **/
9069
9027
  VertexListeners.prototype.removeDragEndListener = function (listener) {
9070
9028
  // this.drag.push( listener );
9071
9029
  this.dragEnd = VertexListeners._removeListener(this.dragEnd, listener);
9072
9030
  return this;
9073
9031
  };
9074
- ;
9075
9032
  /**
9076
9033
  * Fire a click event with the given event instance to all
9077
9034
  * installed click listeners.
@@ -9085,7 +9042,6 @@ var VertexListeners = /** @class */ (function () {
9085
9042
  VertexListeners.prototype.fireClickEvent = function (e) {
9086
9043
  VertexListeners._fireEvent(this, this.click, e);
9087
9044
  };
9088
- ;
9089
9045
  /**
9090
9046
  * Fire a drag event with the given event instance to all
9091
9047
  * installed drag listeners.
@@ -9099,7 +9055,6 @@ var VertexListeners = /** @class */ (function () {
9099
9055
  VertexListeners.prototype.fireDragEvent = function (e) {
9100
9056
  VertexListeners._fireEvent(this, this.drag, e);
9101
9057
  };
9102
- ;
9103
9058
  /**
9104
9059
  * Fire a dragStart event with the given event instance to all
9105
9060
  * installed drag-start listeners.
@@ -9113,7 +9068,6 @@ var VertexListeners = /** @class */ (function () {
9113
9068
  VertexListeners.prototype.fireDragStartEvent = function (e) {
9114
9069
  VertexListeners._fireEvent(this, this.dragStart, e);
9115
9070
  };
9116
- ;
9117
9071
  /**
9118
9072
  * Fire a dragEnd event with the given event instance to all
9119
9073
  * installed drag-end listeners.
@@ -9127,13 +9081,21 @@ var VertexListeners = /** @class */ (function () {
9127
9081
  VertexListeners.prototype.fireDragEndEvent = function (e) {
9128
9082
  VertexListeners._fireEvent(this, this.dragEnd, e);
9129
9083
  };
9130
- ;
9084
+ /**
9085
+ * Removes all listeners from this listeners object.
9086
+ */
9087
+ VertexListeners.prototype.removeAllListeners = function () {
9088
+ this.click = [];
9089
+ this.drag = [];
9090
+ this.dragStart = [];
9091
+ this.dragEnd = [];
9092
+ };
9131
9093
  /**
9132
9094
  * @private
9133
9095
  **/
9134
9096
  VertexListeners._fireEvent = function (_self, listeners, e) {
9135
9097
  var ve = e;
9136
- if (typeof ve.params == 'undefined')
9098
+ if (typeof ve.params == "undefined")
9137
9099
  ve.params = { vertex: _self.vertex };
9138
9100
  else
9139
9101
  ve.params.vertex = _self.vertex;
@@ -9141,7 +9103,6 @@ var VertexListeners = /** @class */ (function () {
9141
9103
  listeners[i](ve);
9142
9104
  }
9143
9105
  };
9144
- ;
9145
9106
  /**
9146
9107
  * @private
9147
9108
  */
@@ -9153,7 +9114,6 @@ var VertexListeners = /** @class */ (function () {
9153
9114
  listeners.push(newListener);
9154
9115
  return true;
9155
9116
  };
9156
- ;
9157
9117
  /**
9158
9118
  * @private
9159
9119
  */
@@ -9164,7 +9124,6 @@ var VertexListeners = /** @class */ (function () {
9164
9124
  }
9165
9125
  return listeners;
9166
9126
  };
9167
- ;
9168
9127
  return VertexListeners;
9169
9128
  }());
9170
9129
  exports.VertexListeners = VertexListeners;
@@ -9217,7 +9176,10 @@ exports.VertexListeners = VertexListeners;
9217
9176
  * @modified 2021-05-31 Added the `setConfiguration` function from `DrawLib`.
9218
9177
  * @modified 2021-11-12 Adding more parameters tot the `text()` function: fontSize, textAlign, fontFamily, lineHeight.
9219
9178
  * @modified 2021-11-19 Added the `color` param to the `label(...)` function.
9220
- * @version 1.10.0
9179
+ * @modified 2022-02-03 Added the `lineWidth` param to the `crosshair` function.
9180
+ * @modified 2022-02-03 Added the `cross(...)` function.
9181
+ * @modified 2022-03-27 Added the `texturedPoly` function.
9182
+ * @version 1.12.0
9221
9183
  **/
9222
9184
  Object.defineProperty(exports, "__esModule", ({ value: true }));
9223
9185
  exports.drawutils = void 0;
@@ -9376,6 +9338,97 @@ var drawutils = /** @class */ (function () {
9376
9338
  this.offset.x + position.x * this.scale.x, this.offset.y + position.y * this.scale.y, size.x * this.scale.x, size.y * this.scale.y);
9377
9339
  this.ctx.restore();
9378
9340
  };
9341
+ /**
9342
+ * Draw an image at the given position with the given size.<br>
9343
+ * <br>
9344
+ * Note: SVG images may have resizing issues at the moment.Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.
9345
+ *
9346
+ * @method texturedPoly
9347
+ * @param {Image} textureImage - The image object to draw.
9348
+ * @param {Bounds} textureSize - The texture size to use; these are the original bounds to map the polygon vertices to.
9349
+ * @param {Polygon} polygon - The polygon to use as clip path.
9350
+ * @param {Vertex} polygonPosition - The polygon's position (relative), measured at the bounding box's center.
9351
+ * @param {number} rotation - The rotation to use for the polygon (and for the texture).
9352
+ * @param {XYCoords={x:0,y:0}} rotationCenter - (optional) The rotational center; default is center of bounding box.
9353
+ * @return {void}
9354
+ * @instance
9355
+ * @memberof drawutils
9356
+ **/
9357
+ drawutils.prototype.texturedPoly = function (textureImage, textureSize, polygon, polygonPosition, rotation) {
9358
+ var basePolygonBounds = polygon.getBounds();
9359
+ var targetCenterDifference = polygonPosition.clone().difference(basePolygonBounds.getCenter());
9360
+ // var rotationalOffset = rotationCenter ? polygonPosition.difference(rotationCenter) : { x: 0, y: 0 };
9361
+ // var rotationalOffset = { x: 0, y: 0 };
9362
+ var tileCenter = basePolygonBounds.getCenter().sub(targetCenterDifference);
9363
+ // Get the position offset of the polygon
9364
+ var targetTextureSize = new Vertex_1.Vertex(textureSize.width, textureSize.height);
9365
+ // var targetTextureOffset = new Vertex(-textureSize.width / 2, -textureSize.height / 2).sub(targetCenterDifference);
9366
+ var targetTextureOffset = new Vertex_1.Vertex(textureSize.min.x, textureSize.min.y).sub(polygonPosition);
9367
+ this.ctx.save();
9368
+ // this.ctx.translate(this.offset.x + rotationCenter.x * this.scale.x, this.offset.y + rotationCenter.y * this.scale.y);
9369
+ this.ctx.translate(this.offset.x + polygonPosition.x * this.scale.x, this.offset.y + polygonPosition.y * this.scale.y);
9370
+ drawutils.helpers.clipPoly(this.ctx, {
9371
+ x: -polygonPosition.x * this.scale.x,
9372
+ y: -polygonPosition.y * this.scale.y
9373
+ }, this.scale, polygon.vertices);
9374
+ this.ctx.scale(this.scale.x, this.scale.y);
9375
+ this.ctx.rotate(rotation);
9376
+ this.ctx.drawImage(textureImage, 0, 0, textureImage.naturalWidth - 1, // There is this horrible Safari bug (fixed in newer versions)
9377
+ textureImage.naturalHeight - 1, // To avoid errors substract 1 here.
9378
+ targetTextureOffset.x, // * this.scale.x,
9379
+ targetTextureOffset.y, // * this.scale.y,
9380
+ targetTextureSize.x, // * this.scale.x,
9381
+ targetTextureSize.y // * this.scale.y
9382
+ );
9383
+ this.ctx.restore();
9384
+ };
9385
+ drawutils.prototype._texturedPoly = function (textureImage, textureSize, polygon, polygonPosition, rotation, rotationCenter) {
9386
+ if (rotationCenter === void 0) { rotationCenter = { x: 0, y: 0 }; }
9387
+ var basePolygonBounds = polygon.getBounds();
9388
+ var targetCenterDifference = polygonPosition.clone().difference(basePolygonBounds.getCenter());
9389
+ var rotationalOffset = rotationCenter ? polygonPosition.difference(rotationCenter) : { x: 0, y: 0 };
9390
+ // var rotationalOffset = { x: 0, y: 0 };
9391
+ var tileCenter = basePolygonBounds.getCenter().sub(targetCenterDifference);
9392
+ // Get the position offset of the polygon
9393
+ var targetTextureSize = new Vertex_1.Vertex(textureSize.width, textureSize.height);
9394
+ var targetTextureOffset = new Vertex_1.Vertex(-textureSize.width / 2, -textureSize.height / 2).sub(targetCenterDifference);
9395
+ this.ctx.save();
9396
+ // this.ctx.translate(
9397
+ // this.offset.x + (tileCenter.x - rotationalOffset.x * 0 + targetTextureOffset.x * 0.0) * this.scale.x,
9398
+ // this.offset.y + (tileCenter.y - rotationalOffset.y * 0 + targetTextureOffset.y * 0.0) * this.scale.y
9399
+ // );
9400
+ this.ctx.translate(this.offset.x + (tileCenter.x - rotationalOffset.x * 0 + targetTextureOffset.x * 0.0) * this.scale.x, this.offset.y + (tileCenter.y - rotationalOffset.y * 0 + targetTextureOffset.y * 0.0) * this.scale.y);
9401
+ this.ctx.rotate(rotation);
9402
+ drawutils.helpers.clipPoly(this.ctx, {
9403
+ x: (-targetCenterDifference.x * 1 - tileCenter.x - rotationalOffset.x) * this.scale.x,
9404
+ y: (-targetCenterDifference.y * 1 - tileCenter.y - rotationalOffset.y) * this.scale.y
9405
+ }, this.scale, polygon.vertices);
9406
+ this.ctx.drawImage(textureImage, 0, 0, textureImage.naturalWidth - 1, // There is this horrible Safari bug (fixed in newer versions)
9407
+ textureImage.naturalHeight - 1, // To avoid errors substract 1 here.
9408
+ (-polygonPosition.x + targetTextureOffset.x * 1 - rotationalOffset.x * 1) * this.scale.x, (-polygonPosition.y + targetTextureOffset.y * 1 - rotationalOffset.y * 1) * this.scale.y, targetTextureSize.x * this.scale.x, targetTextureSize.y * this.scale.y);
9409
+ // const scaledTextureSize = new Bounds(
9410
+ // new Vertex(
9411
+ // -polygonPosition.x + targetTextureOffset.x - rotationalOffset.x,
9412
+ // -polygonPosition.y + targetTextureOffset.y - rotationalOffset.y
9413
+ // ).scaleXY(this.scale, rotationCenter),
9414
+ // new Vertex(
9415
+ // -polygonPosition.x + targetTextureOffset.x - rotationalOffset.x + targetTextureSize.x,
9416
+ // -polygonPosition.y + targetTextureOffset.y - rotationalOffset.y + targetTextureSize.y
9417
+ // ).scaleXY(this.scale, rotationCenter)
9418
+ // );
9419
+ // this.ctx.drawImage(
9420
+ // textureImage,
9421
+ // 0,
9422
+ // 0,
9423
+ // textureImage.naturalWidth - 1, // There is this horrible Safari bug (fixed in newer versions)
9424
+ // textureImage.naturalHeight - 1, // To avoid errors substract 1 here.
9425
+ // scaledTextureSize.min.x,
9426
+ // scaledTextureSize.min.y,
9427
+ // scaledTextureSize.width,
9428
+ // scaledTextureSize.height
9429
+ // );
9430
+ this.ctx.restore();
9431
+ };
9379
9432
  /**
9380
9433
  * Draw a rectangle.
9381
9434
  *
@@ -9816,11 +9869,12 @@ var drawutils = /** @class */ (function () {
9816
9869
  * @param {XYCoords} center - The center of the crosshair.
9817
9870
  * @param {number} radius - The radius of the crosshair.
9818
9871
  * @param {string} color - The CSS color to draw the crosshair with.
9872
+ * @param {number=0.5} lineWidth - (optional, default=0.5) The line width to use.
9819
9873
  * @return {void}
9820
9874
  * @instance
9821
9875
  * @memberof drawutils
9822
9876
  */
9823
- drawutils.prototype.crosshair = function (center, radius, color) {
9877
+ drawutils.prototype.crosshair = function (center, radius, color, lineWidth) {
9824
9878
  this.ctx.save();
9825
9879
  this.ctx.beginPath();
9826
9880
  this.ctx.moveTo(this.offset.x + center.x * this.scale.x - radius, this.offset.y + center.y * this.scale.y);
@@ -9828,7 +9882,34 @@ var drawutils = /** @class */ (function () {
9828
9882
  this.ctx.moveTo(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y - radius);
9829
9883
  this.ctx.lineTo(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y + radius);
9830
9884
  this.ctx.strokeStyle = color;
9831
- this.ctx.lineWidth = 0.5;
9885
+ this.ctx.lineWidth = lineWidth || 0.5;
9886
+ this.ctx.stroke();
9887
+ this.ctx.closePath();
9888
+ this.ctx.restore();
9889
+ };
9890
+ /**
9891
+ * Draw a cross with diagonal axes with given radius, color and lineWidth at the given position.<br>
9892
+ * <br>
9893
+ * Note that the x's radius will not be affected by scaling.
9894
+ *
9895
+ * @method crosshair
9896
+ * @param {XYCoords} center - The center of the crosshair.
9897
+ * @param {number} radius - The radius of the crosshair.
9898
+ * @param {string} color - The CSS color to draw the crosshair with.
9899
+ * @param {number=1} lineWidth - (optional, default=1.0) The line width to use.
9900
+ * @return {void}
9901
+ * @instance
9902
+ * @memberof drawutils
9903
+ */
9904
+ drawutils.prototype.cross = function (center, radius, color, lineWidth) {
9905
+ this.ctx.save();
9906
+ this.ctx.beginPath();
9907
+ this.ctx.moveTo(this.offset.x + center.x * this.scale.x - radius, this.offset.y + center.y * this.scale.y - radius);
9908
+ this.ctx.lineTo(this.offset.x + center.x * this.scale.x + radius, this.offset.y + center.y * this.scale.y + radius);
9909
+ this.ctx.moveTo(this.offset.x + center.x * this.scale.x - radius, this.offset.y + center.y * this.scale.y + radius);
9910
+ this.ctx.lineTo(this.offset.x + center.x * this.scale.x + radius, this.offset.y + center.y * this.scale.y - radius);
9911
+ this.ctx.strokeStyle = color;
9912
+ this.ctx.lineWidth = lineWidth || 1.0;
9832
9913
  this.ctx.stroke();
9833
9914
  this.ctx.closePath();
9834
9915
  this.ctx.restore();
@@ -10005,6 +10086,21 @@ var drawutils = /** @class */ (function () {
10005
10086
  this.ctx.fillStyle = color;
10006
10087
  this.ctx.fillRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
10007
10088
  };
10089
+ drawutils.helpers = {
10090
+ // A helper function to define the clipping path.
10091
+ // This could be a candidate for the draw library.
10092
+ clipPoly: function (ctx, offset, scale, vertices) {
10093
+ ctx.beginPath();
10094
+ // Set clip mask
10095
+ ctx.moveTo(offset.x + vertices[0].x * scale.x, offset.y + vertices[0].y * scale.y);
10096
+ for (var i = 1; i < vertices.length; i++) {
10097
+ var vert = vertices[i];
10098
+ ctx.lineTo(offset.x + vert.x * scale.x, offset.y + vert.y * scale.y);
10099
+ }
10100
+ ctx.closePath();
10101
+ ctx.clip();
10102
+ }
10103
+ };
10008
10104
  return drawutils;
10009
10105
  }());
10010
10106
  exports.drawutils = drawutils;
@@ -10024,7 +10120,10 @@ exports.drawutils = drawutils;
10024
10120
  * @modified 2020-10-15 Re-added the text() function.
10025
10121
  * @modified 2021-01-24 Added the `setCurrentId` function.
10026
10122
  * @modified 2021-05-31 Added the `setConfiguration` function from `DrawLib`.
10027
- * @version 0.0.5
10123
+ * @modified 2022-02-03 Added the `lineWidth` param to the `crosshair` function.
10124
+ * @modified 2022-02-03 Added the `cross(...)` function.
10125
+ * @modified 2022-03-27 Added the `texturedPoly` function.
10126
+ * @version 0.0.7
10028
10127
  **/
10029
10128
  Object.defineProperty(exports, "__esModule", ({ value: true }));
10030
10129
  exports.drawutilsgl = void 0;
@@ -10224,6 +10323,24 @@ var drawutilsgl = /** @class */ (function () {
10224
10323
  drawutilsgl.prototype.image = function (image, position, size) {
10225
10324
  // NOT YET IMPLEMENTED
10226
10325
  };
10326
+ /**
10327
+ * Draw an image at the given position with the given size.<br>
10328
+ * <br>
10329
+ * Note: SVG images may have resizing issues at the moment.Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.
10330
+ *
10331
+ * @method texturedPoly
10332
+ * @param {Image} textureImage - The image object to draw.
10333
+ * @param {Bounds} textureSize - The texture size to use; these are the original bounds to map the polygon vertices to.
10334
+ * @param {Polygon} polygon - The polygon to use as clip path.
10335
+ * @param {Vertex} polygonPosition - The polygon's position (relative), measured at the bounding box's center.
10336
+ * @param {number} rotation - The rotation to use for the polygon (and for the texture).
10337
+ * @return {void}
10338
+ * @instance
10339
+ * @memberof drawutilsgl
10340
+ **/
10341
+ drawutilsgl.prototype.texturedPoly = function (textureImage, textureSize, polygon, polygonPosition, rotation) {
10342
+ // NOT YET IMPLEMENTED
10343
+ };
10227
10344
  // +---------------------------------------------------------------------------------
10228
10345
  // | This is the final helper function for drawing and filling stuff. It is not
10229
10346
  // | intended to be used from the outside.
@@ -10505,11 +10622,29 @@ var drawutilsgl = /** @class */ (function () {
10505
10622
  * @param {XYCoords} center - The center of the crosshair.
10506
10623
  * @param {number} radius - The radius of the crosshair.
10507
10624
  * @param {string} color - The CSS color to draw the crosshair with.
10625
+ * @param {number=0.5} lineWidth - (optional, default=0.5) The line width to use.
10626
+ * @return {void}
10627
+ * @instance
10628
+ * @memberof drawutils
10629
+ */
10630
+ drawutilsgl.prototype.crosshair = function (center, radius, color, lineWidth) {
10631
+ // NOT YET IMPLEMENTED
10632
+ };
10633
+ /**
10634
+ * Draw a cross with diagonal axes with given radius, color and lineWidth at the given position.<br>
10635
+ * <br>
10636
+ * Note that the x's radius will not be affected by scaling.
10637
+ *
10638
+ * @method crosshair
10639
+ * @param {XYCoords} center - The center of the crosshair.
10640
+ * @param {number} radius - The radius of the crosshair.
10641
+ * @param {string} color - The CSS color to draw the crosshair with.
10642
+ * @param {number=1} lineWidth - (optional, default=1.0) The line width to use.
10508
10643
  * @return {void}
10509
10644
  * @instance
10510
10645
  * @memberof drawutils
10511
10646
  */
10512
- drawutilsgl.prototype.crosshair = function (center, radius, color) {
10647
+ drawutilsgl.prototype.cross = function (center, radius, color, lineWidth) {
10513
10648
  // NOT YET IMPLEMENTED
10514
10649
  };
10515
10650
  /**
@@ -10748,13 +10883,18 @@ var GLU = /** @class */ (function () {
10748
10883
  * @modified 2021-11-15 Adding more parameters tot the `text()` function: fontSize, textAlign, fontFamily, lineHeight.
10749
10884
  * @modified 2021-11-19 Fixing the `label(text,x,y)` position.
10750
10885
  * @modified 2021-11-19 Added the `color` param to the `label(...)` function.
10751
- * @version 1.4.0
10886
+ * @modified 2022-02-03 Added the `lineWidth` param to the `crosshair` function.
10887
+ * @modified 2022-02-03 Added the `cross(...)` function.
10888
+ * @modified 2022-03-26 Added the private `nodeDefs` and `bufferedNodeDefs` attributes.
10889
+ * @modified 2022-03-26 Added the `texturedPoly` function to draw textures polygons.
10890
+ * @version 1.6.0
10752
10891
  **/
10753
10892
  Object.defineProperty(exports, "__esModule", ({ value: true }));
10754
10893
  exports.drawutilssvg = void 0;
10755
10894
  var CircleSector_1 = __webpack_require__(946);
10756
10895
  var CubicBezierCurve_1 = __webpack_require__(510);
10757
10896
  var Vertex_1 = __webpack_require__(421);
10897
+ var UIDGenerator_1 = __webpack_require__(197);
10758
10898
  var RAD_TO_DEG = 180 / Math.PI;
10759
10899
  /**
10760
10900
  * @classdesc A helper class for basic SVG drawing operations. This class should
@@ -10780,7 +10920,7 @@ var drawutilssvg = /** @class */ (function () {
10780
10920
  * @param {boolean=} isSecondary - (optional) Indicates if this is the primary or secondary instance. Only primary instances manage child nodes.
10781
10921
  * @param {SVGGElement=} gNode - (optional) Primary and seconday instances share the same &lt;g> node.
10782
10922
  **/
10783
- function drawutilssvg(svgNode, offset, scale, canvasSize, fillShapes, drawConfig, isSecondary, gNode, bufferGNode) {
10923
+ function drawutilssvg(svgNode, offset, scale, canvasSize, fillShapes, drawConfig, isSecondary, gNode, bufferGNode, nodeDefs, bufferNodeDefs) {
10784
10924
  this.svgNode = svgNode;
10785
10925
  this.offset = new Vertex_1.Vertex(0, 0).set(offset);
10786
10926
  this.scale = new Vertex_1.Vertex(1, 1).set(scale);
@@ -10792,14 +10932,23 @@ var drawutilssvg = /** @class */ (function () {
10792
10932
  if (isSecondary) {
10793
10933
  this.gNode = gNode;
10794
10934
  this.bufferGNode = bufferGNode;
10935
+ this.nodeDefs = nodeDefs;
10936
+ this.bufferedNodeDefs = bufferNodeDefs;
10795
10937
  }
10796
10938
  else {
10797
10939
  this.addStyleDefs(drawConfig);
10940
+ this.addDefsNode();
10798
10941
  this.gNode = this.createSVGNode("g");
10799
10942
  this.bufferGNode = this.createSVGNode("g");
10800
10943
  this.svgNode.appendChild(this.gNode);
10801
10944
  }
10802
10945
  }
10946
+ /**
10947
+ * Adds a default style defintion based on the passed DrawConfig.
10948
+ * Twaek the draw config to change default colors or line thicknesses.
10949
+ *
10950
+ * @param {DrawConfig} drawConfig
10951
+ */
10803
10952
  drawutilssvg.prototype.addStyleDefs = function (drawConfig) {
10804
10953
  this.nodeStyle = this.createSVGNode("style");
10805
10954
  this.svgNode.appendChild(this.nodeStyle);
@@ -10832,6 +10981,15 @@ var drawutilssvg = /** @class */ (function () {
10832
10981
  }
10833
10982
  this.nodeStyle.innerHTML = rules.join("\n");
10834
10983
  };
10984
+ /**
10985
+ * Adds the internal <defs> node.
10986
+ */
10987
+ drawutilssvg.prototype.addDefsNode = function () {
10988
+ this.nodeDefs = this.createSVGNode("defs");
10989
+ // this.svgNode.appendChild(this.nodeDefs);
10990
+ this.bufferedNodeDefs = this.createSVGNode("defs");
10991
+ this.svgNode.appendChild(this.nodeDefs);
10992
+ };
10835
10993
  /**
10836
10994
  * This is a simple way to include custom CSS class mappings to the style defs of the generated SVG.
10837
10995
  *
@@ -10969,7 +11127,7 @@ var drawutilssvg = /** @class */ (function () {
10969
11127
  drawutilssvg.prototype.copyInstance = function (fillShapes) {
10970
11128
  var copy = new drawutilssvg(this.svgNode, this.offset, this.scale, this.canvasSize, fillShapes, null, // no DrawConfig
10971
11129
  true, // isSecondary
10972
- this.gNode, this.bufferGNode);
11130
+ this.gNode, this.bufferGNode, this.nodeDefs, this.bufferedNodeDefs);
10973
11131
  return copy;
10974
11132
  };
10975
11133
  /**
@@ -11046,11 +11204,15 @@ var drawutilssvg = /** @class */ (function () {
11046
11204
  // layout updates.
11047
11205
  // Replace the old <g>-node with the buffer node.
11048
11206
  // https://stackoverflow.com/questions/27442464/how-to-update-a-svg-image-without-seeing-a-blinking
11207
+ this.svgNode.replaceChild(this.bufferedNodeDefs, this.nodeDefs);
11049
11208
  this.svgNode.replaceChild(this.bufferGNode, this.gNode);
11050
11209
  }
11051
- var tmp = this.gNode;
11210
+ var tmpGNode = this.gNode;
11052
11211
  this.gNode = this.bufferGNode;
11053
- this.bufferGNode = tmp;
11212
+ this.bufferGNode = tmpGNode;
11213
+ var tmpDefsNode = this.nodeDefs;
11214
+ this.nodeDefs = this.bufferedNodeDefs;
11215
+ this.bufferedNodeDefs = tmpDefsNode;
11054
11216
  };
11055
11217
  drawutilssvg.prototype._x = function (x) {
11056
11218
  return this.offset.x + this.scale.x * x;
@@ -11143,6 +11305,75 @@ var drawutilssvg = /** @class */ (function () {
11143
11305
  node.setAttribute("href", image.src);
11144
11306
  return this._bindFillDraw(node, "image", null, null);
11145
11307
  };
11308
+ /**
11309
+ * Draw an image at the given position with the given size.<br>
11310
+ * <br>
11311
+ * Note: SVG images may have resizing issues at the moment.Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.
11312
+ *
11313
+ * @method texturedPoly
11314
+ * @param {Image} textureImage - The image object to draw.
11315
+ * @param {Bounds} textureSize - The texture size to use; these are the original bounds to map the polygon vertices to.
11316
+ * @param {Polygon} polygon - The polygon to use as clip path.
11317
+ * @param {Vertex} polygonPosition - The polygon's position (relative), measured at the bounding box's center.
11318
+ * @param {number} rotation - The rotation to use for the polygon (and for the texture).
11319
+ * @return {void}
11320
+ * @instance
11321
+ * @memberof drawutilssvg
11322
+ **/
11323
+ drawutilssvg.prototype.texturedPoly = function (textureImage, textureSize, polygon, polygonPosition, rotation) {
11324
+ var basePolygonBounds = polygon.getBounds();
11325
+ var rotatedScalingOrigin = new Vertex_1.Vertex(textureSize.min).clone().rotate(rotation, polygonPosition);
11326
+ var rotationCenter = polygonPosition.clone().add(rotatedScalingOrigin.difference(textureSize.min).inv());
11327
+ // Create something like this
11328
+ // ...
11329
+ // <defs>
11330
+ // <clipPath id="shape">
11331
+ // <path fill="none" d="..."/>
11332
+ // </clipPath>
11333
+ // </defs>
11334
+ // ...
11335
+ // <g clip-path="url(#shape)">
11336
+ // <g transform="scale(...)">
11337
+ // <image width="643" height="643" transform="rotate(...)" xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/beagle400.jpg" >
11338
+ // </g>
11339
+ // </g>
11340
+ // </image>
11341
+ // ...
11342
+ var clipPathNode = this.makeNode("clipPath");
11343
+ var clipPathId = "clippath_" + UIDGenerator_1.UIDGenerator.next(); // TODO: use a better UUID generator here?
11344
+ clipPathNode.setAttribute("id", clipPathId);
11345
+ var gNode = this.makeNode("g");
11346
+ var imageNode = this.makeNode("image");
11347
+ imageNode.setAttribute("x", "" + this._x(rotatedScalingOrigin.x));
11348
+ imageNode.setAttribute("y", "" + this._y(rotatedScalingOrigin.y));
11349
+ imageNode.setAttribute("width", "" + textureSize.width);
11350
+ imageNode.setAttribute("height", "" + textureSize.height);
11351
+ imageNode.setAttribute("href", textureImage.src);
11352
+ // imageNode.setAttribute("opacity", "0.5");
11353
+ // SVG rotations in degrees
11354
+ imageNode.setAttribute("transform", "rotate(" + rotation * RAD_TO_DEG + ", " + this._x(rotatedScalingOrigin.x) + ", " + this._y(rotatedScalingOrigin.y) + ")");
11355
+ var pathNode = this.makeNode("path");
11356
+ var pathData = [];
11357
+ if (polygon.vertices.length > 0) {
11358
+ var self_1 = this;
11359
+ pathData.push("M", "" + this._x(polygon.vertices[0].x), "" + this._y(polygon.vertices[0].y));
11360
+ for (var i = 1; i < polygon.vertices.length; i++) {
11361
+ pathData.push("L", "" + this._x(polygon.vertices[i].x), "" + this._y(polygon.vertices[i].y));
11362
+ }
11363
+ }
11364
+ pathNode.setAttribute("d", pathData.join(" "));
11365
+ clipPathNode.appendChild(pathNode);
11366
+ this.bufferedNodeDefs.appendChild(clipPathNode);
11367
+ gNode.appendChild(imageNode);
11368
+ gNode.setAttribute("transform-origin", this._x(rotatedScalingOrigin.x) + " " + this._y(rotatedScalingOrigin.y));
11369
+ gNode.setAttribute("transform", "scale(" + this.scale.x + ", " + this.scale.y + ")");
11370
+ var clipNode = this.makeNode("g");
11371
+ clipNode.appendChild(gNode);
11372
+ clipNode.setAttribute("clip-path", "url(#" + clipPathId + ")");
11373
+ // TODO: check if the image class is correct here or if we should use a 'clippedImage' class here
11374
+ this._bindFillDraw(clipNode, "image", null, null); // No color, no lineWidth
11375
+ return clipNode;
11376
+ };
11146
11377
  /**
11147
11378
  * Draw the given (cubic) bézier curve.
11148
11379
  *
@@ -11535,11 +11766,12 @@ var drawutilssvg = /** @class */ (function () {
11535
11766
  * @param {XYCoords} center - The center of the crosshair.
11536
11767
  * @param {number} radius - The radius of the crosshair.
11537
11768
  * @param {string} color - The CSS color to draw the crosshair with.
11769
+ * @param {number=0.5} lineWidth - (optional, default=0.5) The line width to use.
11538
11770
  * @return {void}
11539
11771
  * @instance
11540
11772
  * @memberof drawutilssvg
11541
11773
  */
11542
- drawutilssvg.prototype.crosshair = function (center, radius, color) {
11774
+ drawutilssvg.prototype.crosshair = function (center, radius, color, lineWidth) {
11543
11775
  var node = this.makeNode("path");
11544
11776
  var d = [
11545
11777
  "M",
@@ -11556,7 +11788,40 @@ var drawutilssvg = /** @class */ (function () {
11556
11788
  this._y(center.y) + radius
11557
11789
  ];
11558
11790
  node.setAttribute("d", d.join(" "));
11559
- return this._bindFillDraw(node, "crosshair", color, 0.5);
11791
+ return this._bindFillDraw(node, "crosshair", color, lineWidth || 0.5);
11792
+ };
11793
+ /**
11794
+ * Draw a cross with diagonal axes with given radius, color and lineWidth at the given position.<br>
11795
+ * <br>
11796
+ * Note that the x's radius will not be affected by scaling.
11797
+ *
11798
+ * @method crosshair
11799
+ * @param {XYCoords} center - The center of the crosshair.
11800
+ * @param {number} radius - The radius of the crosshair.
11801
+ * @param {string} color - The CSS color to draw the crosshair with.
11802
+ * @param {number=1} lineWidth - (optional, default=1.0) The line width to use.
11803
+ * @return {void}
11804
+ * @instance
11805
+ * @memberof drawutils
11806
+ */
11807
+ drawutilssvg.prototype.cross = function (center, radius, color, lineWidth) {
11808
+ var node = this.makeNode("path");
11809
+ var d = [
11810
+ "M",
11811
+ this._x(center.x) - radius,
11812
+ this._y(center.y) - radius,
11813
+ "L",
11814
+ this._x(center.x) + radius,
11815
+ this._y(center.y) + radius,
11816
+ "M",
11817
+ this._x(center.x) - radius,
11818
+ this._y(center.y) + radius,
11819
+ "L",
11820
+ this._x(center.x) + radius,
11821
+ this._y(center.y) - radius
11822
+ ];
11823
+ node.setAttribute("d", d.join(" "));
11824
+ return this._bindFillDraw(node, "cross", color, lineWidth || 1.0);
11560
11825
  };
11561
11826
  /**
11562
11827
  * Draw a polygon.
@@ -11719,14 +11984,6 @@ var drawutilssvg = /** @class */ (function () {
11719
11984
  if (this.isSecondary) {
11720
11985
  return;
11721
11986
  }
11722
- // // Clearing an SVG is equivalent to removing all its child elements.
11723
- // for (var i = 0; i < this.gNode.childNodes.length; i++) {
11724
- // // Hide all nodes here. Don't throw them away.
11725
- // // We can probably re-use them in the next draw cycle.
11726
- // var child: SVGElement = this.gNode.childNodes[i] as SVGElement;
11727
- // this.cache.set(child.getAttribute("id"), child);
11728
- // }
11729
- // this.removeAllChildNodes();
11730
11987
  // Add a covering rect with the given background color
11731
11988
  this.curId = "background";
11732
11989
  this.curClassName = undefined;
@@ -11752,6 +12009,9 @@ var drawutilssvg = /** @class */ (function () {
11752
12009
  while (this.bufferGNode.lastChild) {
11753
12010
  this.bufferGNode.removeChild(this.bufferGNode.lastChild);
11754
12011
  }
12012
+ while (this.bufferedNodeDefs.lastChild) {
12013
+ this.bufferedNodeDefs.removeChild(this.bufferedNodeDefs.lastChild);
12014
+ }
11755
12015
  };
11756
12016
  /**
11757
12017
  * Create a new and empty `SVGElement` &lt;svg&gt; in the svg-namespace.