plotboilerplate 1.12.8 → 1.14.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 (98) hide show
  1. package/README.md +4 -1
  2. package/changelog.md +26 -0
  3. package/dist/index.esm.js +292 -51
  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 +306 -50
  10. package/dist/plotboilerplate.min.js +1 -1
  11. package/package.json +1 -1
  12. package/src/cjs/BezierPath.d.ts +12 -1
  13. package/src/cjs/BezierPath.js +34 -5
  14. package/src/cjs/BezierPath.js.map +1 -1
  15. package/src/cjs/PBText.d.ts +116 -0
  16. package/src/cjs/PBText.js +66 -0
  17. package/src/cjs/PBText.js.map +1 -0
  18. package/src/cjs/PlotBoilerplate.d.ts +2 -1
  19. package/src/cjs/PlotBoilerplate.js +41 -14
  20. package/src/cjs/PlotBoilerplate.js.map +1 -1
  21. package/src/cjs/Vertex.d.ts +18 -4
  22. package/src/cjs/Vertex.js +24 -7
  23. package/src/cjs/Vertex.js.map +1 -1
  24. package/src/cjs/draw.d.ts +30 -2
  25. package/src/cjs/draw.js +51 -6
  26. package/src/cjs/draw.js.map +1 -1
  27. package/src/cjs/drawgl.d.ts +29 -2
  28. package/src/cjs/drawgl.js +21 -4
  29. package/src/cjs/drawgl.js.map +1 -1
  30. package/src/cjs/drawutilssvg.d.ts +25 -7
  31. package/src/cjs/drawutilssvg.js +62 -14
  32. package/src/cjs/drawutilssvg.js.map +1 -1
  33. package/src/cjs/entry.js +1 -0
  34. package/src/cjs/index.d.ts +1 -0
  35. package/src/cjs/index.js +1 -0
  36. package/src/cjs/index.js.map +1 -1
  37. package/src/cjs/interfaces/DrawLib.d.ts +27 -6
  38. package/src/cjs/interfaces/DrawLib.js +3 -0
  39. package/src/cjs/interfaces/DrawLib.js.map +1 -1
  40. package/src/cjs/interfaces/core.d.ts +9 -1
  41. package/src/cjs/interfaces/core.js +1 -0
  42. package/src/cjs/interfaces/core.js.map +1 -1
  43. package/src/cjs/utils/datastructures/Color.d.ts +28 -15
  44. package/src/cjs/utils/datastructures/Color.js +276 -88
  45. package/src/cjs/utils/datastructures/Color.js.map +1 -1
  46. package/src/esm/BezierPath.d.ts +12 -1
  47. package/src/esm/BezierPath.js +34 -5
  48. package/src/esm/BezierPath.js.map +1 -1
  49. package/src/esm/PBText.d.ts +116 -0
  50. package/src/esm/PBText.js +61 -0
  51. package/src/esm/PBText.js.map +1 -0
  52. package/src/esm/PlotBoilerplate.d.ts +2 -1
  53. package/src/esm/PlotBoilerplate.js +41 -14
  54. package/src/esm/PlotBoilerplate.js.map +1 -1
  55. package/src/esm/Vertex.d.ts +18 -4
  56. package/src/esm/Vertex.js +24 -7
  57. package/src/esm/Vertex.js.map +1 -1
  58. package/src/esm/draw.d.ts +30 -2
  59. package/src/esm/draw.js +51 -6
  60. package/src/esm/draw.js.map +1 -1
  61. package/src/esm/drawgl.d.ts +29 -2
  62. package/src/esm/drawgl.js +21 -4
  63. package/src/esm/drawgl.js.map +1 -1
  64. package/src/esm/drawutilssvg.d.ts +25 -7
  65. package/src/esm/drawutilssvg.js +62 -14
  66. package/src/esm/drawutilssvg.js.map +1 -1
  67. package/src/esm/entry.js +1 -0
  68. package/src/esm/index.d.ts +1 -0
  69. package/src/esm/index.js +1 -0
  70. package/src/esm/index.js.map +1 -1
  71. package/src/esm/interfaces/DrawLib.d.ts +27 -6
  72. package/src/esm/interfaces/DrawLib.js +3 -0
  73. package/src/esm/interfaces/DrawLib.js.map +1 -1
  74. package/src/esm/interfaces/core.d.ts +9 -1
  75. package/src/esm/interfaces/core.js +1 -0
  76. package/src/esm/interfaces/core.js.map +1 -1
  77. package/src/esm/utils/datastructures/Color.d.ts +28 -15
  78. package/src/esm/utils/datastructures/Color.js +277 -89
  79. package/src/esm/utils/datastructures/Color.js.map +1 -1
  80. package/src/ts/BezierPath.ts +37 -5
  81. package/src/ts/PBText.ts +147 -0
  82. package/src/ts/PlotBoilerplate.ts +44 -18
  83. package/src/ts/Vertex.ts +26 -7
  84. package/src/ts/draw.ts +71 -8
  85. package/src/ts/drawgl.ts +48 -8
  86. package/src/ts/drawutilssvg.ts +94 -17
  87. package/src/ts/index.ts +1 -0
  88. package/src/ts/interfaces/DrawLib.ts +30 -4
  89. package/src/ts/interfaces/core.ts +9 -0
  90. package/src/ts/utils/datastructures/Color.ts +695 -508
  91. package/dist/plotboilerplate.browser.min.js.LICENSE.txt +0 -8
  92. package/src/ts/utils/algorithms/clearPolygonDuplicateVertices.ts~ +0 -5
  93. package/src/ts/utils/algorithms/findPolygonSelfIntersections.ts~ +0 -45
  94. package/src/ts/utils/algorithms/splitPolygonToNonIntersecting.ts~ +0 -113
  95. package/src/ts/utils/algorithms/sutherlandHodgman.ts~ +0 -88
  96. package/src/ts/utils/datastructures/Color.ts~ +0 -331
  97. package/src/ts/utils/datastructures/Girih.ts~ +0 -151
  98. package/src/ts/utils/datastructures/GirihTile.ts~ +0 -419
