plotboilerplate 1.12.9 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/changelog.md +34 -0
- package/dist/index.esm.js +435 -92
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/dist/plotboilerplate.browser.min.js +1 -1
- package/dist/plotboilerplate.browser.min.js.map +1 -1
- package/dist/plotboilerplate.js +449 -91
- package/dist/plotboilerplate.min.js +1 -1
- package/package.json +1 -1
- package/src/cjs/BezierPath.d.ts +12 -1
- package/src/cjs/BezierPath.js +34 -5
- package/src/cjs/BezierPath.js.map +1 -1
- package/src/cjs/PBText.d.ts +116 -0
- package/src/cjs/PBText.js +66 -0
- package/src/cjs/PBText.js.map +1 -0
- package/src/cjs/PlotBoilerplate.d.ts +2 -1
- package/src/cjs/PlotBoilerplate.js +43 -15
- package/src/cjs/PlotBoilerplate.js.map +1 -1
- package/src/cjs/Polygon.d.ts +22 -1
- package/src/cjs/Polygon.js +102 -39
- package/src/cjs/Polygon.js.map +1 -1
- package/src/cjs/Vertex.d.ts +42 -4
- package/src/cjs/Vertex.js +62 -7
- package/src/cjs/Vertex.js.map +1 -1
- package/src/cjs/draw.d.ts +30 -2
- package/src/cjs/draw.js +51 -6
- package/src/cjs/draw.js.map +1 -1
- package/src/cjs/drawgl.d.ts +29 -2
- package/src/cjs/drawgl.js +21 -4
- package/src/cjs/drawgl.js.map +1 -1
- package/src/cjs/drawutilssvg.d.ts +25 -7
- package/src/cjs/drawutilssvg.js +62 -14
- package/src/cjs/drawutilssvg.js.map +1 -1
- package/src/cjs/entry.js +1 -0
- package/src/cjs/index.d.ts +1 -0
- package/src/cjs/index.js +1 -0
- package/src/cjs/index.js.map +1 -1
- package/src/cjs/interfaces/DrawLib.d.ts +27 -6
- package/src/cjs/interfaces/DrawLib.js +3 -0
- package/src/cjs/interfaces/DrawLib.js.map +1 -1
- package/src/cjs/interfaces/core.d.ts +9 -1
- package/src/cjs/interfaces/core.js +1 -0
- package/src/cjs/interfaces/core.js.map +1 -1
- package/src/cjs/utils/datastructures/Color.d.ts +28 -15
- package/src/cjs/utils/datastructures/Color.js +276 -88
- package/src/cjs/utils/datastructures/Color.js.map +1 -1
- package/src/cjs/utils/findInVertexArray.d.ts +19 -0
- package/src/cjs/utils/findInVertexArray.js +29 -0
- package/src/cjs/utils/findInVertexArray.js.map +1 -0
- package/src/esm/BezierPath.d.ts +12 -1
- package/src/esm/BezierPath.js +34 -5
- package/src/esm/BezierPath.js.map +1 -1
- package/src/esm/PBText.d.ts +116 -0
- package/src/esm/PBText.js +61 -0
- package/src/esm/PBText.js.map +1 -0
- package/src/esm/PlotBoilerplate.d.ts +2 -1
- package/src/esm/PlotBoilerplate.js +43 -15
- package/src/esm/PlotBoilerplate.js.map +1 -1
- package/src/esm/Polygon.d.ts +22 -1
- package/src/esm/Polygon.js +102 -39
- package/src/esm/Polygon.js.map +1 -1
- package/src/esm/Vertex.d.ts +42 -4
- package/src/esm/Vertex.js +62 -7
- package/src/esm/Vertex.js.map +1 -1
- package/src/esm/draw.d.ts +30 -2
- package/src/esm/draw.js +51 -6
- package/src/esm/draw.js.map +1 -1
- package/src/esm/drawgl.d.ts +29 -2
- package/src/esm/drawgl.js +21 -4
- package/src/esm/drawgl.js.map +1 -1
- package/src/esm/drawutilssvg.d.ts +25 -7
- package/src/esm/drawutilssvg.js +62 -14
- package/src/esm/drawutilssvg.js.map +1 -1
- package/src/esm/entry.js +1 -0
- package/src/esm/index.d.ts +1 -0
- package/src/esm/index.js +1 -0
- package/src/esm/index.js.map +1 -1
- package/src/esm/interfaces/DrawLib.d.ts +27 -6
- package/src/esm/interfaces/DrawLib.js +3 -0
- package/src/esm/interfaces/DrawLib.js.map +1 -1
- package/src/esm/interfaces/core.d.ts +9 -1
- package/src/esm/interfaces/core.js +1 -0
- package/src/esm/interfaces/core.js.map +1 -1
- package/src/esm/utils/datastructures/Color.d.ts +28 -15
- package/src/esm/utils/datastructures/Color.js +277 -89
- package/src/esm/utils/datastructures/Color.js.map +1 -1
- package/src/esm/utils/findInVertexArray.d.ts +19 -0
- package/src/esm/utils/findInVertexArray.js +25 -0
- package/src/esm/utils/findInVertexArray.js.map +1 -0
- package/src/ts/BezierPath.ts +37 -5
- package/src/ts/PBText.ts +147 -0
- package/src/ts/PlotBoilerplate.ts +47 -19
- package/src/ts/Polygon.ts +493 -451
- package/src/ts/Vertex.ts +66 -7
- package/src/ts/draw.ts +71 -8
- package/src/ts/drawgl.ts +48 -8
- package/src/ts/drawutilssvg.ts +94 -17
- package/src/ts/index.ts +1 -0
- package/src/ts/interfaces/DrawLib.ts +30 -4
- package/src/ts/interfaces/core.ts +9 -0
- package/src/ts/utils/datastructures/Color.ts +695 -508
- package/src/ts/utils/findInVertexArray.ts +28 -0
- package/dist/plotboilerplate.browser.min.js.LICENSE.txt +0 -8
- package/src/ts/utils/algorithms/clearPolygonDuplicateVertices.ts~ +0 -5
- package/src/ts/utils/algorithms/findPolygonSelfIntersections.ts~ +0 -45
- package/src/ts/utils/algorithms/sh-tmp.ts~ +0 -59
- package/src/ts/utils/algorithms/splitPolygonToNonIntersecting.ts~ +0 -113
- package/src/ts/utils/algorithms/sutherlandHodgman.ts~ +0 -88
- package/src/ts/utils/datastructures/Color.ts~ +0 -331
- package/src/ts/utils/datastructures/Girih.ts~ +0 -151
- package/src/ts/utils/datastructures/GirihTile.ts~ +0 -419
package/dist/index.esm.js
CHANGED
|
@@ -358,7 +358,10 @@ 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
|
-
* @
|
|
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
|
+
* @modified 2021-12-17 Added the functions `lerp` and `lerpAbs` for linear interpolations.
|
|
364
|
+
* @version 2.6.0
|
|
362
365
|
*
|
|
363
366
|
* @file Vertex
|
|
364
367
|
* @public
|
|
@@ -699,20 +702,72 @@ class Vertex {
|
|
|
699
702
|
}
|
|
700
703
|
/**
|
|
701
704
|
* This is a vector-like behavior and 'scales' this vertex
|
|
702
|
-
* towards/from a given center.
|
|
705
|
+
* towards/from a given center by one uniform scale factor.
|
|
703
706
|
*
|
|
704
707
|
* @method scale
|
|
705
708
|
* @param {number} factor - The factor to 'scale' this vertex; 1.0 means no change.
|
|
706
|
-
* @param {
|
|
709
|
+
* @param {XYCoords=} center - The origin of scaling; default is (0,0).
|
|
707
710
|
* @return {Vertex} this
|
|
708
711
|
* @instance
|
|
709
712
|
* @memberof Vertex
|
|
710
713
|
**/
|
|
711
714
|
scale(factor, center) {
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
715
|
+
return this.scaleXY({ x: factor, y: factor }, center);
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Perform a linear interpolation towards the given target vertex.
|
|
719
|
+
* The amount value `t` is relative, `t=0.0` means no change, `t=1.0`
|
|
720
|
+
* means this point will be moved to the exact target position.
|
|
721
|
+
*
|
|
722
|
+
* `t=0.5` will move this point to the middle of the connecting
|
|
723
|
+
* linear segment.
|
|
724
|
+
*
|
|
725
|
+
* @param {XYCoords} target - The target position to lerp this vertex to.
|
|
726
|
+
* @param {number} t - The relative amount, usually in [0..1], but other values will work, too.
|
|
727
|
+
* @returns
|
|
728
|
+
*/
|
|
729
|
+
lerp(target, t) {
|
|
730
|
+
var diff = this.difference(target);
|
|
731
|
+
// return new Vertex(this.x + diff.x * t, this.y + diff.y * t);
|
|
732
|
+
this.x += diff.x * t;
|
|
733
|
+
this.y += diff.y * t;
|
|
734
|
+
return this;
|
|
735
|
+
}
|
|
736
|
+
/**
|
|
737
|
+
* Perform a linear interpolation towards the given target vertex (absolute variant).
|
|
738
|
+
* The amount value `t` is absolute, which means the lerp amount is a direct distance
|
|
739
|
+
* value. This point will have move the amount of the passed distance `u`.
|
|
740
|
+
*
|
|
741
|
+
* @param {XYCoords} target - The target position to lerp this vertex to.
|
|
742
|
+
* @param {number} t - The absolute move amount to use to lerping.
|
|
743
|
+
* @returns
|
|
744
|
+
*/
|
|
745
|
+
lerpAbs(target, u) {
|
|
746
|
+
var dist = this.distance(target);
|
|
747
|
+
var diff = this.difference(target);
|
|
748
|
+
var step = { x: diff.x / dist, y: diff.y / dist };
|
|
749
|
+
// return new Vertex(this.x + step.x * u, this.y + step.y * u);
|
|
750
|
+
this.x += step.x * u;
|
|
751
|
+
this.y += step.y * u;
|
|
752
|
+
return this;
|
|
753
|
+
}
|
|
754
|
+
/**
|
|
755
|
+
* This is a vector-like behavior and 'scales' this vertex
|
|
756
|
+
* towards/from a given center by two independent x- and y- scale factors.
|
|
757
|
+
*
|
|
758
|
+
* @method scale
|
|
759
|
+
* @param {number} factor - The factor to 'scale' this vertex; 1.0 means no change.
|
|
760
|
+
* @param {XYCoords=} center - The origin of scaling; default is (0,0).
|
|
761
|
+
* @return {Vertex} this
|
|
762
|
+
* @instance
|
|
763
|
+
* @memberof Vertex
|
|
764
|
+
**/
|
|
765
|
+
scaleXY(factors, center) {
|
|
766
|
+
if (!center || typeof center === "undefined") {
|
|
767
|
+
center = { x: 0, y: 0 };
|
|
768
|
+
}
|
|
769
|
+
this.x = center.x + (this.x - center.x) * factors.x;
|
|
770
|
+
this.y = center.y + (this.y - center.y) * factors.y;
|
|
716
771
|
return this;
|
|
717
772
|
}
|
|
718
773
|
/**
|
|
@@ -893,7 +948,9 @@ Vertex.utils = {
|
|
|
893
948
|
* @modified 2021-01-29 Added the `isClockwise` function.
|
|
894
949
|
* @modified 2021-01-29 Added the `area` function.
|
|
895
950
|
* @modified 2021-01-29 Changed the param type for `containsVert` from Vertex to XYCoords.
|
|
896
|
-
* @
|
|
951
|
+
* @modified 2021-12-14 Added the `perimeter()` function.
|
|
952
|
+
* @modified 2021-12-16 Added the `getEvenDistributionPolygon()` function.
|
|
953
|
+
* @version 1.8.0
|
|
897
954
|
*
|
|
898
955
|
* @file Polygon
|
|
899
956
|
* @public
|
|
@@ -924,12 +981,11 @@ class Polygon {
|
|
|
924
981
|
**/
|
|
925
982
|
this.className = "Polygon";
|
|
926
983
|
this.uid = UIDGenerator.next();
|
|
927
|
-
if (typeof vertices ==
|
|
984
|
+
if (typeof vertices == "undefined")
|
|
928
985
|
vertices = [];
|
|
929
986
|
this.vertices = vertices;
|
|
930
987
|
this.isOpen = isOpen;
|
|
931
988
|
}
|
|
932
|
-
;
|
|
933
989
|
/**
|
|
934
990
|
* Add a vertex to the end of the `vertices` array.
|
|
935
991
|
*
|
|
@@ -941,7 +997,6 @@ class Polygon {
|
|
|
941
997
|
addVertex(vert) {
|
|
942
998
|
this.vertices.push(vert);
|
|
943
999
|
}
|
|
944
|
-
;
|
|
945
1000
|
/**
|
|
946
1001
|
* Get the polygon vertex at the given position (index).
|
|
947
1002
|
*
|
|
@@ -964,7 +1019,6 @@ class Polygon {
|
|
|
964
1019
|
else
|
|
965
1020
|
return this.vertices[index % this.vertices.length];
|
|
966
1021
|
}
|
|
967
|
-
;
|
|
968
1022
|
/**
|
|
969
1023
|
* Move the polygon's vertices by the given amount.
|
|
970
1024
|
*
|
|
@@ -980,7 +1034,6 @@ class Polygon {
|
|
|
980
1034
|
}
|
|
981
1035
|
return this;
|
|
982
1036
|
}
|
|
983
|
-
;
|
|
984
1037
|
/**
|
|
985
1038
|
* Check if the given vertex is inside this polygon.<br>
|
|
986
1039
|
* <br>
|
|
@@ -1000,14 +1053,12 @@ class Polygon {
|
|
|
1000
1053
|
for (var i = 0, j = this.vertices.length - 1; i < this.vertices.length; j = i++) {
|
|
1001
1054
|
let xi = this.vertices[i].x, yi = this.vertices[i].y;
|
|
1002
1055
|
let xj = this.vertices[j].x, yj = this.vertices[j].y;
|
|
1003
|
-
var intersect =
|
|
1004
|
-
&& (vert.x < (xj - xi) * (vert.y - yi) / (yj - yi) + xi);
|
|
1056
|
+
var intersect = yi > vert.y != yj > vert.y && vert.x < ((xj - xi) * (vert.y - yi)) / (yj - yi) + xi;
|
|
1005
1057
|
if (intersect)
|
|
1006
1058
|
inside = !inside;
|
|
1007
1059
|
}
|
|
1008
1060
|
return inside;
|
|
1009
1061
|
}
|
|
1010
|
-
;
|
|
1011
1062
|
/**
|
|
1012
1063
|
* Calculate the area of the given polygon (unsigned).
|
|
1013
1064
|
*
|
|
@@ -1021,7 +1072,6 @@ class Polygon {
|
|
|
1021
1072
|
area() {
|
|
1022
1073
|
return Polygon.utils.area(this.vertices);
|
|
1023
1074
|
}
|
|
1024
|
-
;
|
|
1025
1075
|
/**
|
|
1026
1076
|
* Calulate the signed polyon area by interpreting the polygon as a matrix
|
|
1027
1077
|
* and calculating its determinant.
|
|
@@ -1034,7 +1084,6 @@ class Polygon {
|
|
|
1034
1084
|
signedArea() {
|
|
1035
1085
|
return Polygon.utils.signedArea(this.vertices);
|
|
1036
1086
|
}
|
|
1037
|
-
;
|
|
1038
1087
|
/**
|
|
1039
1088
|
* Get the winding order of this polgon: clockwise or counterclockwise.
|
|
1040
1089
|
*
|
|
@@ -1046,7 +1095,28 @@ class Polygon {
|
|
|
1046
1095
|
isClockwise() {
|
|
1047
1096
|
return Polygon.utils.signedArea(this.vertices) < 0;
|
|
1048
1097
|
}
|
|
1049
|
-
|
|
1098
|
+
/**
|
|
1099
|
+
* Get the perimeter of this polygon.
|
|
1100
|
+
* The perimeter is the absolute length of the outline.
|
|
1101
|
+
*
|
|
1102
|
+
* If this polygon is open then the last segment (connecting the first and the
|
|
1103
|
+
* last vertex) will be skipped.
|
|
1104
|
+
*
|
|
1105
|
+
* @method perimeter
|
|
1106
|
+
* @instance
|
|
1107
|
+
* @memberof Polygon
|
|
1108
|
+
* @return {number}
|
|
1109
|
+
*/
|
|
1110
|
+
perimeter() {
|
|
1111
|
+
let length = 0;
|
|
1112
|
+
for (var i = 1; i < this.vertices.length; i++) {
|
|
1113
|
+
length += this.vertices[i - 1].distance(this.vertices[i]);
|
|
1114
|
+
}
|
|
1115
|
+
if (!this.isOpen && this.vertices.length > 1) {
|
|
1116
|
+
length += this.vertices[0].distance(this.vertices[this.vertices.length - 1]);
|
|
1117
|
+
}
|
|
1118
|
+
return length;
|
|
1119
|
+
}
|
|
1050
1120
|
/**
|
|
1051
1121
|
* Scale the polygon relative to the given center.
|
|
1052
1122
|
*
|
|
@@ -1059,14 +1129,13 @@ class Polygon {
|
|
|
1059
1129
|
**/
|
|
1060
1130
|
scale(factor, center) {
|
|
1061
1131
|
for (var i in this.vertices) {
|
|
1062
|
-
if (typeof this.vertices[i].scale ==
|
|
1132
|
+
if (typeof this.vertices[i].scale == "function")
|
|
1063
1133
|
this.vertices[i].scale(factor, center);
|
|
1064
1134
|
else
|
|
1065
|
-
console.log(
|
|
1135
|
+
console.log("There seems to be a null vertex!", this.vertices[i]);
|
|
1066
1136
|
}
|
|
1067
1137
|
return this;
|
|
1068
1138
|
}
|
|
1069
|
-
;
|
|
1070
1139
|
/**
|
|
1071
1140
|
* Rotate the polygon around the given center.
|
|
1072
1141
|
*
|
|
@@ -1083,7 +1152,52 @@ class Polygon {
|
|
|
1083
1152
|
}
|
|
1084
1153
|
return this;
|
|
1085
1154
|
}
|
|
1086
|
-
|
|
1155
|
+
/**
|
|
1156
|
+
* Convert this polygon into a new polygon with n evenly distributed vertices.
|
|
1157
|
+
*
|
|
1158
|
+
* @param {number} pointCount - Must not be negative.
|
|
1159
|
+
*/
|
|
1160
|
+
getEvenDistributionPolygon(pointCount) {
|
|
1161
|
+
if (pointCount <= 0) {
|
|
1162
|
+
throw new Error("pointCount must be larger than zero; is " + pointCount + ".");
|
|
1163
|
+
}
|
|
1164
|
+
const result = new Polygon([], this.isOpen);
|
|
1165
|
+
if (this.vertices.length === 0) {
|
|
1166
|
+
return result;
|
|
1167
|
+
}
|
|
1168
|
+
// Fetch and add the start point from the source polygon
|
|
1169
|
+
let polygonPoint = new Vertex(this.vertices[0]);
|
|
1170
|
+
result.vertices.push(polygonPoint);
|
|
1171
|
+
if (this.vertices.length === 1) {
|
|
1172
|
+
return result;
|
|
1173
|
+
}
|
|
1174
|
+
const perimeter = this.perimeter();
|
|
1175
|
+
const stepSize = perimeter / pointCount;
|
|
1176
|
+
const n = this.vertices.length;
|
|
1177
|
+
let polygonIndex = 1;
|
|
1178
|
+
let nextPolygonPoint = new Vertex(this.vertices[1]);
|
|
1179
|
+
let segmentLength = polygonPoint.distance(nextPolygonPoint);
|
|
1180
|
+
let loopMax = this.isOpen ? n : n + 1;
|
|
1181
|
+
let curSegmentU = stepSize;
|
|
1182
|
+
var i = 1;
|
|
1183
|
+
while (i < pointCount && polygonIndex < loopMax) {
|
|
1184
|
+
// Check if next eq point is inside this segment
|
|
1185
|
+
if (curSegmentU < segmentLength) {
|
|
1186
|
+
let newPoint = polygonPoint.clone().lerpAbs(nextPolygonPoint, curSegmentU);
|
|
1187
|
+
result.vertices.push(newPoint);
|
|
1188
|
+
curSegmentU += stepSize;
|
|
1189
|
+
i++;
|
|
1190
|
+
}
|
|
1191
|
+
else {
|
|
1192
|
+
polygonIndex++;
|
|
1193
|
+
polygonPoint = nextPolygonPoint;
|
|
1194
|
+
nextPolygonPoint = new Vertex(this.vertices[polygonIndex % n]);
|
|
1195
|
+
curSegmentU = curSegmentU - segmentLength;
|
|
1196
|
+
segmentLength = polygonPoint.distance(nextPolygonPoint);
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
return result;
|
|
1200
|
+
}
|
|
1087
1201
|
/**
|
|
1088
1202
|
* Get the bounding box (bounds) of this polygon.
|
|
1089
1203
|
*
|
|
@@ -1095,7 +1209,6 @@ class Polygon {
|
|
|
1095
1209
|
getBounds() {
|
|
1096
1210
|
return Bounds.computeFromVertices(this.vertices);
|
|
1097
1211
|
}
|
|
1098
|
-
;
|
|
1099
1212
|
/**
|
|
1100
1213
|
* Convert this polygon to a sequence of quadratic Bézier curves.<br>
|
|
1101
1214
|
* <br>
|
|
@@ -1127,7 +1240,6 @@ class Polygon {
|
|
|
1127
1240
|
}
|
|
1128
1241
|
return qbezier;
|
|
1129
1242
|
}
|
|
1130
|
-
;
|
|
1131
1243
|
/**
|
|
1132
1244
|
* Convert this polygon to a quadratic bezier curve, represented as an SVG data string.
|
|
1133
1245
|
*
|
|
@@ -1140,13 +1252,12 @@ class Polygon {
|
|
|
1140
1252
|
var qdata = this.toQuadraticBezierData();
|
|
1141
1253
|
if (qdata.length == 0)
|
|
1142
1254
|
return "";
|
|
1143
|
-
var buffer = [
|
|
1255
|
+
var buffer = ["M " + qdata[0].x + " " + qdata[0].y];
|
|
1144
1256
|
for (var i = 1; i < qdata.length; i += 2) {
|
|
1145
|
-
buffer.push(
|
|
1257
|
+
buffer.push("Q " + qdata[i].x + " " + qdata[i].y + ", " + qdata[i + 1].x + " " + qdata[i + 1].y);
|
|
1146
1258
|
}
|
|
1147
|
-
return buffer.join(
|
|
1259
|
+
return buffer.join(" ");
|
|
1148
1260
|
}
|
|
1149
|
-
;
|
|
1150
1261
|
/**
|
|
1151
1262
|
* Convert this polygon to a sequence of cubic Bézier curves.<br>
|
|
1152
1263
|
* <br>
|
|
@@ -1163,7 +1274,7 @@ class Polygon {
|
|
|
1163
1274
|
* @memberof Polygon
|
|
1164
1275
|
**/
|
|
1165
1276
|
toCubicBezierData(threshold) {
|
|
1166
|
-
if (typeof threshold ==
|
|
1277
|
+
if (typeof threshold == "undefined")
|
|
1167
1278
|
threshold = 1.0;
|
|
1168
1279
|
if (this.vertices.length < 3)
|
|
1169
1280
|
return [];
|
|
@@ -1187,7 +1298,6 @@ class Polygon {
|
|
|
1187
1298
|
}
|
|
1188
1299
|
return cbezier;
|
|
1189
1300
|
}
|
|
1190
|
-
;
|
|
1191
1301
|
/**
|
|
1192
1302
|
* Convert this polygon to a cubic bezier curve, represented as an SVG data string.
|
|
1193
1303
|
*
|
|
@@ -1200,13 +1310,23 @@ class Polygon {
|
|
|
1200
1310
|
var qdata = this.toCubicBezierData(threshold);
|
|
1201
1311
|
if (qdata.length == 0)
|
|
1202
1312
|
return "";
|
|
1203
|
-
var buffer = [
|
|
1313
|
+
var buffer = ["M " + qdata[0].x + " " + qdata[0].y];
|
|
1204
1314
|
for (var i = 1; i < qdata.length; i += 3) {
|
|
1205
|
-
buffer.push(
|
|
1206
|
-
|
|
1207
|
-
|
|
1315
|
+
buffer.push("C " +
|
|
1316
|
+
qdata[i].x +
|
|
1317
|
+
" " +
|
|
1318
|
+
qdata[i].y +
|
|
1319
|
+
", " +
|
|
1320
|
+
qdata[i + 1].x +
|
|
1321
|
+
" " +
|
|
1322
|
+
qdata[i + 1].y +
|
|
1323
|
+
", " +
|
|
1324
|
+
qdata[i + 2].x +
|
|
1325
|
+
" " +
|
|
1326
|
+
qdata[i + 2].y);
|
|
1327
|
+
}
|
|
1328
|
+
return buffer.join(" ");
|
|
1208
1329
|
}
|
|
1209
|
-
;
|
|
1210
1330
|
/**
|
|
1211
1331
|
* Convert this polygon to a cubic bezier path instance.
|
|
1212
1332
|
*
|
|
@@ -1225,7 +1345,6 @@ class Polygon {
|
|
|
1225
1345
|
}
|
|
1226
1346
|
return BezierPath.fromArray(pathdata);
|
|
1227
1347
|
}
|
|
1228
|
-
;
|
|
1229
1348
|
/**
|
|
1230
1349
|
* Create an SVG representation of this polygon.
|
|
1231
1350
|
*
|
|
@@ -1239,29 +1358,28 @@ class Polygon {
|
|
|
1239
1358
|
toSVGString(options) {
|
|
1240
1359
|
options = options || {};
|
|
1241
1360
|
var buffer = [];
|
|
1242
|
-
buffer.push(
|
|
1361
|
+
buffer.push("<path");
|
|
1243
1362
|
if (options.className)
|
|
1244
1363
|
buffer.push(' class="' + options.className + '"');
|
|
1245
1364
|
buffer.push(' d="');
|
|
1246
1365
|
if (this.vertices.length > 0) {
|
|
1247
|
-
buffer.push(
|
|
1366
|
+
buffer.push("M ");
|
|
1248
1367
|
buffer.push(this.vertices[0].x.toString());
|
|
1249
|
-
buffer.push(
|
|
1368
|
+
buffer.push(" ");
|
|
1250
1369
|
buffer.push(this.vertices[0].y.toString());
|
|
1251
1370
|
for (var i = 1; i < this.vertices.length; i++) {
|
|
1252
|
-
buffer.push(
|
|
1371
|
+
buffer.push(" L ");
|
|
1253
1372
|
buffer.push(this.vertices[i].x.toString());
|
|
1254
|
-
buffer.push(
|
|
1373
|
+
buffer.push(" ");
|
|
1255
1374
|
buffer.push(this.vertices[i].y.toString());
|
|
1256
1375
|
}
|
|
1257
1376
|
if (!this.isOpen) {
|
|
1258
|
-
buffer.push(
|
|
1377
|
+
buffer.push(" Z");
|
|
1259
1378
|
}
|
|
1260
1379
|
}
|
|
1261
1380
|
buffer.push('" />');
|
|
1262
|
-
return buffer.join(
|
|
1381
|
+
return buffer.join("");
|
|
1263
1382
|
}
|
|
1264
|
-
;
|
|
1265
1383
|
}
|
|
1266
1384
|
Polygon.utils = {
|
|
1267
1385
|
/**
|
|
@@ -1281,8 +1399,8 @@ Polygon.utils = {
|
|
|
1281
1399
|
const addY = vertices[(i + 1) % l].y;
|
|
1282
1400
|
const subX = vertices[(i + 1) % l].x;
|
|
1283
1401
|
const subY = vertices[i].y;
|
|
1284
|
-
total +=
|
|
1285
|
-
total -=
|
|
1402
|
+
total += addX * addY * 0.5;
|
|
1403
|
+
total -= subX * subY * 0.5;
|
|
1286
1404
|
}
|
|
1287
1405
|
return Math.abs(total);
|
|
1288
1406
|
},
|
|
@@ -3021,6 +3139,35 @@ class BezierPath {
|
|
|
3021
3139
|
this.updateArcLengths();
|
|
3022
3140
|
return this;
|
|
3023
3141
|
}
|
|
3142
|
+
/**
|
|
3143
|
+
* Scale the whole bezier path by the given uniform factor.
|
|
3144
|
+
*
|
|
3145
|
+
* @method scale
|
|
3146
|
+
* @param {Vertex} anchor - The scale origin to scale from.
|
|
3147
|
+
* @param {number} scaleFactor - The scalar to be multiplied with.
|
|
3148
|
+
* @instance
|
|
3149
|
+
* @memberof BezierPath
|
|
3150
|
+
* @return {BezierPath} this for chaining.
|
|
3151
|
+
**/
|
|
3152
|
+
scale(anchor, scaleFactor) {
|
|
3153
|
+
// var scaleFactors : XYCoords = { x : scaleFactor, y : scaleFactor };
|
|
3154
|
+
// for (var i = 0; i < this.bezierCurves.length; i++) {
|
|
3155
|
+
// var curve = this.bezierCurves[i];
|
|
3156
|
+
// curve.getStartPoint().scale(scaleFactor, anchor);
|
|
3157
|
+
// curve.getStartControlPoint().scale(scaleFactor, anchor);
|
|
3158
|
+
// curve.getEndControlPoint().scale(scaleFactor, anchor);
|
|
3159
|
+
// // Do NOT scale the end point here!
|
|
3160
|
+
// // Don't forget that the curves are connected and on curve's end point
|
|
3161
|
+
// // the the successor's start point (same instance)!
|
|
3162
|
+
// }
|
|
3163
|
+
// // Finally move the last end point (was not scaled yet)
|
|
3164
|
+
// if (this.bezierCurves.length > 0 && !this.adjustCircular) {
|
|
3165
|
+
// this.bezierCurves[this.bezierCurves.length - 1].getEndPoint().scale(scaleFactor, anchor);
|
|
3166
|
+
// }
|
|
3167
|
+
// this.updateArcLengths();
|
|
3168
|
+
// return this;
|
|
3169
|
+
return this.scaleXY({ x: scaleFactor, y: scaleFactor }, anchor);
|
|
3170
|
+
}
|
|
3024
3171
|
/**
|
|
3025
3172
|
* Scale the whole bezier path by the given (x,y)-factors.
|
|
3026
3173
|
*
|
|
@@ -3031,19 +3178,19 @@ class BezierPath {
|
|
|
3031
3178
|
* @memberof BezierPath
|
|
3032
3179
|
* @return {BezierPath} this for chaining.
|
|
3033
3180
|
**/
|
|
3034
|
-
|
|
3181
|
+
scaleXY(scaleFactors, anchor) {
|
|
3035
3182
|
for (var i = 0; i < this.bezierCurves.length; i++) {
|
|
3036
3183
|
var curve = this.bezierCurves[i];
|
|
3037
|
-
curve.getStartPoint().
|
|
3038
|
-
curve.getStartControlPoint().
|
|
3039
|
-
curve.getEndControlPoint().
|
|
3184
|
+
curve.getStartPoint().scaleXY(scaleFactors, anchor);
|
|
3185
|
+
curve.getStartControlPoint().scaleXY(scaleFactors, anchor);
|
|
3186
|
+
curve.getEndControlPoint().scaleXY(scaleFactors, anchor);
|
|
3040
3187
|
// Do NOT scale the end point here!
|
|
3041
3188
|
// Don't forget that the curves are connected and on curve's end point
|
|
3042
3189
|
// the the successor's start point (same instance)!
|
|
3043
3190
|
}
|
|
3044
3191
|
// Finally move the last end point (was not scaled yet)
|
|
3045
3192
|
if (this.bezierCurves.length > 0 && !this.adjustCircular) {
|
|
3046
|
-
this.bezierCurves[this.bezierCurves.length - 1].getEndPoint().
|
|
3193
|
+
this.bezierCurves[this.bezierCurves.length - 1].getEndPoint().scaleXY(scaleFactors, anchor);
|
|
3047
3194
|
}
|
|
3048
3195
|
this.updateArcLengths();
|
|
3049
3196
|
return this;
|
|
@@ -4165,8 +4312,12 @@ CircleSector.circleSectorUtils = {
|
|
|
4165
4312
|
* @modified 2021-03-31 Added 'ellipseSector' the the class names.
|
|
4166
4313
|
* @modified 2021-03-31 Implemented buffering using a buffer <g> node and the beginDrawCycle and endDrawCycle methods.
|
|
4167
4314
|
* @modified 2021-05-31 Added the `setConfiguration` function from `DrawLib`.
|
|
4168
|
-
* @
|
|
4315
|
+
* @modified 2021-11-15 Adding more parameters tot the `text()` function: fontSize, textAlign, fontFamily, lineHeight.
|
|
4316
|
+
* @modified 2021-11-19 Fixing the `label(text,x,y)` position.
|
|
4317
|
+
* @modified 2021-11-19 Added the `color` param to the `label(...)` function.
|
|
4318
|
+
* @version 1.4.0
|
|
4169
4319
|
**/
|
|
4320
|
+
const RAD_TO_DEG = 180 / Math.PI;
|
|
4170
4321
|
/**
|
|
4171
4322
|
* @classdesc A helper class for basic SVG drawing operations. This class should
|
|
4172
4323
|
* be compatible to the default 'draw' class.
|
|
@@ -4226,7 +4377,8 @@ class drawutilssvg {
|
|
|
4226
4377
|
"vertex": "Vertex",
|
|
4227
4378
|
"line": "Line",
|
|
4228
4379
|
"vector": "Vector",
|
|
4229
|
-
"image": "Image"
|
|
4380
|
+
"image": "Image",
|
|
4381
|
+
"text": "Text"
|
|
4230
4382
|
};
|
|
4231
4383
|
// Question: why isn't this working if the svgNode is created dynamically? (nodeStyle.sheet is null)
|
|
4232
4384
|
const rules = [];
|
|
@@ -5006,27 +5158,65 @@ class drawutilssvg {
|
|
|
5006
5158
|
if (!isOpen)
|
|
5007
5159
|
d.push("Z");
|
|
5008
5160
|
node.setAttribute("d", d.join(" "));
|
|
5009
|
-
return this._bindFillDraw(node, "
|
|
5161
|
+
return this._bindFillDraw(node, "polygon", color, lineWidth || 1);
|
|
5010
5162
|
}
|
|
5011
5163
|
/**
|
|
5012
|
-
* Draw a text
|
|
5164
|
+
* Draw a text at the given relative position.
|
|
5013
5165
|
*
|
|
5014
|
-
* @method
|
|
5166
|
+
* @method text
|
|
5015
5167
|
* @param {string} text - The text to draw.
|
|
5016
5168
|
* @param {number} x - The x-position to draw the text at.
|
|
5017
5169
|
* @param {number} y - The y-position to draw the text at.
|
|
5018
|
-
* @param {
|
|
5170
|
+
* @param {string=} options.color - The Color to use.
|
|
5171
|
+
* @param {string=} options.fontFamily - The font family to use.
|
|
5172
|
+
* @param {number=} options.fontSize - The font size (in pixels) to use.
|
|
5173
|
+
* @param {FontStyle=} options.fontStyle - The font style to use.
|
|
5174
|
+
* @param {FontWeight=} options.fontWeight - The font weight to use.
|
|
5175
|
+
* @param {number=} options.lineHeight - The line height (in pixels) to use.
|
|
5176
|
+
* @param {number=} options.rotation - The (optional) rotation in radians.
|
|
5177
|
+
* @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
5178
|
* @return {void}
|
|
5020
5179
|
* @instance
|
|
5021
|
-
* @memberof
|
|
5180
|
+
* @memberof drawutils
|
|
5022
5181
|
*/
|
|
5023
5182
|
text(text, x, y, options) {
|
|
5183
|
+
var _a, _b;
|
|
5024
5184
|
options = options || {};
|
|
5025
5185
|
const color = options.color || "black";
|
|
5026
|
-
const
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5186
|
+
const lineHeight = ((_b = (_a = options.lineHeight) !== null && _a !== void 0 ? _a : options.fontSize) !== null && _b !== void 0 ? _b : 0) * this.scale.x;
|
|
5187
|
+
// https://www.w3.org/TR/SVG/text.html#TextAnchorProperty
|
|
5188
|
+
// start | middle | end
|
|
5189
|
+
const textAlign = options.textAlign === "left" || options.textAlign === "start"
|
|
5190
|
+
? "start"
|
|
5191
|
+
: options.textAlign === "center"
|
|
5192
|
+
? "middle"
|
|
5193
|
+
: options.textAlign === "right" || options.textAlign === "end"
|
|
5194
|
+
? "end"
|
|
5195
|
+
: "start";
|
|
5196
|
+
const transformOrigin = `${this._x(x)}px ${this._y(y)}px`;
|
|
5197
|
+
const translate = `translate(${this._x(x)} ${this._y(y) + lineHeight / 2})`;
|
|
5198
|
+
// Safari has a transform-origin/rotation bug.
|
|
5199
|
+
// It's essential to use rotate(r,x,y) here. "rotate(r)"" with transform-origin(x,y) won't do the job.
|
|
5200
|
+
// And rotate and translate cannot be used is combination on a text object.
|
|
5201
|
+
// So wrap the text inside a <g>, translate the <g>, and rotate the text inside.
|
|
5202
|
+
const rotate = options.rotation ? `rotate(${options.rotation * RAD_TO_DEG} 0 0)` : ``;
|
|
5203
|
+
const node = this.makeNode("g");
|
|
5204
|
+
const curId = this.curId;
|
|
5205
|
+
this.curId = curId + "_text";
|
|
5206
|
+
const textNode = this.makeNode("text");
|
|
5207
|
+
node.appendChild(textNode);
|
|
5208
|
+
textNode.setAttribute("font-family", options.fontFamily); // May be undefined
|
|
5209
|
+
textNode.setAttribute("font-size", options.fontSize ? `${options.fontSize * this.scale.x}` : null);
|
|
5210
|
+
textNode.setAttribute("font-style", options.fontStyle ? `${options.fontStyle}` : null);
|
|
5211
|
+
textNode.setAttribute("font-weight", options.fontWeight ? `${options.fontWeight}` : null);
|
|
5212
|
+
textNode.setAttribute("text-anchor", textAlign);
|
|
5213
|
+
textNode.setAttribute("transform-origin", "0 0");
|
|
5214
|
+
textNode.setAttribute("transform", rotate);
|
|
5215
|
+
node.setAttribute("transform-origin", transformOrigin);
|
|
5216
|
+
node.setAttribute("transform", translate);
|
|
5217
|
+
textNode.innerHTML = text;
|
|
5218
|
+
// Restore old ID
|
|
5219
|
+
this.curId = curId;
|
|
5030
5220
|
return this._bindFillDraw(node, "text", color, 1);
|
|
5031
5221
|
}
|
|
5032
5222
|
/**
|
|
@@ -5037,16 +5227,21 @@ class drawutilssvg {
|
|
|
5037
5227
|
* @param {number} x - The x-position to draw the text at.
|
|
5038
5228
|
* @param {number} y - The y-position to draw the text at.
|
|
5039
5229
|
* @param {number=} rotation - The (optional) rotation in radians.
|
|
5230
|
+
* @param {string="black"} color - The color to use (default is black).
|
|
5040
5231
|
* @return {void}
|
|
5041
5232
|
* @instance
|
|
5042
5233
|
* @memberof drawutilssvg
|
|
5043
5234
|
*/
|
|
5044
|
-
label(text, x, y, rotation) {
|
|
5235
|
+
label(text, x, y, rotation, color) {
|
|
5045
5236
|
const node = this.makeNode("text");
|
|
5046
5237
|
// For some strange reason SVG rotation transforms use degrees instead of radians
|
|
5047
|
-
node.setAttribute("transform", `translate(${
|
|
5238
|
+
node.setAttribute("transform", `translate(${x},${y}), rotate(${((rotation || 0) / Math.PI) * 180})`);
|
|
5239
|
+
node.setAttribute("font-family", "Arial");
|
|
5240
|
+
node.setAttribute("font-size", "9pt");
|
|
5241
|
+
node.setAttribute("font-style", "normal");
|
|
5242
|
+
node.setAttribute("font-weight", "lighter");
|
|
5048
5243
|
node.innerHTML = text;
|
|
5049
|
-
return this._bindFillDraw(node, "label", "black", null);
|
|
5244
|
+
return this._bindFillDraw(node, "label", color || "black", null);
|
|
5050
5245
|
}
|
|
5051
5246
|
/**
|
|
5052
5247
|
* Draw an SVG-like path given by the specified path data.
|
|
@@ -5355,7 +5550,9 @@ drawutilssvg.HEAD_XML = [
|
|
|
5355
5550
|
* @modified 2021-02-22 Added the `path` drawing function to draw SVG path data.
|
|
5356
5551
|
* @modified 2021-03-31 Added the `endDrawCycle` function from `DrawLib`.
|
|
5357
5552
|
* @modified 2021-05-31 Added the `setConfiguration` function from `DrawLib`.
|
|
5358
|
-
* @
|
|
5553
|
+
* @modified 2021-11-12 Adding more parameters tot the `text()` function: fontSize, textAlign, fontFamily, lineHeight.
|
|
5554
|
+
* @modified 2021-11-19 Added the `color` param to the `label(...)` function.
|
|
5555
|
+
* @version 1.10.0
|
|
5359
5556
|
**/
|
|
5360
5557
|
// Todo: rename this class to Drawutils?
|
|
5361
5558
|
/**
|
|
@@ -6010,20 +6207,62 @@ class drawutils {
|
|
|
6010
6207
|
this.ctx.setLineDash([]);
|
|
6011
6208
|
this.ctx.restore();
|
|
6012
6209
|
}
|
|
6210
|
+
/**
|
|
6211
|
+
* Draw a text at the given relative position.
|
|
6212
|
+
*
|
|
6213
|
+
* @method text
|
|
6214
|
+
* @param {string} text - The text to draw.
|
|
6215
|
+
* @param {number} x - The x-position to draw the text at.
|
|
6216
|
+
* @param {number} y - The y-position to draw the text at.
|
|
6217
|
+
* @param {string=} options.color - The Color to use.
|
|
6218
|
+
* @param {string=} options.fontFamily - The font family to use.
|
|
6219
|
+
* @param {number=} options.fontSize - The font size (in pixels) to use.
|
|
6220
|
+
* @param {FontStyle=} options.fontStyle - The font style to use.
|
|
6221
|
+
* @param {FontWeight=} options.fontWeight - The font weight to use.
|
|
6222
|
+
* @param {number=} options.lineHeight - The line height (in pixels) to use.
|
|
6223
|
+
* @param {number=} options.rotation - The (optional) rotation in radians.
|
|
6224
|
+
* @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"`.
|
|
6225
|
+
* @return {void}
|
|
6226
|
+
* @instance
|
|
6227
|
+
* @memberof drawutils
|
|
6228
|
+
*/
|
|
6013
6229
|
text(text, x, y, options) {
|
|
6230
|
+
// See https://stackoverflow.com/a/23523697
|
|
6231
|
+
var _a, _b, _c;
|
|
6014
6232
|
options = options || {};
|
|
6015
6233
|
this.ctx.save();
|
|
6016
|
-
|
|
6017
|
-
|
|
6234
|
+
let relX = this.offset.x + x * this.scale.x;
|
|
6235
|
+
let relY = this.offset.y + y * this.scale.y;
|
|
6018
6236
|
const color = options.color || "black";
|
|
6237
|
+
if (options.fontSize || options.fontFamily) {
|
|
6238
|
+
// Scaling of text only works in uniform mode
|
|
6239
|
+
this.ctx.font =
|
|
6240
|
+
(options.fontWeight ? options.fontWeight + " " : "") +
|
|
6241
|
+
(options.fontStyle ? options.fontStyle + " " : "") +
|
|
6242
|
+
(options.fontSize ? options.fontSize * this.scale.x + "px " : " ") +
|
|
6243
|
+
(options.fontFamily
|
|
6244
|
+
? options.fontFamily.indexOf(" ") === -1
|
|
6245
|
+
? options.fontFamily
|
|
6246
|
+
: `"${options.fontFamily}"`
|
|
6247
|
+
: "Arial");
|
|
6248
|
+
}
|
|
6249
|
+
if (options.textAlign) {
|
|
6250
|
+
this.ctx.textAlign = options.textAlign;
|
|
6251
|
+
}
|
|
6252
|
+
const rotation = (_a = options.rotation) !== null && _a !== void 0 ? _a : 0.0;
|
|
6253
|
+
const lineHeight = ((_c = (_b = options.lineHeight) !== null && _b !== void 0 ? _b : options.fontSize) !== null && _c !== void 0 ? _c : 0) * this.scale.x;
|
|
6254
|
+
this.ctx.translate(relX, relY);
|
|
6255
|
+
this.ctx.rotate(rotation);
|
|
6019
6256
|
if (this.fillShapes) {
|
|
6020
6257
|
this.ctx.fillStyle = color;
|
|
6021
|
-
this.ctx.fillText(text,
|
|
6258
|
+
this.ctx.fillText(text, 0, lineHeight / 2);
|
|
6022
6259
|
}
|
|
6023
6260
|
else {
|
|
6024
6261
|
this.ctx.strokeStyle = color;
|
|
6025
|
-
this.ctx.strokeText(text,
|
|
6262
|
+
this.ctx.strokeText(text, 0, lineHeight / 2);
|
|
6026
6263
|
}
|
|
6264
|
+
// this.ctx.translate(-relX, -relY);
|
|
6265
|
+
// this.ctx.rotate(-rotation); // is this necessary before 'restore()'?
|
|
6027
6266
|
this.ctx.restore();
|
|
6028
6267
|
}
|
|
6029
6268
|
/**
|
|
@@ -6043,8 +6282,9 @@ class drawutils {
|
|
|
6043
6282
|
*/
|
|
6044
6283
|
label(text, x, y, rotation, color) {
|
|
6045
6284
|
this.ctx.save();
|
|
6285
|
+
this.ctx.font = "lighter 9pt Arial";
|
|
6046
6286
|
this.ctx.translate(x, y);
|
|
6047
|
-
if (typeof rotation
|
|
6287
|
+
if (typeof rotation !== "undefined")
|
|
6048
6288
|
this.ctx.rotate(rotation);
|
|
6049
6289
|
this.ctx.fillStyle = color || "black";
|
|
6050
6290
|
if (this.fillShapes) {
|
|
@@ -6653,6 +6893,25 @@ class drawutilsgl {
|
|
|
6653
6893
|
polyline(vertices, isOpen, color, lineWidth) {
|
|
6654
6894
|
// NOT YET IMPLEMENTED
|
|
6655
6895
|
}
|
|
6896
|
+
/**
|
|
6897
|
+
* Draw a text at the given relative position.
|
|
6898
|
+
*
|
|
6899
|
+
* @method text
|
|
6900
|
+
* @param {string} text - The text to draw.
|
|
6901
|
+
* @param {number} x - The x-position to draw the text at.
|
|
6902
|
+
* @param {number} y - The y-position to draw the text at.
|
|
6903
|
+
* @param {string=} options.color - The Color to use.
|
|
6904
|
+
* @param {string=} options.fontFamily - The font family to use.
|
|
6905
|
+
* @param {number=} options.fontSize - The font size (in pixels) to use.
|
|
6906
|
+
* @param {FontStyle=} options.fontStyle - The font style to use.
|
|
6907
|
+
* @param {FontWeight=} options.fontWeight - The font weight to use.
|
|
6908
|
+
* @param {number=} options.lineHeight - The line height (in pixels) to use.
|
|
6909
|
+
* @param {number=} options.rotation - The (optional) rotation in radians.
|
|
6910
|
+
* @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"`.
|
|
6911
|
+
* @return {void}
|
|
6912
|
+
* @instance
|
|
6913
|
+
* @memberof drawutils
|
|
6914
|
+
*/
|
|
6656
6915
|
text(text, x, y, options) {
|
|
6657
6916
|
// NOT YET IMPLEMENTED
|
|
6658
6917
|
}
|
|
@@ -6664,14 +6923,12 @@ class drawutilsgl {
|
|
|
6664
6923
|
* @param {number} x - The x-position to draw the text at.
|
|
6665
6924
|
* @param {number} y - The y-position to draw the text at.
|
|
6666
6925
|
* @param {number=} rotation - The (aoptional) rotation in radians.
|
|
6926
|
+
* @param {string="black"} color - The color to use (default is black).
|
|
6667
6927
|
* @return {void}
|
|
6668
6928
|
* @instance
|
|
6669
6929
|
* @memberof drawutils
|
|
6670
6930
|
*/
|
|
6671
|
-
|
|
6672
|
-
// | Draw a non-scaling text label at the given position.
|
|
6673
|
-
// +-------------------------------
|
|
6674
|
-
label(text, x, y, rotation) {
|
|
6931
|
+
label(text, x, y, rotation, color) {
|
|
6675
6932
|
// NOT YET IMPLEMENTED
|
|
6676
6933
|
}
|
|
6677
6934
|
/**
|
|
@@ -8265,6 +8522,65 @@ class PBImage {
|
|
|
8265
8522
|
;
|
|
8266
8523
|
}
|
|
8267
8524
|
|
|
8525
|
+
/**
|
|
8526
|
+
* @author Ikaros Kappler
|
|
8527
|
+
* @date 2021-11-16
|
|
8528
|
+
* @version 1.0.0
|
|
8529
|
+
**/
|
|
8530
|
+
/**
|
|
8531
|
+
* @classdesc A simple text element: position, fontSize, fontFamily, color, textAlign, lineHeight and rotation.
|
|
8532
|
+
*
|
|
8533
|
+
* @requires FontOptions
|
|
8534
|
+
* @requires FontSize
|
|
8535
|
+
* @requires FontStyle
|
|
8536
|
+
* @requires FontWeight
|
|
8537
|
+
* @requires Vertex
|
|
8538
|
+
* @requires SVGSerializale
|
|
8539
|
+
* @requires UID
|
|
8540
|
+
* @requires UIDGenerator
|
|
8541
|
+
**/
|
|
8542
|
+
class PBText {
|
|
8543
|
+
/**
|
|
8544
|
+
* Create a new circle with given center point and radius.
|
|
8545
|
+
*
|
|
8546
|
+
* @constructor
|
|
8547
|
+
* @name Circle
|
|
8548
|
+
* @param {Vertex} center - The center point of the circle.
|
|
8549
|
+
* @param {number} radius - The radius of the circle.
|
|
8550
|
+
*/
|
|
8551
|
+
constructor(text, anchor, options) {
|
|
8552
|
+
/**
|
|
8553
|
+
* Required to generate proper CSS classes and other class related IDs.
|
|
8554
|
+
**/
|
|
8555
|
+
this.className = "PBText";
|
|
8556
|
+
this.uid = UIDGenerator.next();
|
|
8557
|
+
this.text = text;
|
|
8558
|
+
this.anchor = anchor !== null && anchor !== void 0 ? anchor : new Vertex();
|
|
8559
|
+
this.color = options.color;
|
|
8560
|
+
this.fontFamily = options.fontFamily;
|
|
8561
|
+
this.fontSize = options.fontSize;
|
|
8562
|
+
this.fontStyle = options.fontStyle;
|
|
8563
|
+
this.fontWeight = options.fontWeight;
|
|
8564
|
+
this.lineHeight = options.lineHeight;
|
|
8565
|
+
this.textAlign = options.textAlign;
|
|
8566
|
+
this.rotation = options.rotation;
|
|
8567
|
+
}
|
|
8568
|
+
/**
|
|
8569
|
+
* Create an SVG representation of this circle.
|
|
8570
|
+
*
|
|
8571
|
+
* @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
|
|
8572
|
+
* @method toSVGString
|
|
8573
|
+
* @param {object=} options - An optional set of options, like 'className'.
|
|
8574
|
+
* @return {string} A string representing the SVG code for this vertex.
|
|
8575
|
+
* @instance
|
|
8576
|
+
* @memberof Circle
|
|
8577
|
+
*/
|
|
8578
|
+
toSVGString(options) {
|
|
8579
|
+
console.warn("[PBText.toSVGString()] This function is not implemented as it defines a deprecated method. Use the 'drawutilssvg.text()' method instead.");
|
|
8580
|
+
return "";
|
|
8581
|
+
}
|
|
8582
|
+
} // END class
|
|
8583
|
+
|
|
8268
8584
|
/* Port from AlloyFinger v0.1.15
|
|
8269
8585
|
* Original by dntzhang
|
|
8270
8586
|
* Typescript port by Ikaros Kappler
|
|
@@ -9394,7 +9710,8 @@ VEllipseSector.ellipseSectorUtils = {
|
|
|
9394
9710
|
* @modified 2021-03-03 Added the `VEllipseSector` drawable.
|
|
9395
9711
|
* @modified 2021-03-29 Clearing `currentClassName` and `currentId` after drawing each drawable.
|
|
9396
9712
|
* @modified 2021-04-25 Extending `remove` to accept arrays of drawables.
|
|
9397
|
-
* @
|
|
9713
|
+
* @modified 2021-11-16 Adding the `PBText` drawable.
|
|
9714
|
+
* @version 1.15.0
|
|
9398
9715
|
*
|
|
9399
9716
|
* @file PlotBoilerplate
|
|
9400
9717
|
* @fileoverview The main class.
|
|
@@ -9639,6 +9956,12 @@ class PlotBoilerplate {
|
|
|
9639
9956
|
image: {
|
|
9640
9957
|
color: "#a8a8a8",
|
|
9641
9958
|
lineWidth: 1
|
|
9959
|
+
},
|
|
9960
|
+
text: {
|
|
9961
|
+
color: "rgba(192,0,128,0.5)",
|
|
9962
|
+
lineWidth: 1,
|
|
9963
|
+
fill: true,
|
|
9964
|
+
anchor: true
|
|
9642
9965
|
}
|
|
9643
9966
|
}; // END drawConfig
|
|
9644
9967
|
// +---------------------------------------------------------------------------------
|
|
@@ -9760,7 +10083,7 @@ class PlotBoilerplate {
|
|
|
9760
10083
|
var blob = new Blob([svgCode], { type: "image/svg;charset=utf-8" });
|
|
9761
10084
|
// See documentation for FileSaver.js for usage.
|
|
9762
10085
|
// https://github.com/eligrey/FileSaver.js
|
|
9763
|
-
if (typeof globalThis["saveAs"]
|
|
10086
|
+
if (typeof globalThis["saveAs"] !== "function")
|
|
9764
10087
|
throw "Cannot save file; did you load the ./utils/savefile helper function and the eligrey/SaveFile library?";
|
|
9765
10088
|
var _saveAs = globalThis["saveAs"];
|
|
9766
10089
|
_saveAs(blob, "plotboilerplate.svg");
|
|
@@ -9866,7 +10189,6 @@ class PlotBoilerplate {
|
|
|
9866
10189
|
add(drawable, redraw) {
|
|
9867
10190
|
if (Array.isArray(drawable)) {
|
|
9868
10191
|
const arr = drawable;
|
|
9869
|
-
// for( var i in arr )
|
|
9870
10192
|
for (var i = 0; i < arr.length; i++) {
|
|
9871
10193
|
this.add(arr[i], false);
|
|
9872
10194
|
}
|
|
@@ -9912,9 +10234,9 @@ class PlotBoilerplate {
|
|
|
9912
10234
|
}
|
|
9913
10235
|
else if (drawable instanceof Polygon) {
|
|
9914
10236
|
this.drawables.push(drawable);
|
|
9915
|
-
|
|
9916
|
-
for (var i = 0; i < drawable.vertices.length; i++)
|
|
10237
|
+
for (var i = 0; i < drawable.vertices.length; i++) {
|
|
9917
10238
|
this.vertices.push(drawable.vertices[i]);
|
|
10239
|
+
}
|
|
9918
10240
|
}
|
|
9919
10241
|
else if (drawable instanceof Triangle) {
|
|
9920
10242
|
this.drawables.push(drawable);
|
|
@@ -9926,8 +10248,9 @@ class PlotBoilerplate {
|
|
|
9926
10248
|
this.drawables.push(drawable);
|
|
9927
10249
|
const bezierPath = drawable;
|
|
9928
10250
|
for (var i = 0; i < bezierPath.bezierCurves.length; i++) {
|
|
9929
|
-
if (!drawable.adjustCircular && i == 0)
|
|
10251
|
+
if (!drawable.adjustCircular && i == 0) {
|
|
9930
10252
|
this.vertices.push(bezierPath.bezierCurves[i].startPoint);
|
|
10253
|
+
}
|
|
9931
10254
|
this.vertices.push(bezierPath.bezierCurves[i].endPoint);
|
|
9932
10255
|
this.vertices.push(bezierPath.bezierCurves[i].startControlPoint);
|
|
9933
10256
|
this.vertices.push(bezierPath.bezierCurves[i].endControlPoint);
|
|
@@ -9946,6 +10269,11 @@ class PlotBoilerplate {
|
|
|
9946
10269
|
});
|
|
9947
10270
|
drawable.lowerRight.attr.selectable = false;
|
|
9948
10271
|
}
|
|
10272
|
+
else if (drawable instanceof PBText) {
|
|
10273
|
+
this.vertices.push(drawable.anchor);
|
|
10274
|
+
this.drawables.push(drawable);
|
|
10275
|
+
drawable.anchor.attr.selectable = false;
|
|
10276
|
+
}
|
|
9949
10277
|
else {
|
|
9950
10278
|
throw "Cannot add drawable of unrecognized type: " + typeof drawable + ".";
|
|
9951
10279
|
}
|
|
@@ -10044,6 +10372,9 @@ class PlotBoilerplate {
|
|
|
10044
10372
|
this.removeVertex(drawable.upperLeft, false);
|
|
10045
10373
|
this.removeVertex(drawable.lowerRight, false);
|
|
10046
10374
|
}
|
|
10375
|
+
else if (drawable instanceof PBText) {
|
|
10376
|
+
this.removeVertex(drawable.anchor, false);
|
|
10377
|
+
}
|
|
10047
10378
|
} // END removeWithVertices
|
|
10048
10379
|
if (redraw) {
|
|
10049
10380
|
this.redraw();
|
|
@@ -10065,8 +10396,9 @@ class PlotBoilerplate {
|
|
|
10065
10396
|
for (var i = 0; i < this.vertices.length; i++) {
|
|
10066
10397
|
if (this.vertices[i] === vert) {
|
|
10067
10398
|
this.vertices.splice(i, 1);
|
|
10068
|
-
if (redraw)
|
|
10399
|
+
if (redraw) {
|
|
10069
10400
|
this.redraw();
|
|
10401
|
+
}
|
|
10070
10402
|
return;
|
|
10071
10403
|
}
|
|
10072
10404
|
}
|
|
@@ -10101,8 +10433,9 @@ class PlotBoilerplate {
|
|
|
10101
10433
|
**/
|
|
10102
10434
|
getVertexNear(pixelPosition, pixelTolerance) {
|
|
10103
10435
|
var p = this.locatePointNear(this.transformMousePosition(pixelPosition.x, pixelPosition.y), pixelTolerance / Math.min(this.config.cssScaleX, this.config.cssScaleY));
|
|
10104
|
-
if (p && p.typeName == "vertex")
|
|
10436
|
+
if (p && p.typeName == "vertex") {
|
|
10105
10437
|
return this.vertices[p.vindex];
|
|
10438
|
+
}
|
|
10106
10439
|
return undefined;
|
|
10107
10440
|
}
|
|
10108
10441
|
/**
|
|
@@ -10369,6 +10702,16 @@ class PlotBoilerplate {
|
|
|
10369
10702
|
d.lowerRight.attr.renderTime = renderTime;
|
|
10370
10703
|
}
|
|
10371
10704
|
}
|
|
10705
|
+
else if (d instanceof PBText) {
|
|
10706
|
+
fill.setCurrentId(d.uid);
|
|
10707
|
+
fill.text(d.text, d.anchor.x, d.anchor.y, d);
|
|
10708
|
+
if (this.drawConfig.text.anchor) {
|
|
10709
|
+
draw.setCurrentId(`${d.uid}_a0`);
|
|
10710
|
+
draw.setCurrentClassName(`${d.className}-anchor`);
|
|
10711
|
+
(this.drawConfig.text.fill ? fill : draw).point(d.anchor, this.drawConfig.text.color);
|
|
10712
|
+
}
|
|
10713
|
+
d.anchor.attr.renderTime = renderTime;
|
|
10714
|
+
}
|
|
10372
10715
|
else {
|
|
10373
10716
|
console.error("Cannot draw object. Unknown class.");
|
|
10374
10717
|
}
|
|
@@ -10647,7 +10990,6 @@ class PlotBoilerplate {
|
|
|
10647
10990
|
// Apply the zoom (the tolerant area should not shrink or grow when zooming)
|
|
10648
10991
|
tolerance /= _self.draw.scale.x;
|
|
10649
10992
|
// Search in vertices
|
|
10650
|
-
// for( var vindex in _self.vertices ) {
|
|
10651
10993
|
for (var vindex = 0; vindex < _self.vertices.length; vindex++) {
|
|
10652
10994
|
var vert = _self.vertices[vindex];
|
|
10653
10995
|
if ((vert.attr.draggable || vert.attr.selectable) && vert.distance(point) < tolerance) {
|
|
@@ -10667,10 +11009,7 @@ class PlotBoilerplate {
|
|
|
10667
11009
|
* @return {void}
|
|
10668
11010
|
**/
|
|
10669
11011
|
handleClick(e) {
|
|
10670
|
-
// x:number,y:number) {
|
|
10671
11012
|
const _self = this;
|
|
10672
|
-
// const x:number = e.params.pos.x;
|
|
10673
|
-
//const y:number = e.params.pos.y;
|
|
10674
11013
|
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
11014
|
if (p) {
|
|
10676
11015
|
_self.vertices[p.vindex].listeners.fireClickEvent(e);
|
|
@@ -10687,7 +11026,7 @@ class PlotBoilerplate {
|
|
|
10687
11026
|
}
|
|
10688
11027
|
_self.redraw();
|
|
10689
11028
|
}
|
|
10690
|
-
else if (this.keyHandler.isDown("y")
|
|
11029
|
+
else if (this.keyHandler.isDown("y")) {
|
|
10691
11030
|
_self.vertices[p.vindex].attr.bezierAutoAdjust = !_self.vertices[p.vindex].attr.bezierAutoAdjust;
|
|
10692
11031
|
_self.redraw();
|
|
10693
11032
|
}
|
|
@@ -10985,6 +11324,7 @@ class PlotBoilerplate {
|
|
|
10985
11324
|
_self.draggedElements = [];
|
|
10986
11325
|
};
|
|
10987
11326
|
const afProps = {
|
|
11327
|
+
// touchStart: (evt: TouchEvent) => {
|
|
10988
11328
|
touchStart: (evt) => {
|
|
10989
11329
|
if (evt.touches.length == 1) {
|
|
10990
11330
|
touchMovePos = new Vertex(relPos({ x: evt.touches[0].clientX, y: evt.touches[0].clientY }));
|
|
@@ -11087,10 +11427,13 @@ class PlotBoilerplate {
|
|
|
11087
11427
|
_self.redraw();
|
|
11088
11428
|
}
|
|
11089
11429
|
}; // END afProps
|
|
11090
|
-
if (window["createAlloyFinger"])
|
|
11430
|
+
if (window["createAlloyFinger"]) {
|
|
11091
11431
|
window["createAlloyFinger"](this.eventCatcher ? this.eventCatcher : this.canvas, afProps);
|
|
11092
|
-
|
|
11432
|
+
}
|
|
11433
|
+
else {
|
|
11434
|
+
/* tslint:disable-next-line */
|
|
11093
11435
|
new AlloyFinger(this.eventCatcher ? this.eventCatcher : this.canvas, afProps);
|
|
11436
|
+
}
|
|
11094
11437
|
}
|
|
11095
11438
|
catch (e) {
|
|
11096
11439
|
console.error("Failed to initialize AlloyFinger!");
|
|
@@ -11453,5 +11796,5 @@ class SVGBuilder {
|
|
|
11453
11796
|
;
|
|
11454
11797
|
}
|
|
11455
11798
|
|
|
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 };
|
|
11799
|
+
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
11800
|
//# sourceMappingURL=index.esm.js.map
|