package/README.md CHANGED
@@ -44,12 +44,15 @@ often use for the visualization of 2D geometries. Basic features are
44
44
  - images
45
45
  ([docs](https://plotboilerplate.io/docs_typedoc/classes/pbimage.html "PBImage class"),
46
46
  [example](https://plotboilerplate.io/repo/demos/basic-PBImage "PBImage example"))
47
+ - text
48
+ ([docs](https://plotboilerplate.io/docs_typedoc/classes/pbtext.html "PBText class"),
49
+ [example](https://plotboilerplate.io/repo/demos/basic-PBText "PBText example"))
47
50
  - configuration of the canvas behavior (fullsize, interaction, raster)
48
51
  - mouse interaction (zoom, pan, drag elements)
49
52
  - keyboard interaction
50
53
  - touch interaction for dragging vertices (mobile devices: zoom, pan, drag elements)
51
54
 
52
- The compressed library has 123kb.
55
+ The compressed library has 128kb.
53
56
 
54
57
  ## Install the package via npm
55
58
 
package/changelog.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ - 2021-12-01
4
+ - Changed the type of param of `BezierPath.scale` to XYCoords.
5
+ - Added function `BezierPath.scaleXY` for non uniform scaling.
6
+ - Changed the type of param of `Vertex.scale` to XYCoords.
7
+ - Added function `Vertex.scaleXY` for non uniform scaling.
8
+ - 2021-11-24
9
+ - Speeding up the demo page with async script execution.
10
+ - Finalizing the demo page for the new `PBText` element (note: it has this name because `Text` already exists).
11
+ - 2021-11-19
12
+ - Fixing the `drawutilssvg.label(text,x,y)` position.
13
+ - Added the `color` param to the `label(...)` function.
14
+ - 2021-11-16
15
+ - Added `text` options to the `DrawConfig` interface.
16
+ - Added the `PBText` class.
17
+ - 2021-11-15
18
+ - Adding more parameters tot the `drawutilssvg.text()` function: fontSize, textAlign, fontFamily, lineHeight.
19
+ - 2021-11-12
20
+ - Adding more parameters tot the `draw.text()` function: fontSize, textAlign, fontFamily, lineHeight.
21
+ - 2021-11.07
22
+ - Changed the behavior of `darken` and `lighten`: the passed value is handled relative now which makes values much easier predictable and makes the change feel more 'natural'.
23
+ - Added tests for the Color class. There were some strange things happening the the `ligthen` and `darken` function.
24
+ - Did the same with `saturate` and `desaturate`.
25
+ - Did the same with the `fadein` and `fadeout` functions.
26
+ - Added setR, setG, setB, setH, setS, setL functions to the Color class.
27
+ - 2021-11-05
28
+ - Fixing the regex in the Color.parse() function for parsing rgba-strings.
3
29
  - 2021-10-12
4
30
  - Added `DrawConfig.bezier.pathVertex` and `DrawConfig.bezier.controlVertex` attributes, both `DrawSettigs`.
5
31
  - Added optional `fill:boolean` to `DrawSettings`. This is useful to give more control over the rendering of Bézier paths.
package/dist/index.esm.js CHANGED
@@ -358,7 +358,9 @@ class VertexListeners {
358
358
  * @modified 2020-05-26 Added functions addX(number) and addY(number).
359
359
  * @modified 2020-10-30 Changed the warnings in `sub(...)` and `add(...)` into real errors.
360
360
  * @modified 2021-03-01 Changed the second param `center` in the `rotate` function from Vertex to XYCoords.
361
- * @version 2.4.2
361
+ * @modified 2021-12-01 Changed the type of param of `scale` to XYCoords.
362
+ * @modified 2021-12-01 Added function `scaleXY` for non uniform scaling.
363
+ * @version 2.5.0
362
364
  *
363
365
  * @file Vertex
364
366
  * @public
@@ -699,20 +701,35 @@ class Vertex {
699
701
  }
700
702
  /**
701
703
  * This is a vector-like behavior and 'scales' this vertex
702
- * towards/from a given center.
704
+ * towards/from a given center by one uniform scale factor.
703
705
  *
704
706
  * @method scale
705
707
  * @param {number} factor - The factor to 'scale' this vertex; 1.0 means no change.
706
- * @param {Vertex=} center - The origin of scaling; default is (0,0).
708
+ * @param {XYCoords=} center - The origin of scaling; default is (0,0).
707
709
  * @return {Vertex} this
708
710
  * @instance
709
711
  * @memberof Vertex
710
712
  **/
711
713
  scale(factor, center) {
712
- if (!center || typeof center === "undefined")
713
- center = new Vertex(0, 0);
714
- this.x = center.x + (this.x - center.x) * factor;
715
- this.y = center.y + (this.y - center.y) * factor;
714
+ return this.scaleXY({ x: factor, y: factor }, center);
715
+ }
716
+ /**
717
+ * This is a vector-like behavior and 'scales' this vertex
718
+ * towards/from a given center by two independent x- and y- scale factors.
719
+ *
720
+ * @method scale
721
+ * @param {number} factor - The factor to 'scale' this vertex; 1.0 means no change.
722
+ * @param {XYCoords=} center - The origin of scaling; default is (0,0).
723
+ * @return {Vertex} this
724
+ * @instance
725
+ * @memberof Vertex
726
+ **/
727
+ scaleXY(factors, center) {
728
+ if (!center || typeof center === "undefined") {
729
+ center = { x: 0, y: 0 };
730
+ }
731
+ this.x = center.x + (this.x - center.x) * factors.x;
732
+ this.y = center.y + (this.y - center.y) * factors.y;
716
733
  return this;
717
734
  }
718
735
  /**
@@ -3021,6 +3038,35 @@ class BezierPath {
3021
3038
  this.updateArcLengths();
3022
3039
  return this;
3023
3040
  }
3041
+ /**
3042
+ * Scale the whole bezier path by the given uniform factor.
3043
+ *
3044
+ * @method scale
3045
+ * @param {Vertex} anchor - The scale origin to scale from.
3046
+ * @param {number} scaleFactor - The scalar to be multiplied with.
3047
+ * @instance
3048
+ * @memberof BezierPath
3049
+ * @return {BezierPath} this for chaining.
3050
+ **/
3051
+ scale(anchor, scaleFactor) {
3052
+ // var scaleFactors : XYCoords = { x : scaleFactor, y : scaleFactor };
3053
+ // for (var i = 0; i < this.bezierCurves.length; i++) {
3054
+ // var curve = this.bezierCurves[i];
3055
+ // curve.getStartPoint().scale(scaleFactor, anchor);
3056
+ // curve.getStartControlPoint().scale(scaleFactor, anchor);
3057
+ // curve.getEndControlPoint().scale(scaleFactor, anchor);
3058
+ // // Do NOT scale the end point here!
3059
+ // // Don't forget that the curves are connected and on curve's end point
3060
+ // // the the successor's start point (same instance)!
3061
+ // }
3062
+ // // Finally move the last end point (was not scaled yet)
3063
+ // if (this.bezierCurves.length > 0 && !this.adjustCircular) {
3064
+ // this.bezierCurves[this.bezierCurves.length - 1].getEndPoint().scale(scaleFactor, anchor);
3065
+ // }
3066
+ // this.updateArcLengths();
3067
+ // return this;
3068
+ return this.scaleXY({ x: scaleFactor, y: scaleFactor }, anchor);
3069
+ }
3024
3070
  /**
3025
3071
  * Scale the whole bezier path by the given (x,y)-factors.
3026
3072
  *
@@ -3031,19 +3077,19 @@ class BezierPath {
3031
3077
  * @memberof BezierPath
3032
3078
  * @return {BezierPath} this for chaining.
3033
3079
  **/
3034
- scale(anchor, scaling) {
3080
+ scaleXY(scaleFactors, anchor) {
3035
3081
  for (var i = 0; i < this.bezierCurves.length; i++) {
3036
3082
  var curve = this.bezierCurves[i];
3037
- curve.getStartPoint().scale(scaling, anchor);
3038
- curve.getStartControlPoint().scale(scaling, anchor);
3039
- curve.getEndControlPoint().scale(scaling, anchor);
3083
+ curve.getStartPoint().scaleXY(scaleFactors, anchor);
3084
+ curve.getStartControlPoint().scaleXY(scaleFactors, anchor);
3085
+ curve.getEndControlPoint().scaleXY(scaleFactors, anchor);
3040
3086
  // Do NOT scale the end point here!
3041
3087
  // Don't forget that the curves are connected and on curve's end point
3042
3088
  // the the successor's start point (same instance)!
3043
3089
  }
3044
3090
  // Finally move the last end point (was not scaled yet)
3045
3091
  if (this.bezierCurves.length > 0 && !this.adjustCircular) {
3046
- this.bezierCurves[this.bezierCurves.length - 1].getEndPoint().scale(scaling, anchor);
3092
+ this.bezierCurves[this.bezierCurves.length - 1].getEndPoint().scaleXY(scaleFactors, anchor);
3047
3093
  }
3048
3094
  this.updateArcLengths();
3049
3095
  return this;
@@ -4165,8 +4211,12 @@ CircleSector.circleSectorUtils = {
4165
4211
  * @modified 2021-03-31 Added 'ellipseSector' the the class names.
4166
4212
  * @modified 2021-03-31 Implemented buffering using a buffer <g> node and the beginDrawCycle and endDrawCycle methods.
4167
4213
  * @modified 2021-05-31 Added the `setConfiguration` function from `DrawLib`.
4168
- * @version 1.3.0
4214
+ * @modified 2021-11-15 Adding more parameters tot the `text()` function: fontSize, textAlign, fontFamily, lineHeight.
4215
+ * @modified 2021-11-19 Fixing the `label(text,x,y)` position.
4216
+ * @modified 2021-11-19 Added the `color` param to the `label(...)` function.
4217
+ * @version 1.4.0
4169
4218
  **/
4219
+ const RAD_TO_DEG = 180 / Math.PI;
4170
4220
  /**
4171
4221
  * @classdesc A helper class for basic SVG drawing operations. This class should
4172
4222
  * be compatible to the default 'draw' class.
@@ -4226,7 +4276,8 @@ class drawutilssvg {
4226
4276
  "vertex": "Vertex",
4227
4277
  "line": "Line",
4228
4278
  "vector": "Vector",
4229
- "image": "Image"
4279
+ "image": "Image",
4280
+ "text": "Text"
4230
4281
  };
4231
4282
  // Question: why isn't this working if the svgNode is created dynamically? (nodeStyle.sheet is null)
4232
4283
  const rules = [];
@@ -5006,27 +5057,65 @@ class drawutilssvg {
5006
5057
  if (!isOpen)
5007
5058
  d.push("Z");
5008
5059
  node.setAttribute("d", d.join(" "));
5009
- return this._bindFillDraw(node, "polyline", color, lineWidth || 1);
5060
+ return this._bindFillDraw(node, "polygon", color, lineWidth || 1);
5010
5061
  }
5011
5062
  /**
5012
- * Draw a text label at the given relative position.
5063
+ * Draw a text at the given relative position.
5013
5064
  *
5014
- * @method label
5065
+ * @method text
5015
5066
  * @param {string} text - The text to draw.
5016
5067
  * @param {number} x - The x-position to draw the text at.
5017
5068
  * @param {number} y - The y-position to draw the text at.
5018
- * @param {number=} rotation - The (optional) rotation in radians.
5069
+ * @param {string=} options.color - The Color to use.
5070
+ * @param {string=} options.fontFamily - The font family to use.
5071
+ * @param {number=} options.fontSize - The font size (in pixels) to use.
5072
+ * @param {FontStyle=} options.fontStyle - The font style to use.
5073
+ * @param {FontWeight=} options.fontWeight - The font weight to use.
5074
+ * @param {number=} options.lineHeight - The line height (in pixels) to use.
5075
+ * @param {number=} options.rotation - The (optional) rotation in radians.
5076
+ * @param {string=} options.textAlign - The text align to use. According to the specifiactions (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign) valid values are `"left" || "right" || "center" || "start" || "end"`.
5019
5077
  * @return {void}
5020
5078
  * @instance
5021
- * @memberof drawutilssvg
5079
+ * @memberof drawutils
5022
5080
  */
5023
5081
  text(text, x, y, options) {
5082
+ var _a, _b;
5024
5083
  options = options || {};
5025
5084
  const color = options.color || "black";
5026
- const node = this.makeNode("text");
5027
- node.setAttribute("x", `${this._x(x)}`);
5028
- node.setAttribute("y", `${this._y(y)}`);
5029
- node.innerHTML = text;
5085
+ const lineHeight = ((_b = (_a = options.lineHeight) !== null && _a !== void 0 ? _a : options.fontSize) !== null && _b !== void 0 ? _b : 0) * this.scale.x;
5086
+ // https://www.w3.org/TR/SVG/text.html#TextAnchorProperty
5087
+ // start | middle | end
5088
+ const textAlign = options.textAlign === "left" || options.textAlign === "start"
5089
+ ? "start"
5090
+ : options.textAlign === "center"
5091
+ ? "middle"
5092
+ : options.textAlign === "right" || options.textAlign === "end"
5093
+ ? "end"
5094
+ : "start";
5095
+ const transformOrigin = `${this._x(x)}px ${this._y(y)}px`;
5096
+ const translate = `translate(${this._x(x)} ${this._y(y) + lineHeight / 2})`;
5097
+ // Safari has a transform-origin/rotation bug.
5098
+ // It's essential to use rotate(r,x,y) here. "rotate(r)"" with transform-origin(x,y) won't do the job.
5099
+ // And rotate and translate cannot be used is combination on a text object.
5100
+ // So wrap the text inside a <g>, translate the <g>, and rotate the text inside.
5101
+ const rotate = options.rotation ? `rotate(${options.rotation * RAD_TO_DEG} 0 0)` : ``;
5102
+ const node = this.makeNode("g");
5103
+ const curId = this.curId;
5104
+ this.curId = curId + "_text";
5105
+ const textNode = this.makeNode("text");
5106
+ node.appendChild(textNode);
5107
+ textNode.setAttribute("font-family", options.fontFamily); // May be undefined
5108
+ textNode.setAttribute("font-size", options.fontSize ? `${options.fontSize * this.scale.x}` : null);
5109
+ textNode.setAttribute("font-style", options.fontStyle ? `${options.fontStyle}` : null);
5110
+ textNode.setAttribute("font-weight", options.fontWeight ? `${options.fontWeight}` : null);
5111
+ textNode.setAttribute("text-anchor", textAlign);
5112
+ textNode.setAttribute("transform-origin", "0 0");
5113
+ textNode.setAttribute("transform", rotate);
5114
+ node.setAttribute("transform-origin", transformOrigin);
5115
+ node.setAttribute("transform", translate);
5116
+ textNode.innerHTML = text;
5117
+ // Restore old ID
5118
+ this.curId = curId;
5030
5119
  return this._bindFillDraw(node, "text", color, 1);
5031
5120
  }
5032
5121
  /**
@@ -5037,16 +5126,21 @@ class drawutilssvg {
5037
5126
  * @param {number} x - The x-position to draw the text at.
5038
5127
  * @param {number} y - The y-position to draw the text at.
5039
5128
  * @param {number=} rotation - The (optional) rotation in radians.
5129
+ * @param {string="black"} color - The color to use (default is black).
5040
5130
  * @return {void}
5041
5131
  * @instance
5042
5132
  * @memberof drawutilssvg
5043
5133
  */
5044
- label(text, x, y, rotation) {
5134
+ label(text, x, y, rotation, color) {
5045
5135
  const node = this.makeNode("text");
5046
5136
  // For some strange reason SVG rotation transforms use degrees instead of radians
5047
- node.setAttribute("transform", `translate(${this.offset.x},${this.offset.y}), rotate(${(rotation / Math.PI) * 180})`);
5137
+ node.setAttribute("transform", `translate(${x},${y}), rotate(${((rotation || 0) / Math.PI) * 180})`);
5138
+ node.setAttribute("font-family", "Arial");
5139
+ node.setAttribute("font-size", "9pt");
5140
+ node.setAttribute("font-style", "normal");
5141
+ node.setAttribute("font-weight", "lighter");
5048
5142
  node.innerHTML = text;
5049
- return this._bindFillDraw(node, "label", "black", null);
5143
+ return this._bindFillDraw(node, "label", color || "black", null);
5050
5144
  }
5051
5145
  /**
5052
5146
  * Draw an SVG-like path given by the specified path data.
@@ -5355,7 +5449,9 @@ drawutilssvg.HEAD_XML = [
5355
5449
  * @modified 2021-02-22 Added the `path` drawing function to draw SVG path data.
5356
5450
  * @modified 2021-03-31 Added the `endDrawCycle` function from `DrawLib`.
5357
5451
  * @modified 2021-05-31 Added the `setConfiguration` function from `DrawLib`.
5358
- * @version 1.9.0
5452
+ * @modified 2021-11-12 Adding more parameters tot the `text()` function: fontSize, textAlign, fontFamily, lineHeight.
5453
+ * @modified 2021-11-19 Added the `color` param to the `label(...)` function.
5454
+ * @version 1.10.0
5359
5455
  **/
5360
5456
  // Todo: rename this class to Drawutils?
5361
5457
  /**
@@ -6010,20 +6106,62 @@ class drawutils {
6010
6106
  this.ctx.setLineDash([]);
6011
6107
  this.ctx.restore();
6012
6108
  }
6109
+ /**
6110
+ * Draw a text at the given relative position.
6111
+ *
6112
+ * @method text
6113
+ * @param {string} text - The text to draw.
6114
+ * @param {number} x - The x-position to draw the text at.
6115
+ * @param {number} y - The y-position to draw the text at.
6116
+ * @param {string=} options.color - The Color to use.
6117
+ * @param {string=} options.fontFamily - The font family to use.
6118
+ * @param {number=} options.fontSize - The font size (in pixels) to use.
6119
+ * @param {FontStyle=} options.fontStyle - The font style to use.
6120
+ * @param {FontWeight=} options.fontWeight - The font weight to use.
6121
+ * @param {number=} options.lineHeight - The line height (in pixels) to use.
6122
+ * @param {number=} options.rotation - The (optional) rotation in radians.
6123
+ * @param {string=} options.textAlign - The text align to use. According to the specifiactions (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign) valid values are `"left" || "right" || "center" || "start" || "end"`.
6124
+ * @return {void}
6125
+ * @instance
6126
+ * @memberof drawutils
6127
+ */
6013
6128
  text(text, x, y, options) {
6129
+ // See https://stackoverflow.com/a/23523697
6130
+ var _a, _b, _c;
6014
6131
  options = options || {};
6015
6132
  this.ctx.save();
6016
- x = this.offset.x + x * this.scale.x;
6017
- y = this.offset.y + y * this.scale.y;
6133
+ let relX = this.offset.x + x * this.scale.x;
6134
+ let relY = this.offset.y + y * this.scale.y;
6018
6135
  const color = options.color || "black";
6136
+ if (options.fontSize || options.fontFamily) {
6137
+ // Scaling of text only works in uniform mode
6138
+ this.ctx.font =
6139
+ (options.fontWeight ? options.fontWeight + " " : "") +
6140
+ (options.fontStyle ? options.fontStyle + " " : "") +
6141
+ (options.fontSize ? options.fontSize * this.scale.x + "px " : " ") +
6142
+ (options.fontFamily
6143
+ ? options.fontFamily.indexOf(" ") === -1
6144
+ ? options.fontFamily
6145
+ : `"${options.fontFamily}"`
6146
+ : "Arial");
6147
+ }
6148
+ if (options.textAlign) {
6149
+ this.ctx.textAlign = options.textAlign;
6150
+ }
6151
+ const rotation = (_a = options.rotation) !== null && _a !== void 0 ? _a : 0.0;
6152
+ const lineHeight = ((_c = (_b = options.lineHeight) !== null && _b !== void 0 ? _b : options.fontSize) !== null && _c !== void 0 ? _c : 0) * this.scale.x;
6153
+ this.ctx.translate(relX, relY);
6154
+ this.ctx.rotate(rotation);
6019
6155
  if (this.fillShapes) {
6020
6156
  this.ctx.fillStyle = color;
6021
- this.ctx.fillText(text, x, y);
6157
+ this.ctx.fillText(text, 0, lineHeight / 2);
6022
6158
  }
6023
6159
  else {
6024
6160
  this.ctx.strokeStyle = color;
6025
- this.ctx.strokeText(text, x, y);
6161
+ this.ctx.strokeText(text, 0, lineHeight / 2);
6026
6162
  }
6163
+ // this.ctx.translate(-relX, -relY);
6164
+ // this.ctx.rotate(-rotation); // is this necessary before 'restore()'?
6027
6165
  this.ctx.restore();
6028
6166
  }
6029
6167
  /**
@@ -6043,8 +6181,9 @@ class drawutils {
6043
6181
  */
6044
6182
  label(text, x, y, rotation, color) {
6045
6183
  this.ctx.save();
6184
+ this.ctx.font = "lighter 9pt Arial";
6046
6185
  this.ctx.translate(x, y);
6047
- if (typeof rotation != "undefined")
6186
+ if (typeof rotation !== "undefined")
6048
6187
  this.ctx.rotate(rotation);
6049
6188
  this.ctx.fillStyle = color || "black";
6050
6189
  if (this.fillShapes) {
@@ -6653,6 +6792,25 @@ class drawutilsgl {
6653
6792
  polyline(vertices, isOpen, color, lineWidth) {
6654
6793
  // NOT YET IMPLEMENTED
6655
6794
  }
6795
+ /**
6796
+ * Draw a text at the given relative position.
6797
+ *
6798
+ * @method text
6799
+ * @param {string} text - The text to draw.
6800
+ * @param {number} x - The x-position to draw the text at.
6801
+ * @param {number} y - The y-position to draw the text at.
6802
+ * @param {string=} options.color - The Color to use.
6803
+ * @param {string=} options.fontFamily - The font family to use.
6804
+ * @param {number=} options.fontSize - The font size (in pixels) to use.
6805
+ * @param {FontStyle=} options.fontStyle - The font style to use.
6806
+ * @param {FontWeight=} options.fontWeight - The font weight to use.
6807
+ * @param {number=} options.lineHeight - The line height (in pixels) to use.
6808
+ * @param {number=} options.rotation - The (optional) rotation in radians.
6809
+ * @param {string=} options.textAlign - The text align to use. According to the specifiactions (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign) valid values are `"left" || "right" || "center" || "start" || "end"`.
6810
+ * @return {void}
6811
+ * @instance
6812
+ * @memberof drawutils
6813
+ */
6656
6814
  text(text, x, y, options) {
6657
6815
  // NOT YET IMPLEMENTED
6658
6816
  }
@@ -6664,14 +6822,12 @@ class drawutilsgl {
6664
6822
  * @param {number} x - The x-position to draw the text at.
6665
6823
  * @param {number} y - The y-position to draw the text at.
6666
6824
  * @param {number=} rotation - The (aoptional) rotation in radians.
6825
+ * @param {string="black"} color - The color to use (default is black).
6667
6826
  * @return {void}
6668
6827
  * @instance
6669
6828
  * @memberof drawutils
6670
6829
  */
6671
- // +---------------------------------------------------------------------------------
6672
- // | Draw a non-scaling text label at the given position.
6673
- // +-------------------------------
6674
- label(text, x, y, rotation) {
6830
+ label(text, x, y, rotation, color) {
6675
6831
  // NOT YET IMPLEMENTED
6676
6832
  }
6677
6833
  /**
@@ -8265,6 +8421,65 @@ class PBImage {
8265
8421
  ;
8266
8422
  }
8267
8423
 
8424
+ /**
8425
+ * @author Ikaros Kappler
8426
+ * @date 2021-11-16
8427
+ * @version 1.0.0
8428
+ **/
8429
+ /**
8430
+ * @classdesc A simple text element: position, fontSize, fontFamily, color, textAlign, lineHeight and rotation.
8431
+ *
8432
+ * @requires FontOptions
8433
+ * @requires FontSize
8434
+ * @requires FontStyle
8435
+ * @requires FontWeight
8436
+ * @requires Vertex
8437
+ * @requires SVGSerializale
8438
+ * @requires UID
8439
+ * @requires UIDGenerator
8440
+ **/
8441
+ class PBText {
8442
+ /**
8443
+ * Create a new circle with given center point and radius.
8444
+ *
8445
+ * @constructor
8446
+ * @name Circle
8447
+ * @param {Vertex} center - The center point of the circle.
8448
+ * @param {number} radius - The radius of the circle.
8449
+ */
8450
+ constructor(text, anchor, options) {
8451
+ /**
8452
+ * Required to generate proper CSS classes and other class related IDs.
8453
+ **/
8454
+ this.className = "PBText";
8455
+ this.uid = UIDGenerator.next();
8456
+ this.text = text;
8457
+ this.anchor = anchor !== null && anchor !== void 0 ? anchor : new Vertex();
8458
+ this.color = options.color;
8459
+ this.fontFamily = options.fontFamily;
8460
+ this.fontSize = options.fontSize;
8461
+ this.fontStyle = options.fontStyle;
8462
+ this.fontWeight = options.fontWeight;
8463
+ this.lineHeight = options.lineHeight;
8464
+ this.textAlign = options.textAlign;
8465
+ this.rotation = options.rotation;
8466
+ }
8467
+ /**
8468
+ * Create an SVG representation of this circle.
8469
+ *
8470
+ * @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
8471
+ * @method toSVGString
8472
+ * @param {object=} options - An optional set of options, like 'className'.
8473
+ * @return {string} A string representing the SVG code for this vertex.
8474
+ * @instance
8475
+ * @memberof Circle
8476
+ */
8477
+ toSVGString(options) {
8478
+ console.warn("[PBText.toSVGString()] This function is not implemented as it defines a deprecated method. Use the 'drawutilssvg.text()' method instead.");
8479
+ return "";
8480
+ }
8481
+ } // END class
8482
+
8268
8483
  /* Port from AlloyFinger v0.1.15
8269
8484
  * Original by dntzhang
8270
8485
  * Typescript port by Ikaros Kappler
@@ -9394,7 +9609,8 @@ VEllipseSector.ellipseSectorUtils = {
9394
9609
  * @modified 2021-03-03 Added the `VEllipseSector` drawable.
9395
9610
  * @modified 2021-03-29 Clearing `currentClassName` and `currentId` after drawing each drawable.
9396
9611
  * @modified 2021-04-25 Extending `remove` to accept arrays of drawables.
9397
- * @version 1.14.0
9612
+ * @modified 2021-11-16 Adding the `PBText` drawable.
9613
+ * @version 1.15.0
9398
9614
  *
9399
9615
  * @file PlotBoilerplate
9400
9616
  * @fileoverview The main class.
@@ -9639,6 +9855,12 @@ class PlotBoilerplate {
9639
9855
  image: {
9640
9856
  color: "#a8a8a8",
9641
9857
  lineWidth: 1
9858
+ },
9859
+ text: {
9860
+ color: "rgba(192,0,128,0.5)",
9861
+ lineWidth: 1,
9862
+ fill: true,
9863
+ anchor: true
9642
9864
  }
9643
9865
  }; // END drawConfig
9644
9866
  // +---------------------------------------------------------------------------------
@@ -9760,7 +9982,7 @@ class PlotBoilerplate {
9760
9982
  var blob = new Blob([svgCode], { type: "image/svg;charset=utf-8" });
9761
9983
  // See documentation for FileSaver.js for usage.
9762
9984
  // https://github.com/eligrey/FileSaver.js
9763
- if (typeof globalThis["saveAs"] != "function")
9985
+ if (typeof globalThis["saveAs"] !== "function")
9764
9986
  throw "Cannot save file; did you load the ./utils/savefile helper function and the eligrey/SaveFile library?";
9765
9987
  var _saveAs = globalThis["saveAs"];
9766
9988
  _saveAs(blob, "plotboilerplate.svg");
@@ -9866,7 +10088,6 @@ class PlotBoilerplate {
9866
10088
  add(drawable, redraw) {
9867
10089
  if (Array.isArray(drawable)) {
9868
10090
  const arr = drawable;
9869
- // for( var i in arr )
9870
10091
  for (var i = 0; i < arr.length; i++) {
9871
10092
  this.add(arr[i], false);
9872
10093
  }
@@ -9912,9 +10133,9 @@ class PlotBoilerplate {
9912
10133
  }
9913
10134
  else if (drawable instanceof Polygon) {
9914
10135
  this.drawables.push(drawable);
9915
- // for( var i in drawable.vertices )
9916
- for (var i = 0; i < drawable.vertices.length; i++)
10136
+ for (var i = 0; i < drawable.vertices.length; i++) {
9917
10137
  this.vertices.push(drawable.vertices[i]);
10138
+ }
9918
10139
  }
9919
10140
  else if (drawable instanceof Triangle) {
9920
10141
  this.drawables.push(drawable);
@@ -9926,8 +10147,9 @@ class PlotBoilerplate {
9926
10147
  this.drawables.push(drawable);
9927
10148
  const bezierPath = drawable;
9928
10149
  for (var i = 0; i < bezierPath.bezierCurves.length; i++) {
9929
- if (!drawable.adjustCircular && i == 0)
10150
+ if (!drawable.adjustCircular && i == 0) {
9930
10151
  this.vertices.push(bezierPath.bezierCurves[i].startPoint);
10152
+ }
9931
10153
  this.vertices.push(bezierPath.bezierCurves[i].endPoint);
9932
10154
  this.vertices.push(bezierPath.bezierCurves[i].startControlPoint);
9933
10155
  this.vertices.push(bezierPath.bezierCurves[i].endControlPoint);
@@ -9946,6 +10168,11 @@ class PlotBoilerplate {
9946
10168
  });
9947
10169
  drawable.lowerRight.attr.selectable = false;
9948
10170
  }
10171
+ else if (drawable instanceof PBText) {
10172
+ this.vertices.push(drawable.anchor);
10173
+ this.drawables.push(drawable);
10174
+ drawable.anchor.attr.selectable = false;
10175
+ }
9949
10176
  else {
9950
10177
  throw "Cannot add drawable of unrecognized type: " + typeof drawable + ".";
9951
10178
  }
@@ -10044,6 +10271,9 @@ class PlotBoilerplate {
10044
10271
  this.removeVertex(drawable.upperLeft, false);
10045
10272
  this.removeVertex(drawable.lowerRight, false);
10046
10273
  }
10274
+ else if (drawable instanceof PBText) {
10275
+ this.removeVertex(drawable.anchor, false);
10276
+ }
10047
10277
  } // END removeWithVertices
10048
10278
  if (redraw) {
10049
10279
  this.redraw();
@@ -10065,8 +10295,9 @@ class PlotBoilerplate {
10065
10295
  for (var i = 0; i < this.vertices.length; i++) {
10066
10296
  if (this.vertices[i] === vert) {
10067
10297
  this.vertices.splice(i, 1);
10068
- if (redraw)
10298
+ if (redraw) {
10069
10299
  this.redraw();
10300
+ }
10070
10301
  return;
10071
10302
  }
10072
10303
  }
@@ -10369,6 +10600,16 @@ class PlotBoilerplate {
10369
10600
  d.lowerRight.attr.renderTime = renderTime;
10370
10601
  }
10371
10602
  }
10603
+ else if (d instanceof PBText) {
10604
+ fill.setCurrentId(d.uid);
10605
+ fill.text(d.text, d.anchor.x, d.anchor.y, d);
10606
+ if (this.drawConfig.text.anchor) {
10607
+ draw.setCurrentId(`${d.uid}_a0`);
10608
+ draw.setCurrentClassName(`${d.className}-anchor`);
10609
+ (this.drawConfig.text.fill ? fill : draw).point(d.anchor, this.drawConfig.text.color);
10610
+ }
10611
+ d.anchor.attr.renderTime = renderTime;
10612
+ }
10372
10613
  else {
10373
10614
  console.error("Cannot draw object. Unknown class.");
10374
10615
  }
@@ -10647,7 +10888,6 @@ class PlotBoilerplate {
10647
10888
  // Apply the zoom (the tolerant area should not shrink or grow when zooming)
10648
10889
  tolerance /= _self.draw.scale.x;
10649
10890
  // Search in vertices
10650
- // for( var vindex in _self.vertices ) {
10651
10891
  for (var vindex = 0; vindex < _self.vertices.length; vindex++) {
10652
10892
  var vert = _self.vertices[vindex];
10653
10893
  if ((vert.attr.draggable || vert.attr.selectable) && vert.distance(point) < tolerance) {
@@ -10667,10 +10907,7 @@ class PlotBoilerplate {
10667
10907
  * @return {void}
10668
10908
  **/
10669
10909
  handleClick(e) {
10670
- // x:number,y:number) {
10671
10910
  const _self = this;
10672
- // const x:number = e.params.pos.x;
10673
- //const y:number = e.params.pos.y;
10674
10911
  var p = this.locatePointNear(_self.transformMousePosition(e.params.pos.x, e.params.pos.y), PlotBoilerplate.DEFAULT_CLICK_TOLERANCE / Math.min(_self.config.cssScaleX, _self.config.cssScaleY));
10675
10912
  if (p) {
10676
10913
  _self.vertices[p.vindex].listeners.fireClickEvent(e);
@@ -10687,7 +10924,7 @@ class PlotBoilerplate {
10687
10924
  }
10688
10925
  _self.redraw();
10689
10926
  }
10690
- else if (this.keyHandler.isDown("y") /* && p.type=='bpath' && (p.pid==BezierPath.START_POINT || p.pid==BezierPath.END_POINT) */) {
10927
+ else if (this.keyHandler.isDown("y")) {
10691
10928
  _self.vertices[p.vindex].attr.bezierAutoAdjust = !_self.vertices[p.vindex].attr.bezierAutoAdjust;
10692
10929
  _self.redraw();
10693
10930
  }
@@ -10985,6 +11222,7 @@ class PlotBoilerplate {
10985
11222
  _self.draggedElements = [];
10986
11223
  };
10987
11224
  const afProps = {
11225
+ // touchStart: (evt: TouchEvent) => {
10988
11226
  touchStart: (evt) => {
10989
11227
  if (evt.touches.length == 1) {
10990
11228
  touchMovePos = new Vertex(relPos({ x: evt.touches[0].clientX, y: evt.touches[0].clientY }));
@@ -11087,10 +11325,13 @@ class PlotBoilerplate {
11087
11325
  _self.redraw();
11088
11326
  }
11089
11327
  }; // END afProps
11090
- if (window["createAlloyFinger"])
11328
+ if (window["createAlloyFinger"]) {
11091
11329
  window["createAlloyFinger"](this.eventCatcher ? this.eventCatcher : this.canvas, afProps);
11092
- else
11330
+ }
11331
+ else {
11332
+ /* tslint:disable-next-line */
11093
11333
  new AlloyFinger(this.eventCatcher ? this.eventCatcher : this.canvas, afProps);
11334
+ }
11094
11335
  }
11095
11336
  catch (e) {
11096
11337
  console.error("Failed to initialize AlloyFinger!");
@@ -11453,5 +11694,5 @@ class SVGBuilder {
11453
11694
  ;
11454
11695
  }
11455
11696
 
11456
- export { BezierPath, Bounds, Circle, CircleSector, CubicBezierCurve, Grid, KeyHandler, Line, MouseHandler, PBImage, PlotBoilerplate, Polygon, SVGBuilder, Triangle, UIDGenerator, VEllipse, VEllipseSector, Vector, VertTuple, Vertex, VertexAttr, VertexListeners, XMouseEvent, XWheelEvent, drawutils, drawutilsgl, drawutilssvg, geomutils };
11697
+ export { BezierPath, Bounds, Circle, CircleSector, CubicBezierCurve, Grid, KeyHandler, Line, MouseHandler, PBImage, PBText, PlotBoilerplate, Polygon, SVGBuilder, Triangle, UIDGenerator, VEllipse, VEllipseSector, Vector, VertTuple, Vertex, VertexAttr, VertexListeners, XMouseEvent, XWheelEvent, drawutils, drawutilsgl, drawutilssvg, geomutils };
11457
11698
  //# sourceMappingURL=index.esm.js.map