plotboilerplate 1.15.0 → 1.16.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/changelog.md +24 -0
- package/dist/index.esm.js +574 -428
- 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 +574 -428
- package/dist/plotboilerplate.min.js +1 -1
- package/package.json +1 -1
- package/src/cjs/BezierPath.d.ts +33 -1
- package/src/cjs/BezierPath.js +80 -13
- package/src/cjs/BezierPath.js.map +1 -1
- package/src/cjs/Circle.d.ts +25 -10
- package/src/cjs/Circle.js +38 -33
- package/src/cjs/Circle.js.map +1 -1
- package/src/cjs/CircleSector.d.ts +27 -13
- package/src/cjs/CircleSector.js +38 -23
- package/src/cjs/CircleSector.js.map +1 -1
- package/src/cjs/CubicBezierCurve.d.ts +17 -1
- package/src/cjs/CubicBezierCurve.js +78 -79
- package/src/cjs/CubicBezierCurve.js.map +1 -1
- package/src/cjs/KeyHandler.d.ts +10 -3
- package/src/cjs/KeyHandler.js +28 -23
- package/src/cjs/KeyHandler.js.map +1 -1
- package/src/cjs/Line.d.ts +2 -1
- package/src/cjs/Line.js +19 -18
- package/src/cjs/Line.js.map +1 -1
- package/src/cjs/MouseHandler.js +43 -53
- package/src/cjs/MouseHandler.js.map +1 -1
- package/src/cjs/PBImage.d.ts +16 -1
- package/src/cjs/PBImage.js +13 -3
- package/src/cjs/PBImage.js.map +1 -1
- package/src/cjs/PBText.d.ts +15 -1
- package/src/cjs/PBText.js +11 -1
- package/src/cjs/PBText.js.map +1 -1
- package/src/cjs/PlotBoilerplate.js +1 -1
- package/src/cjs/PlotBoilerplate.js.map +1 -1
- package/src/cjs/Polygon.d.ts +16 -1
- package/src/cjs/Polygon.js +37 -23
- package/src/cjs/Polygon.js.map +1 -1
- package/src/cjs/Triangle.d.ts +16 -1
- package/src/cjs/Triangle.js +50 -54
- package/src/cjs/Triangle.js.map +1 -1
- package/src/cjs/VEllipse.d.ts +16 -1
- package/src/cjs/VEllipse.js +25 -12
- package/src/cjs/VEllipse.js.map +1 -1
- package/src/cjs/VEllipseSector.d.ts +15 -1
- package/src/cjs/VEllipseSector.js +11 -1
- package/src/cjs/VEllipseSector.js.map +1 -1
- package/src/cjs/Vector.d.ts +3 -1
- package/src/cjs/Vector.js +32 -36
- package/src/cjs/Vector.js.map +1 -1
- package/src/cjs/VertTuple.d.ts +15 -1
- package/src/cjs/VertTuple.js +14 -19
- package/src/cjs/VertTuple.js.map +1 -1
- package/src/cjs/Vertex.d.ts +25 -1
- package/src/cjs/Vertex.js +38 -11
- package/src/cjs/Vertex.js.map +1 -1
- package/src/cjs/VertexListeners.d.ts +12 -8
- package/src/cjs/VertexListeners.js +18 -25
- package/src/cjs/VertexListeners.js.map +1 -1
- package/src/cjs/utils/creategui.js +1 -1
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.d.ts +15 -0
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.js +55 -28
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
- package/src/cjs/utils/io/DndFileHandler.d.ts +63 -0
- package/src/cjs/utils/io/DndFileHandler.js +112 -0
- package/src/cjs/utils/io/DndFileHandler.js.map +1 -0
- package/src/cjs/utils/io/FileDrop.d.ts +98 -0
- package/src/cjs/utils/io/FileDrop.js +142 -0
- package/src/cjs/utils/io/FileDrop.js.map +1 -0
- package/src/esm/BezierPath.d.ts +33 -1
- package/src/esm/BezierPath.js +80 -13
- package/src/esm/BezierPath.js.map +1 -1
- package/src/esm/Circle.d.ts +25 -10
- package/src/esm/Circle.js +38 -33
- package/src/esm/Circle.js.map +1 -1
- package/src/esm/CircleSector.d.ts +27 -13
- package/src/esm/CircleSector.js +38 -23
- package/src/esm/CircleSector.js.map +1 -1
- package/src/esm/CubicBezierCurve.d.ts +17 -1
- package/src/esm/CubicBezierCurve.js +78 -79
- package/src/esm/CubicBezierCurve.js.map +1 -1
- package/src/esm/KeyHandler.d.ts +10 -3
- package/src/esm/KeyHandler.js +28 -23
- package/src/esm/KeyHandler.js.map +1 -1
- package/src/esm/Line.d.ts +2 -1
- package/src/esm/Line.js +19 -18
- package/src/esm/Line.js.map +1 -1
- package/src/esm/MouseHandler.js +43 -53
- package/src/esm/MouseHandler.js.map +1 -1
- package/src/esm/PBImage.d.ts +16 -1
- package/src/esm/PBImage.js +13 -3
- package/src/esm/PBImage.js.map +1 -1
- package/src/esm/PBText.d.ts +15 -1
- package/src/esm/PBText.js +11 -1
- package/src/esm/PBText.js.map +1 -1
- package/src/esm/PlotBoilerplate.js +1 -1
- package/src/esm/PlotBoilerplate.js.map +1 -1
- package/src/esm/Polygon.d.ts +16 -1
- package/src/esm/Polygon.js +37 -23
- package/src/esm/Polygon.js.map +1 -1
- package/src/esm/Triangle.d.ts +16 -1
- package/src/esm/Triangle.js +50 -54
- package/src/esm/Triangle.js.map +1 -1
- package/src/esm/VEllipse.d.ts +16 -1
- package/src/esm/VEllipse.js +25 -12
- package/src/esm/VEllipse.js.map +1 -1
- package/src/esm/VEllipseSector.d.ts +15 -1
- package/src/esm/VEllipseSector.js +11 -1
- package/src/esm/VEllipseSector.js.map +1 -1
- package/src/esm/Vector.d.ts +3 -1
- package/src/esm/Vector.js +32 -36
- package/src/esm/Vector.js.map +1 -1
- package/src/esm/VertTuple.d.ts +15 -1
- package/src/esm/VertTuple.js +14 -19
- package/src/esm/VertTuple.js.map +1 -1
- package/src/esm/Vertex.d.ts +25 -1
- package/src/esm/Vertex.js +38 -11
- package/src/esm/Vertex.js.map +1 -1
- package/src/esm/VertexListeners.d.ts +12 -8
- package/src/esm/VertexListeners.js +18 -25
- package/src/esm/VertexListeners.js.map +1 -1
- package/src/esm/utils/helpers/BezierPathInteractionHelper.d.ts +15 -0
- package/src/esm/utils/helpers/BezierPathInteractionHelper.js +54 -28
- package/src/esm/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
- package/src/esm/utils/io/DndFileHandler.d.ts +63 -0
- package/src/esm/utils/io/DndFileHandler.js +106 -0
- package/src/esm/utils/io/DndFileHandler.js.map +1 -0
- package/src/esm/utils/io/FileDrop.d.ts +98 -0
- package/src/esm/utils/io/FileDrop.js +136 -0
- package/src/esm/utils/io/FileDrop.js.map +1 -0
- package/src/ts/BezierPath.ts +96 -11
- package/src/ts/Circle.ts +213 -200
- package/src/ts/CircleSector.ts +171 -141
- package/src/ts/CubicBezierCurve.ts +777 -810
- package/src/ts/KeyHandler.ts +221 -212
- package/src/ts/Line.ts +77 -80
- package/src/ts/MouseHandler.ts +356 -368
- package/src/ts/PBImage.ts +81 -68
- package/src/ts/PBText.ts +20 -1
- package/src/ts/PlotBoilerplate.ts +1 -1
- package/src/ts/Polygon.ts +48 -22
- package/src/ts/Triangle.ts +484 -489
- package/src/ts/VEllipse.ts +36 -11
- package/src/ts/VEllipseSector.ts +20 -1
- package/src/ts/Vector.ts +164 -160
- package/src/ts/VertTuple.ts +333 -338
- package/src/ts/Vertex.ts +52 -10
- package/src/ts/VertexListeners.ts +248 -266
- package/src/ts/utils/helpers/BezierPathInteractionHelper.ts +61 -30
- package/src/ts/utils/io/FileDrop.ts +178 -0
package/dist/index.esm.js
CHANGED
|
@@ -99,7 +99,6 @@ class VertexListeners {
|
|
|
99
99
|
this.dragEnd = [];
|
|
100
100
|
this.vertex = vertex;
|
|
101
101
|
}
|
|
102
|
-
;
|
|
103
102
|
/**
|
|
104
103
|
* Add a click listener.
|
|
105
104
|
*
|
|
@@ -113,7 +112,6 @@ class VertexListeners {
|
|
|
113
112
|
VertexListeners._addListener(this.click, listener);
|
|
114
113
|
return this;
|
|
115
114
|
}
|
|
116
|
-
;
|
|
117
115
|
/**
|
|
118
116
|
* The click listener is a function with a single drag event param.
|
|
119
117
|
* @callback VertexListeners~clickListener
|
|
@@ -132,7 +130,6 @@ class VertexListeners {
|
|
|
132
130
|
this.click = VertexListeners._removeListener(this.click, listener);
|
|
133
131
|
return this;
|
|
134
132
|
}
|
|
135
|
-
;
|
|
136
133
|
/**
|
|
137
134
|
* The click listener is a function with a single drag event param.
|
|
138
135
|
* @callback VertexListeners~clickListener
|
|
@@ -151,7 +148,6 @@ class VertexListeners {
|
|
|
151
148
|
VertexListeners._addListener(this.drag, listener);
|
|
152
149
|
return this;
|
|
153
150
|
}
|
|
154
|
-
;
|
|
155
151
|
/**
|
|
156
152
|
* The drag listener is a function with a single drag event param.
|
|
157
153
|
* @callback VertexListeners~dragListener
|
|
@@ -170,7 +166,6 @@ class VertexListeners {
|
|
|
170
166
|
this.drag = VertexListeners._removeListener(this.drag, listener);
|
|
171
167
|
return this;
|
|
172
168
|
}
|
|
173
|
-
;
|
|
174
169
|
/**
|
|
175
170
|
* Add a dragStart listener.
|
|
176
171
|
*
|
|
@@ -184,7 +179,6 @@ class VertexListeners {
|
|
|
184
179
|
VertexListeners._addListener(this.dragStart, listener);
|
|
185
180
|
return this;
|
|
186
181
|
}
|
|
187
|
-
;
|
|
188
182
|
/**
|
|
189
183
|
* The drag-start listener is a function with a single drag event param.
|
|
190
184
|
* @callback VertexListeners~dragStartListener
|
|
@@ -203,7 +197,6 @@ class VertexListeners {
|
|
|
203
197
|
this.dragStart = VertexListeners._removeListener(this.dragStart, listener);
|
|
204
198
|
return this;
|
|
205
199
|
}
|
|
206
|
-
;
|
|
207
200
|
/**
|
|
208
201
|
* Add a dragEnd listener.
|
|
209
202
|
*
|
|
@@ -218,27 +211,25 @@ class VertexListeners {
|
|
|
218
211
|
VertexListeners._addListener(this.dragEnd, listener);
|
|
219
212
|
return this;
|
|
220
213
|
}
|
|
221
|
-
;
|
|
222
214
|
/**
|
|
223
215
|
* The drag-end listener is a function with a single drag event param.
|
|
224
216
|
* @callback VertexListeners~dragEndListener
|
|
225
217
|
* @param {Event} e - The (extended) drag event.
|
|
226
218
|
*/
|
|
227
219
|
/**
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
220
|
+
* Remove a drag listener.
|
|
221
|
+
*
|
|
222
|
+
* @method removeDragEndListener
|
|
223
|
+
* @param {VertexListeners~clickListener} listener - The drag listener to remove (a callback).
|
|
224
|
+
* @return {VertexListeners} this (for chaining)
|
|
225
|
+
* @instance
|
|
226
|
+
* @memberof VertexListeners
|
|
227
|
+
**/
|
|
236
228
|
removeDragEndListener(listener) {
|
|
237
229
|
// this.drag.push( listener );
|
|
238
230
|
this.dragEnd = VertexListeners._removeListener(this.dragEnd, listener);
|
|
239
231
|
return this;
|
|
240
232
|
}
|
|
241
|
-
;
|
|
242
233
|
/**
|
|
243
234
|
* Fire a click event with the given event instance to all
|
|
244
235
|
* installed click listeners.
|
|
@@ -252,7 +243,6 @@ class VertexListeners {
|
|
|
252
243
|
fireClickEvent(e) {
|
|
253
244
|
VertexListeners._fireEvent(this, this.click, e);
|
|
254
245
|
}
|
|
255
|
-
;
|
|
256
246
|
/**
|
|
257
247
|
* Fire a drag event with the given event instance to all
|
|
258
248
|
* installed drag listeners.
|
|
@@ -266,7 +256,6 @@ class VertexListeners {
|
|
|
266
256
|
fireDragEvent(e) {
|
|
267
257
|
VertexListeners._fireEvent(this, this.drag, e);
|
|
268
258
|
}
|
|
269
|
-
;
|
|
270
259
|
/**
|
|
271
260
|
* Fire a dragStart event with the given event instance to all
|
|
272
261
|
* installed drag-start listeners.
|
|
@@ -280,7 +269,6 @@ class VertexListeners {
|
|
|
280
269
|
fireDragStartEvent(e) {
|
|
281
270
|
VertexListeners._fireEvent(this, this.dragStart, e);
|
|
282
271
|
}
|
|
283
|
-
;
|
|
284
272
|
/**
|
|
285
273
|
* Fire a dragEnd event with the given event instance to all
|
|
286
274
|
* installed drag-end listeners.
|
|
@@ -294,13 +282,21 @@ class VertexListeners {
|
|
|
294
282
|
fireDragEndEvent(e) {
|
|
295
283
|
VertexListeners._fireEvent(this, this.dragEnd, e);
|
|
296
284
|
}
|
|
297
|
-
|
|
285
|
+
/**
|
|
286
|
+
* Removes all listeners from this listeners object.
|
|
287
|
+
*/
|
|
288
|
+
removeAllListeners() {
|
|
289
|
+
this.click = [];
|
|
290
|
+
this.drag = [];
|
|
291
|
+
this.dragStart = [];
|
|
292
|
+
this.dragEnd = [];
|
|
293
|
+
}
|
|
298
294
|
/**
|
|
299
295
|
* @private
|
|
300
296
|
**/
|
|
301
297
|
static _fireEvent(_self, listeners, e) {
|
|
302
298
|
const ve = e;
|
|
303
|
-
if (typeof ve.params ==
|
|
299
|
+
if (typeof ve.params == "undefined")
|
|
304
300
|
ve.params = { vertex: _self.vertex };
|
|
305
301
|
else
|
|
306
302
|
ve.params.vertex = _self.vertex;
|
|
@@ -308,7 +304,6 @@ class VertexListeners {
|
|
|
308
304
|
listeners[i](ve);
|
|
309
305
|
}
|
|
310
306
|
}
|
|
311
|
-
;
|
|
312
307
|
/**
|
|
313
308
|
* @private
|
|
314
309
|
*/
|
|
@@ -320,7 +315,6 @@ class VertexListeners {
|
|
|
320
315
|
listeners.push(newListener);
|
|
321
316
|
return true;
|
|
322
317
|
}
|
|
323
|
-
;
|
|
324
318
|
/**
|
|
325
319
|
* @private
|
|
326
320
|
*/
|
|
@@ -331,7 +325,6 @@ class VertexListeners {
|
|
|
331
325
|
}
|
|
332
326
|
return listeners;
|
|
333
327
|
}
|
|
334
|
-
;
|
|
335
328
|
}
|
|
336
329
|
|
|
337
330
|
/**
|
|
@@ -361,7 +354,10 @@ class VertexListeners {
|
|
|
361
354
|
* @modified 2021-12-01 Changed the type of param of `scale` to XYCoords.
|
|
362
355
|
* @modified 2021-12-01 Added function `scaleXY` for non uniform scaling.
|
|
363
356
|
* @modified 2021-12-17 Added the functions `lerp` and `lerpAbs` for linear interpolations.
|
|
364
|
-
* @
|
|
357
|
+
* @modified 2022-01-31 Added `Vertex.utils.arrayToJSON`.
|
|
358
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
359
|
+
* @modified 2022-02-02 Cleared the `Vertex.toSVGString` function (deprecated). Use `drawutilssvg` instead.
|
|
360
|
+
* @version 2.7.0
|
|
365
361
|
*
|
|
366
362
|
* @file Vertex
|
|
367
363
|
* @public
|
|
@@ -856,20 +852,31 @@ class Vertex {
|
|
|
856
852
|
* @return {string} A string representing the SVG code for this vertex.
|
|
857
853
|
* @instance
|
|
858
854
|
* @memberof Vertex
|
|
855
|
+
* @deprecated
|
|
859
856
|
**/
|
|
860
857
|
toSVGString(options) {
|
|
861
|
-
options = options || {};
|
|
862
|
-
var buffer = [];
|
|
863
|
-
buffer.push("<circle");
|
|
864
|
-
if (options.className)
|
|
865
|
-
|
|
866
|
-
buffer.push('
|
|
867
|
-
buffer.push('
|
|
868
|
-
buffer.push(
|
|
869
|
-
buffer.
|
|
870
|
-
return
|
|
858
|
+
// options = options || {};
|
|
859
|
+
// var buffer = [];
|
|
860
|
+
// buffer.push("<circle");
|
|
861
|
+
// if (options.className) buffer.push(' class="' + options.className + '"');
|
|
862
|
+
// buffer.push(' cx="' + this.x + '"');
|
|
863
|
+
// buffer.push(' cy="' + this.y + '"');
|
|
864
|
+
// buffer.push(' r="2"');
|
|
865
|
+
// buffer.push(" />");
|
|
866
|
+
// return buffer.join("");
|
|
867
|
+
console.warn("[Deprecation] Warning: the Vertex.toSVGString method is deprecated and does not return and valid SVG data any more. Please use `drawutilssvg` instead.");
|
|
868
|
+
return "";
|
|
871
869
|
}
|
|
872
870
|
// END Vertex
|
|
871
|
+
/**
|
|
872
|
+
* This function should invalidate any installed listeners and invalidate this object.
|
|
873
|
+
* After calling this function the object might not hold valid data any more and
|
|
874
|
+
* should not be used.
|
|
875
|
+
*/
|
|
876
|
+
destroy() {
|
|
877
|
+
this.listeners.removeAllListeners();
|
|
878
|
+
this.isDestroyed = true;
|
|
879
|
+
}
|
|
873
880
|
/**
|
|
874
881
|
* Create a new random vertex inside the given viewport.
|
|
875
882
|
*
|
|
@@ -924,6 +931,19 @@ Vertex.utils = {
|
|
|
924
931
|
vertices.push(new Vertex(zB.x * scaleX, zB.y * scaleY));
|
|
925
932
|
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)));
|
|
926
933
|
return vertices;
|
|
934
|
+
},
|
|
935
|
+
/**
|
|
936
|
+
* Convert the given vertices (array) to a JSON string.
|
|
937
|
+
*
|
|
938
|
+
* @param {number?} precision - (optional) The numeric precision to be used (number of precision digits).
|
|
939
|
+
* @returns {string}
|
|
940
|
+
*/
|
|
941
|
+
arrayToJSON(vertices, precision) {
|
|
942
|
+
return JSON.stringify(vertices.map(function (vert) {
|
|
943
|
+
return typeof precision === undefined
|
|
944
|
+
? { x: vert.x, y: vert.y }
|
|
945
|
+
: { x: Number(vert.x.toFixed(precision)), y: Number(vert.y.toFixed(precision)) };
|
|
946
|
+
}));
|
|
927
947
|
}
|
|
928
948
|
};
|
|
929
949
|
|
|
@@ -950,7 +970,9 @@ Vertex.utils = {
|
|
|
950
970
|
* @modified 2021-01-29 Changed the param type for `containsVert` from Vertex to XYCoords.
|
|
951
971
|
* @modified 2021-12-14 Added the `perimeter()` function.
|
|
952
972
|
* @modified 2021-12-16 Added the `getEvenDistributionPolygon()` function.
|
|
953
|
-
* @
|
|
973
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
974
|
+
* @modified 2022-02-02 Cleared the `Polygon.toSVGString` function (deprecated). Use `drawutilssvg` instead.
|
|
975
|
+
* @version 1.9.0
|
|
954
976
|
*
|
|
955
977
|
* @file Polygon
|
|
956
978
|
* @public
|
|
@@ -1356,29 +1378,41 @@ class Polygon {
|
|
|
1356
1378
|
* @memberof Polygon
|
|
1357
1379
|
**/
|
|
1358
1380
|
toSVGString(options) {
|
|
1359
|
-
options = options || {};
|
|
1360
|
-
var buffer = [];
|
|
1361
|
-
buffer.push("<path");
|
|
1362
|
-
if (options.className)
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1381
|
+
// options = options || {};
|
|
1382
|
+
// var buffer: Array<string> = [];
|
|
1383
|
+
// buffer.push("<path");
|
|
1384
|
+
// if (options.className) buffer.push(' class="' + options.className + '"');
|
|
1385
|
+
// buffer.push(' d="');
|
|
1386
|
+
// if (this.vertices.length > 0) {
|
|
1387
|
+
// buffer.push("M ");
|
|
1388
|
+
// buffer.push(this.vertices[0].x.toString());
|
|
1389
|
+
// buffer.push(" ");
|
|
1390
|
+
// buffer.push(this.vertices[0].y.toString());
|
|
1391
|
+
// for (var i = 1; i < this.vertices.length; i++) {
|
|
1392
|
+
// buffer.push(" L ");
|
|
1393
|
+
// buffer.push(this.vertices[i].x.toString());
|
|
1394
|
+
// buffer.push(" ");
|
|
1395
|
+
// buffer.push(this.vertices[i].y.toString());
|
|
1396
|
+
// }
|
|
1397
|
+
// if (!this.isOpen) {
|
|
1398
|
+
// buffer.push(" Z");
|
|
1399
|
+
// }
|
|
1400
|
+
// }
|
|
1401
|
+
// buffer.push('" />');
|
|
1402
|
+
// return buffer.join("");
|
|
1403
|
+
console.warn("[Deprecation] Warning: the Polygon.toSVGString method is deprecated and does not return and valid SVG data any more. Please use `drawutilssvg` instead.");
|
|
1404
|
+
return "";
|
|
1405
|
+
}
|
|
1406
|
+
/**
|
|
1407
|
+
* This function should invalidate any installed listeners and invalidate this object.
|
|
1408
|
+
* After calling this function the object might not hold valid data any more and
|
|
1409
|
+
* should not be used.
|
|
1410
|
+
*/
|
|
1411
|
+
destroy() {
|
|
1412
|
+
for (var i = 0; i < this.vertices.length; i++) {
|
|
1413
|
+
this.vertices[i].destroy();
|
|
1379
1414
|
}
|
|
1380
|
-
|
|
1381
|
-
return buffer.join("");
|
|
1415
|
+
this.isDestroyed = true;
|
|
1382
1416
|
}
|
|
1383
1417
|
}
|
|
1384
1418
|
Polygon.utils = {
|
|
@@ -1507,7 +1541,8 @@ class Bounds {
|
|
|
1507
1541
|
* @modified 2020-12-04 Changed `getClosestT` param from `Vertex` to `XYCoords` (generalized).
|
|
1508
1542
|
* @modified 2020-12-04 Added the `hasPoint(XYCoords)` function.
|
|
1509
1543
|
* @modified 2021-01-20 Added UID.
|
|
1510
|
-
* @
|
|
1544
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
1545
|
+
* @version 1.2.0
|
|
1511
1546
|
*/
|
|
1512
1547
|
/**
|
|
1513
1548
|
* @classdesc An abstract base classes for vertex tuple constructs, like Lines or Vectors.
|
|
@@ -1541,7 +1576,6 @@ class VertTuple {
|
|
|
1541
1576
|
length() {
|
|
1542
1577
|
return Math.sqrt(Math.pow(this.b.x - this.a.x, 2) + Math.pow(this.b.y - this.a.y, 2));
|
|
1543
1578
|
}
|
|
1544
|
-
;
|
|
1545
1579
|
/**
|
|
1546
1580
|
* Set the length of this vector to the given amount. This only works if this
|
|
1547
1581
|
* vector is not a null vector.
|
|
@@ -1554,7 +1588,6 @@ class VertTuple {
|
|
|
1554
1588
|
setLength(length) {
|
|
1555
1589
|
return this.scale(length / this.length());
|
|
1556
1590
|
}
|
|
1557
|
-
;
|
|
1558
1591
|
/**
|
|
1559
1592
|
* Substract the given vertex from this line's end points.
|
|
1560
1593
|
*
|
|
@@ -1569,7 +1602,6 @@ class VertTuple {
|
|
|
1569
1602
|
this.b.sub(amount);
|
|
1570
1603
|
return this;
|
|
1571
1604
|
}
|
|
1572
|
-
;
|
|
1573
1605
|
/**
|
|
1574
1606
|
* Add the given vertex to this line's end points.
|
|
1575
1607
|
*
|
|
@@ -1584,7 +1616,6 @@ class VertTuple {
|
|
|
1584
1616
|
this.b.add(amount);
|
|
1585
1617
|
return this;
|
|
1586
1618
|
}
|
|
1587
|
-
;
|
|
1588
1619
|
/**
|
|
1589
1620
|
* Normalize this line (set to length 1).
|
|
1590
1621
|
*
|
|
@@ -1597,7 +1628,6 @@ class VertTuple {
|
|
|
1597
1628
|
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());
|
|
1598
1629
|
return this;
|
|
1599
1630
|
}
|
|
1600
|
-
;
|
|
1601
1631
|
/**
|
|
1602
1632
|
* Scale this line by the given factor.
|
|
1603
1633
|
*
|
|
@@ -1611,7 +1641,6 @@ class VertTuple {
|
|
|
1611
1641
|
this.b.set(this.a.x + (this.b.x - this.a.x) * factor, this.a.y + (this.b.y - this.a.y) * factor);
|
|
1612
1642
|
return this;
|
|
1613
1643
|
}
|
|
1614
|
-
;
|
|
1615
1644
|
/**
|
|
1616
1645
|
* Move this line to a new location.
|
|
1617
1646
|
*
|
|
@@ -1627,7 +1656,6 @@ class VertTuple {
|
|
|
1627
1656
|
this.b.add(diff);
|
|
1628
1657
|
return this;
|
|
1629
1658
|
}
|
|
1630
|
-
;
|
|
1631
1659
|
/**
|
|
1632
1660
|
* Get the angle between this and the passed line (in radians).
|
|
1633
1661
|
*
|
|
@@ -1638,7 +1666,7 @@ class VertTuple {
|
|
|
1638
1666
|
* @memberof VertTuple
|
|
1639
1667
|
**/
|
|
1640
1668
|
angle(line) {
|
|
1641
|
-
if (line == null || typeof line ==
|
|
1669
|
+
if (line == null || typeof line == "undefined") {
|
|
1642
1670
|
line = this.factory(new Vertex(0, 0), new Vertex(100, 0));
|
|
1643
1671
|
}
|
|
1644
1672
|
// Compute the angle from x axis and the return the difference :)
|
|
@@ -1648,7 +1676,6 @@ class VertTuple {
|
|
|
1648
1676
|
// The result might be negative, but isn't it usually nicer to determine angles in positive values only?
|
|
1649
1677
|
return Math.atan2(v1.x, v1.y) - Math.atan2(v0.x, v0.y);
|
|
1650
1678
|
}
|
|
1651
|
-
;
|
|
1652
1679
|
/**
|
|
1653
1680
|
* Get line point at position t in [0 ... 1]:<br>
|
|
1654
1681
|
* <pre>[P(0)]=[A]--------------------[P(t)]------[B]=[P(1)]</pre><br>
|
|
@@ -1664,7 +1691,6 @@ class VertTuple {
|
|
|
1664
1691
|
vertAt(t) {
|
|
1665
1692
|
return new Vertex(this.a.x + (this.b.x - this.a.x) * t, this.a.y + (this.b.y - this.a.y) * t);
|
|
1666
1693
|
}
|
|
1667
|
-
;
|
|
1668
1694
|
/**
|
|
1669
1695
|
* Get the denominator of this and the given line.
|
|
1670
1696
|
*
|
|
@@ -1678,9 +1704,8 @@ class VertTuple {
|
|
|
1678
1704
|
**/
|
|
1679
1705
|
denominator(line) {
|
|
1680
1706
|
// http://jsfiddle.net/justin_c_rounds/Gd2S2/
|
|
1681
|
-
return (
|
|
1707
|
+
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);
|
|
1682
1708
|
}
|
|
1683
|
-
;
|
|
1684
1709
|
/**
|
|
1685
1710
|
* Checks if this and the given line are co-linear.
|
|
1686
1711
|
*
|
|
@@ -1695,7 +1720,6 @@ class VertTuple {
|
|
|
1695
1720
|
colinear(line) {
|
|
1696
1721
|
return Math.abs(this.denominator(line)) < Vertex.EPSILON;
|
|
1697
1722
|
}
|
|
1698
|
-
;
|
|
1699
1723
|
/**
|
|
1700
1724
|
* Get the closest position T from this line to the specified point.
|
|
1701
1725
|
*
|
|
@@ -1718,7 +1742,6 @@ class VertTuple {
|
|
|
1718
1742
|
// t = Math.max(0, Math.min(1, t));
|
|
1719
1743
|
return t;
|
|
1720
1744
|
}
|
|
1721
|
-
;
|
|
1722
1745
|
/**
|
|
1723
1746
|
* Check if the given point is located on this line. Optionally also check if
|
|
1724
1747
|
* that point is located between point `a` and `b`.
|
|
@@ -1754,7 +1777,6 @@ class VertTuple {
|
|
|
1754
1777
|
var t = this.getClosestT(p);
|
|
1755
1778
|
return this.vertAt(t);
|
|
1756
1779
|
}
|
|
1757
|
-
;
|
|
1758
1780
|
/**
|
|
1759
1781
|
* The the minimal distance between this line and the specified point.
|
|
1760
1782
|
*
|
|
@@ -1769,7 +1791,6 @@ class VertTuple {
|
|
|
1769
1791
|
// https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
|
|
1770
1792
|
return Math.sqrt(VertTuple.vtutils.dist2(p, this.vertAt(this.getClosestT(p))));
|
|
1771
1793
|
}
|
|
1772
|
-
;
|
|
1773
1794
|
/**
|
|
1774
1795
|
* Create a deep clone of this instance.
|
|
1775
1796
|
*
|
|
@@ -1781,7 +1802,6 @@ class VertTuple {
|
|
|
1781
1802
|
clone() {
|
|
1782
1803
|
return this.factory(this.a.clone(), this.b.clone());
|
|
1783
1804
|
}
|
|
1784
|
-
;
|
|
1785
1805
|
/**
|
|
1786
1806
|
* Create a string representation of this line.
|
|
1787
1807
|
*
|
|
@@ -1793,7 +1813,16 @@ class VertTuple {
|
|
|
1793
1813
|
toString() {
|
|
1794
1814
|
return "{ a : " + this.a.toString() + ", b : " + this.b.toString() + " }";
|
|
1795
1815
|
}
|
|
1796
|
-
|
|
1816
|
+
/**
|
|
1817
|
+
* This function should invalidate any installed listeners and invalidate this object.
|
|
1818
|
+
* After calling this function the object might not hold valid data any more and
|
|
1819
|
+
* should not be used.
|
|
1820
|
+
*/
|
|
1821
|
+
destroy() {
|
|
1822
|
+
this.a.destroy();
|
|
1823
|
+
this.b.destroy();
|
|
1824
|
+
this.isDestroyed = true;
|
|
1825
|
+
}
|
|
1797
1826
|
}
|
|
1798
1827
|
/**
|
|
1799
1828
|
* @private
|
|
@@ -1815,7 +1844,9 @@ VertTuple.vtutils = {
|
|
|
1815
1844
|
* @modified 2019-12-04 Added the Vector.inv() function.
|
|
1816
1845
|
* @modified 2020-03-23 Ported to Typescript from JS.
|
|
1817
1846
|
* @modified 2021-01-20 Added UID.
|
|
1818
|
-
* @
|
|
1847
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
1848
|
+
* @modified 2022-02-02 Cleared the `Vector.toSVGString` function (deprecated). Use `drawutilssvg` instead.
|
|
1849
|
+
* @version 1.4.0
|
|
1819
1850
|
*
|
|
1820
1851
|
* @file Vector
|
|
1821
1852
|
* @public
|
|
@@ -1846,7 +1877,6 @@ class Vector extends VertTuple {
|
|
|
1846
1877
|
**/
|
|
1847
1878
|
this.className = "Vector";
|
|
1848
1879
|
}
|
|
1849
|
-
;
|
|
1850
1880
|
/**
|
|
1851
1881
|
* Get the perpendicular of this vector which is located at a.
|
|
1852
1882
|
*
|
|
@@ -1861,7 +1891,6 @@ class Vector extends VertTuple {
|
|
|
1861
1891
|
v.b.add(this.a);
|
|
1862
1892
|
return v;
|
|
1863
1893
|
}
|
|
1864
|
-
;
|
|
1865
1894
|
/**
|
|
1866
1895
|
* The inverse of a vector is a vector witht the same magnitude but oppose direction.
|
|
1867
1896
|
*
|
|
@@ -1875,7 +1904,6 @@ class Vector extends VertTuple {
|
|
|
1875
1904
|
this.b = tmp;
|
|
1876
1905
|
return this;
|
|
1877
1906
|
}
|
|
1878
|
-
;
|
|
1879
1907
|
/**
|
|
1880
1908
|
* This function computes the inverse of the vector, which means 'a' stays untouched.
|
|
1881
1909
|
*
|
|
@@ -1886,7 +1914,6 @@ class Vector extends VertTuple {
|
|
|
1886
1914
|
this.b.y = this.a.y - (this.b.y - this.a.y);
|
|
1887
1915
|
return this;
|
|
1888
1916
|
}
|
|
1889
|
-
;
|
|
1890
1917
|
/**
|
|
1891
1918
|
* Get the intersection if this vector and the specified vector.
|
|
1892
1919
|
*
|
|
@@ -1902,16 +1929,15 @@ class Vector extends VertTuple {
|
|
|
1902
1929
|
return null;
|
|
1903
1930
|
var a = this.a.y - line.a.y;
|
|
1904
1931
|
var b = this.a.x - line.a.x;
|
|
1905
|
-
var numerator1 = (
|
|
1906
|
-
var numerator2 = (
|
|
1932
|
+
var numerator1 = (line.b.x - line.a.x) * a - (line.b.y - line.a.y) * b;
|
|
1933
|
+
var numerator2 = (this.b.x - this.a.x) * a - (this.b.y - this.a.y) * b;
|
|
1907
1934
|
a = numerator1 / denominator; // NaN if parallel lines
|
|
1908
1935
|
b = numerator2 / denominator;
|
|
1909
1936
|
// TODO:
|
|
1910
1937
|
// FOR A VECTOR THE LINE-INTERSECTION MUST BE ON BOTH VECTORS
|
|
1911
1938
|
// if we cast these lines infinitely in both directions, they intersect here:
|
|
1912
|
-
return new Vertex(this.a.x +
|
|
1939
|
+
return new Vertex(this.a.x + a * (this.b.x - this.a.x), this.a.y + a * (this.b.y - this.a.y));
|
|
1913
1940
|
}
|
|
1914
|
-
;
|
|
1915
1941
|
/**
|
|
1916
1942
|
* Create an SVG representation of this line.
|
|
1917
1943
|
*
|
|
@@ -1924,31 +1950,30 @@ class Vector extends VertTuple {
|
|
|
1924
1950
|
* @memberof Vector
|
|
1925
1951
|
**/
|
|
1926
1952
|
toSVGString(options) {
|
|
1927
|
-
options = options || {};
|
|
1928
|
-
var buffer = [];
|
|
1929
|
-
var vertices = Vector.utils.buildArrowHead(this.a, this.b, 8, 1.0, 1.0);
|
|
1930
|
-
buffer.push(
|
|
1931
|
-
if (options.className)
|
|
1932
|
-
|
|
1933
|
-
buffer.push(
|
|
1934
|
-
buffer.push('
|
|
1935
|
-
buffer.push('
|
|
1936
|
-
buffer.push('
|
|
1937
|
-
buffer.push('
|
|
1938
|
-
buffer.push(
|
|
1939
|
-
|
|
1940
|
-
//
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
buffer.
|
|
1948
|
-
|
|
1949
|
-
return
|
|
1953
|
+
// options = options || {};
|
|
1954
|
+
// var buffer = [];
|
|
1955
|
+
// var vertices = Vector.utils.buildArrowHead(this.a, this.b, 8, 1.0, 1.0);
|
|
1956
|
+
// buffer.push("<g");
|
|
1957
|
+
// if (options.className) buffer.push(' class="' + options.className + '"');
|
|
1958
|
+
// buffer.push(">");
|
|
1959
|
+
// buffer.push(" <line");
|
|
1960
|
+
// buffer.push(' x1="' + this.a.x + '"');
|
|
1961
|
+
// buffer.push(' y1="' + this.a.y + '"');
|
|
1962
|
+
// buffer.push(' x2="' + vertices[0].x + '"');
|
|
1963
|
+
// buffer.push(' y2="' + vertices[0].y + '"');
|
|
1964
|
+
// buffer.push(" />");
|
|
1965
|
+
// // Add arrow head
|
|
1966
|
+
// buffer.push(' <polygon points="');
|
|
1967
|
+
// for (var i = 0; i < vertices.length; i++) {
|
|
1968
|
+
// if (i > 0) buffer.push(" ");
|
|
1969
|
+
// buffer.push("" + vertices[i].x + "," + vertices[i].y);
|
|
1970
|
+
// }
|
|
1971
|
+
// buffer.push('"/>');
|
|
1972
|
+
// buffer.push("</g>");
|
|
1973
|
+
// return buffer.join("");
|
|
1974
|
+
console.warn("[Deprecation] Warning: the Vector.toSVGString method is deprecated and does not return and valid SVG data any more. Please use `drawutilssvg` instead.");
|
|
1975
|
+
return "";
|
|
1950
1976
|
}
|
|
1951
|
-
;
|
|
1952
1977
|
}
|
|
1953
1978
|
Vector.utils = {
|
|
1954
1979
|
/**
|
|
@@ -1979,10 +2004,10 @@ Vector.utils = {
|
|
|
1979
2004
|
buildArrowHead: (zA, zB, headlen, scaleX, scaleY) => {
|
|
1980
2005
|
var angle = Math.atan2((zB.y - zA.y) * scaleY, (zB.x - zA.x) * scaleX);
|
|
1981
2006
|
var vertices = [];
|
|
1982
|
-
vertices.push(new Vertex(zB.x * scaleX -
|
|
1983
|
-
vertices.push(new Vertex(zB.x * scaleX -
|
|
2007
|
+
vertices.push(new Vertex(zB.x * scaleX - headlen * Math.cos(angle), zB.y * scaleY - headlen * Math.sin(angle)));
|
|
2008
|
+
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)));
|
|
1984
2009
|
vertices.push(new Vertex(zB.x * scaleX, zB.y * scaleY));
|
|
1985
|
-
vertices.push(new Vertex(zB.x * scaleX -
|
|
2010
|
+
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)));
|
|
1986
2011
|
return vertices;
|
|
1987
2012
|
}
|
|
1988
2013
|
};
|
|
@@ -2007,7 +2032,9 @@ Vector.utils = {
|
|
|
2007
2032
|
* @modified 2020-07-14 Changed the moveCurvePoint(...,Vertex) to moveCurvePoint(...,XYCoords), which is more generic.
|
|
2008
2033
|
* @modified 2020-07-24 Added the getClosestT function and the helper function locateIntervalByDistance(...).
|
|
2009
2034
|
* @modified 2021-01-20 Added UID.
|
|
2010
|
-
* @
|
|
2035
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
2036
|
+
* @modified 2022-02-02 Cleared the `toSVGPathData` function (deprecated). Use `drawutilssvg` instead.
|
|
2037
|
+
* @version 2.6.0
|
|
2011
2038
|
*
|
|
2012
2039
|
* @file CubicBezierCurve
|
|
2013
2040
|
* @public
|
|
@@ -2056,7 +2083,6 @@ class CubicBezierCurve {
|
|
|
2056
2083
|
this.arcLength = null;
|
|
2057
2084
|
this.updateArcLengths();
|
|
2058
2085
|
}
|
|
2059
|
-
;
|
|
2060
2086
|
/**
|
|
2061
2087
|
* Move the given curve point (the start point, end point or one of the two
|
|
2062
2088
|
* control points).
|
|
@@ -2093,7 +2119,6 @@ class CubicBezierCurve {
|
|
|
2093
2119
|
if (updateArcLengths)
|
|
2094
2120
|
this.updateArcLengths();
|
|
2095
2121
|
}
|
|
2096
|
-
;
|
|
2097
2122
|
/**
|
|
2098
2123
|
* Translate the whole curve by the given {x,y} amount: moves all four points.
|
|
2099
2124
|
*
|
|
@@ -2110,7 +2135,6 @@ class CubicBezierCurve {
|
|
|
2110
2135
|
this.endPoint.add(amount);
|
|
2111
2136
|
return this;
|
|
2112
2137
|
}
|
|
2113
|
-
;
|
|
2114
2138
|
/**
|
|
2115
2139
|
* Reverse this curve, means swapping start- and end-point and swapping
|
|
2116
2140
|
* start-control- and end-control-point.
|
|
@@ -2129,7 +2153,6 @@ class CubicBezierCurve {
|
|
|
2129
2153
|
this.endControlPoint = tmp;
|
|
2130
2154
|
return this;
|
|
2131
2155
|
}
|
|
2132
|
-
;
|
|
2133
2156
|
/**
|
|
2134
2157
|
* Get the total curve length.<br>
|
|
2135
2158
|
* <br>
|
|
@@ -2148,7 +2171,6 @@ class CubicBezierCurve {
|
|
|
2148
2171
|
getLength() {
|
|
2149
2172
|
return this.arcLength;
|
|
2150
2173
|
}
|
|
2151
|
-
;
|
|
2152
2174
|
/**
|
|
2153
2175
|
* Uptate the internal arc segment buffer and their lengths.<br>
|
|
2154
2176
|
* <br>
|
|
@@ -2186,7 +2208,6 @@ class CubicBezierCurve {
|
|
|
2186
2208
|
}
|
|
2187
2209
|
this.arcLength = newLength;
|
|
2188
2210
|
}
|
|
2189
|
-
;
|
|
2190
2211
|
/**
|
|
2191
2212
|
* Get a 't' (relative position on curve) with the closest distance to point 'p'.
|
|
2192
2213
|
*
|
|
@@ -2209,7 +2230,6 @@ class CubicBezierCurve {
|
|
|
2209
2230
|
} while (iteration < 4 && this.getPointAt(result.tPrev).distance(this.getPointAt(result.tNext)) > desiredEpsilon);
|
|
2210
2231
|
return result.t;
|
|
2211
2232
|
}
|
|
2212
|
-
;
|
|
2213
2233
|
/**
|
|
2214
2234
|
* This helper function locates the 't' on a fixed step interval with the minimal distance
|
|
2215
2235
|
* between the curve (at 't') and the given point.
|
|
@@ -2238,12 +2258,12 @@ class CubicBezierCurve {
|
|
|
2238
2258
|
minDist = dist;
|
|
2239
2259
|
}
|
|
2240
2260
|
}
|
|
2241
|
-
return {
|
|
2261
|
+
return {
|
|
2262
|
+
t: tStart + tDiff * (minIndex / stepCount),
|
|
2242
2263
|
tPrev: tStart + tDiff * (Math.max(0, minIndex - 1) / stepCount),
|
|
2243
2264
|
tNext: tStart + tDiff * (Math.min(stepCount, minIndex + 1) / stepCount)
|
|
2244
2265
|
};
|
|
2245
2266
|
}
|
|
2246
|
-
;
|
|
2247
2267
|
/**
|
|
2248
2268
|
* Get the bounds of this bezier curve.
|
|
2249
2269
|
*
|
|
@@ -2265,7 +2285,6 @@ class CubicBezierCurve {
|
|
|
2265
2285
|
}
|
|
2266
2286
|
return new Bounds(min, max);
|
|
2267
2287
|
}
|
|
2268
|
-
;
|
|
2269
2288
|
/**
|
|
2270
2289
|
* Get the start point of the curve.<br>
|
|
2271
2290
|
* <br>
|
|
@@ -2279,7 +2298,6 @@ class CubicBezierCurve {
|
|
|
2279
2298
|
getStartPoint() {
|
|
2280
2299
|
return this.startPoint;
|
|
2281
2300
|
}
|
|
2282
|
-
;
|
|
2283
2301
|
/**
|
|
2284
2302
|
* Get the end point of the curve.<br>
|
|
2285
2303
|
* <br>
|
|
@@ -2293,7 +2311,6 @@ class CubicBezierCurve {
|
|
|
2293
2311
|
getEndPoint() {
|
|
2294
2312
|
return this.endPoint;
|
|
2295
2313
|
}
|
|
2296
|
-
;
|
|
2297
2314
|
/**
|
|
2298
2315
|
* Get the start control point of the curve.<br>
|
|
2299
2316
|
* <br>
|
|
@@ -2307,7 +2324,6 @@ class CubicBezierCurve {
|
|
|
2307
2324
|
getStartControlPoint() {
|
|
2308
2325
|
return this.startControlPoint;
|
|
2309
2326
|
}
|
|
2310
|
-
;
|
|
2311
2327
|
/**
|
|
2312
2328
|
* Get the end control point of the curve.<br>
|
|
2313
2329
|
* <br>
|
|
@@ -2321,7 +2337,6 @@ class CubicBezierCurve {
|
|
|
2321
2337
|
getEndControlPoint() {
|
|
2322
2338
|
return this.endControlPoint;
|
|
2323
2339
|
}
|
|
2324
|
-
;
|
|
2325
2340
|
/**
|
|
2326
2341
|
* Get one of the four curve points specified by the passt point ID.
|
|
2327
2342
|
*
|
|
@@ -2342,7 +2357,6 @@ class CubicBezierCurve {
|
|
|
2342
2357
|
return this.endControlPoint;
|
|
2343
2358
|
throw new Error(`Invalid point ID '${id}'.`);
|
|
2344
2359
|
}
|
|
2345
|
-
;
|
|
2346
2360
|
/**
|
|
2347
2361
|
* Get the curve point at a given position t, where t is in [0,1].<br>
|
|
2348
2362
|
* <br>
|
|
@@ -2357,13 +2371,16 @@ class CubicBezierCurve {
|
|
|
2357
2371
|
**/
|
|
2358
2372
|
getPointAt(t) {
|
|
2359
2373
|
// Perform some powerful math magic
|
|
2360
|
-
const x = this.startPoint.x * Math.pow(1.0 - t, 3) +
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2374
|
+
const x = this.startPoint.x * Math.pow(1.0 - t, 3) +
|
|
2375
|
+
this.startControlPoint.x * 3 * t * Math.pow(1.0 - t, 2) +
|
|
2376
|
+
this.endControlPoint.x * 3 * Math.pow(t, 2) * (1.0 - t) +
|
|
2377
|
+
this.endPoint.x * Math.pow(t, 3);
|
|
2378
|
+
const y = this.startPoint.y * Math.pow(1.0 - t, 3) +
|
|
2379
|
+
this.startControlPoint.y * 3 * t * Math.pow(1.0 - t, 2) +
|
|
2380
|
+
this.endControlPoint.y * 3 * Math.pow(t, 2) * (1.0 - t) +
|
|
2381
|
+
this.endPoint.y * Math.pow(t, 3);
|
|
2364
2382
|
return new Vertex(x, y);
|
|
2365
2383
|
}
|
|
2366
|
-
;
|
|
2367
2384
|
/**
|
|
2368
2385
|
* Get the curve point at a given position u, where u is in [0,arcLength].<br>
|
|
2369
2386
|
* <br>
|
|
@@ -2379,7 +2396,6 @@ class CubicBezierCurve {
|
|
|
2379
2396
|
getPoint(u) {
|
|
2380
2397
|
return this.getPointAt(u / this.arcLength);
|
|
2381
2398
|
}
|
|
2382
|
-
;
|
|
2383
2399
|
/**
|
|
2384
2400
|
* Get the curve tangent vector at a given absolute curve position t in [0,1].<br>
|
|
2385
2401
|
* <br>
|
|
@@ -2400,18 +2416,11 @@ class CubicBezierCurve {
|
|
|
2400
2416
|
const t2 = t * t;
|
|
2401
2417
|
// (1 - t)^2 = (1-t)*(1-t) = 1 - t - t + t^2 = 1 - 2*t + t^2
|
|
2402
2418
|
const nt2 = 1 - 2 * t + t2;
|
|
2403
|
-
const tX = -3 * a.x * nt2 +
|
|
2404
|
-
|
|
2405
|
-
c.x * (6 * (t - t2) - 3 * t2) +
|
|
2406
|
-
3 * d.x * t2;
|
|
2407
|
-
const tY = -3 * a.y * nt2 +
|
|
2408
|
-
b.y * (3 * nt2 - 6 * (t - t2)) +
|
|
2409
|
-
c.y * (6 * (t - t2) - 3 * t2) +
|
|
2410
|
-
3 * d.y * t2;
|
|
2419
|
+
const tX = -3 * a.x * nt2 + b.x * (3 * nt2 - 6 * (t - t2)) + c.x * (6 * (t - t2) - 3 * t2) + 3 * d.x * t2;
|
|
2420
|
+
const tY = -3 * a.y * nt2 + b.y * (3 * nt2 - 6 * (t - t2)) + c.y * (6 * (t - t2) - 3 * t2) + 3 * d.y * t2;
|
|
2411
2421
|
// Note: my implementation does NOT normalize tangent vectors!
|
|
2412
2422
|
return new Vertex(tX, tY);
|
|
2413
2423
|
}
|
|
2414
|
-
;
|
|
2415
2424
|
/**
|
|
2416
2425
|
* Get a sub curve at the given start end end offsets (values between 0.0 and 1.0).
|
|
2417
2426
|
*
|
|
@@ -2437,7 +2446,6 @@ class CubicBezierCurve {
|
|
|
2437
2446
|
// pb.draw.cubicBezier( startVec.a, endVec.a, startVec.b, endVec.b, '#8800ff', 2 );
|
|
2438
2447
|
return new CubicBezierCurve(startVec.a, endVec.a, startVec.b, endVec.b);
|
|
2439
2448
|
}
|
|
2440
|
-
;
|
|
2441
2449
|
/**
|
|
2442
2450
|
* Convert a relative curve position u to the absolute curve position t.
|
|
2443
2451
|
*
|
|
@@ -2448,9 +2456,8 @@ class CubicBezierCurve {
|
|
|
2448
2456
|
* @return {number}
|
|
2449
2457
|
**/
|
|
2450
2458
|
convertU2T(u) {
|
|
2451
|
-
return Math.max(0.0, Math.min(1.0,
|
|
2459
|
+
return Math.max(0.0, Math.min(1.0, u / this.arcLength));
|
|
2452
2460
|
}
|
|
2453
|
-
;
|
|
2454
2461
|
/**
|
|
2455
2462
|
* Get the curve tangent vector at a given relative position u in [0,arcLength].<br>
|
|
2456
2463
|
* <br>
|
|
@@ -2465,7 +2472,6 @@ class CubicBezierCurve {
|
|
|
2465
2472
|
getTangent(u) {
|
|
2466
2473
|
return this.getTangentAt(this.convertU2T(u));
|
|
2467
2474
|
}
|
|
2468
|
-
;
|
|
2469
2475
|
/**
|
|
2470
2476
|
* Get the curve perpendicular at a given relative position u in [0,arcLength] as a vector.<br>
|
|
2471
2477
|
* <br>
|
|
@@ -2480,7 +2486,6 @@ class CubicBezierCurve {
|
|
|
2480
2486
|
getPerpendicular(u) {
|
|
2481
2487
|
return this.getPerpendicularAt(this.convertU2T(u));
|
|
2482
2488
|
}
|
|
2483
|
-
;
|
|
2484
2489
|
/**
|
|
2485
2490
|
* Get the curve perpendicular at a given absolute position t in [0,1] as a vector.<br>
|
|
2486
2491
|
* <br>
|
|
@@ -2496,7 +2501,6 @@ class CubicBezierCurve {
|
|
|
2496
2501
|
const tangentVector = this.getTangentAt(t);
|
|
2497
2502
|
return new Vertex(tangentVector.y, -tangentVector.x);
|
|
2498
2503
|
}
|
|
2499
|
-
;
|
|
2500
2504
|
/**
|
|
2501
2505
|
* Clone this Bézier curve (deep clone).
|
|
2502
2506
|
*
|
|
@@ -2508,7 +2512,6 @@ class CubicBezierCurve {
|
|
|
2508
2512
|
clone() {
|
|
2509
2513
|
return new CubicBezierCurve(this.getStartPoint().clone(), this.getEndPoint().clone(), this.getStartControlPoint().clone(), this.getEndControlPoint().clone());
|
|
2510
2514
|
}
|
|
2511
|
-
;
|
|
2512
2515
|
/**
|
|
2513
2516
|
* Check if this and the specified curve are equal.<br>
|
|
2514
2517
|
* <br>
|
|
@@ -2527,17 +2530,25 @@ class CubicBezierCurve {
|
|
|
2527
2530
|
// Let's see if this restricted version works out.
|
|
2528
2531
|
if (!curve)
|
|
2529
2532
|
return false;
|
|
2530
|
-
if (!curve.startPoint ||
|
|
2531
|
-
!curve.endPoint ||
|
|
2532
|
-
!curve.startControlPoint ||
|
|
2533
|
-
!curve.endControlPoint)
|
|
2533
|
+
if (!curve.startPoint || !curve.endPoint || !curve.startControlPoint || !curve.endControlPoint)
|
|
2534
2534
|
return false;
|
|
2535
|
-
return this.startPoint.equals(curve.startPoint)
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2535
|
+
return (this.startPoint.equals(curve.startPoint) &&
|
|
2536
|
+
this.endPoint.equals(curve.endPoint) &&
|
|
2537
|
+
this.startControlPoint.equals(curve.startControlPoint) &&
|
|
2538
|
+
this.endControlPoint.equals(curve.endControlPoint));
|
|
2539
|
+
}
|
|
2540
|
+
/**
|
|
2541
|
+
* This function should invalidate any installed listeners and invalidate this object.
|
|
2542
|
+
* After calling this function the object might not hold valid data any more and
|
|
2543
|
+
* should not be used.
|
|
2544
|
+
*/
|
|
2545
|
+
destroy() {
|
|
2546
|
+
this.startPoint.destroy();
|
|
2547
|
+
this.endPoint.destroy();
|
|
2548
|
+
this.startControlPoint.destroy();
|
|
2549
|
+
this.endControlPoint.destroy();
|
|
2550
|
+
this.isDestroyed = true;
|
|
2539
2551
|
}
|
|
2540
|
-
;
|
|
2541
2552
|
/**
|
|
2542
2553
|
* Quick check for class instance.
|
|
2543
2554
|
* Is there a better way?
|
|
@@ -2563,7 +2574,6 @@ class CubicBezierCurve {
|
|
|
2563
2574
|
*/
|
|
2564
2575
|
return obj instanceof CubicBezierCurve;
|
|
2565
2576
|
}
|
|
2566
|
-
;
|
|
2567
2577
|
/**
|
|
2568
2578
|
* Create an SVG path data representation of this bézier curve.
|
|
2569
2579
|
*
|
|
@@ -2572,32 +2582,34 @@ class CubicBezierCurve {
|
|
|
2572
2582
|
* or in other words<br>
|
|
2573
2583
|
* <pre>'M startoint.x startPoint.y C startControlPoint.x startControlPoint.y endControlPoint.x endControlPoint.y endPoint.x endPoint.y'</pre>
|
|
2574
2584
|
*
|
|
2585
|
+
* @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
|
|
2575
2586
|
* @method toSVGPathData
|
|
2576
2587
|
* @instance
|
|
2577
2588
|
* @memberof CubicBezierCurve
|
|
2578
2589
|
* @return {string} The SVG path data string.
|
|
2579
2590
|
**/
|
|
2580
2591
|
toSVGPathData() {
|
|
2581
|
-
var buffer = [];
|
|
2582
|
-
buffer.push(
|
|
2583
|
-
buffer.push(this.startPoint.x.toString());
|
|
2584
|
-
buffer.push(
|
|
2585
|
-
buffer.push(this.startPoint.y.toString());
|
|
2586
|
-
buffer.push(
|
|
2587
|
-
buffer.push(this.startControlPoint.x.toString());
|
|
2588
|
-
buffer.push(
|
|
2589
|
-
buffer.push(this.startControlPoint.y.toString());
|
|
2590
|
-
buffer.push(
|
|
2591
|
-
buffer.push(this.endControlPoint.x.toString());
|
|
2592
|
-
buffer.push(
|
|
2593
|
-
buffer.push(this.endControlPoint.y.toString());
|
|
2594
|
-
buffer.push(
|
|
2595
|
-
buffer.push(this.endPoint.x.toString());
|
|
2596
|
-
buffer.push(
|
|
2597
|
-
buffer.push(this.endPoint.y.toString());
|
|
2598
|
-
return buffer.join(
|
|
2592
|
+
// var buffer: Array<string> = [];
|
|
2593
|
+
// buffer.push("M ");
|
|
2594
|
+
// buffer.push(this.startPoint.x.toString());
|
|
2595
|
+
// buffer.push(" ");
|
|
2596
|
+
// buffer.push(this.startPoint.y.toString());
|
|
2597
|
+
// buffer.push(" C ");
|
|
2598
|
+
// buffer.push(this.startControlPoint.x.toString());
|
|
2599
|
+
// buffer.push(" ");
|
|
2600
|
+
// buffer.push(this.startControlPoint.y.toString());
|
|
2601
|
+
// buffer.push(" ");
|
|
2602
|
+
// buffer.push(this.endControlPoint.x.toString());
|
|
2603
|
+
// buffer.push(" ");
|
|
2604
|
+
// buffer.push(this.endControlPoint.y.toString());
|
|
2605
|
+
// buffer.push(" ");
|
|
2606
|
+
// buffer.push(this.endPoint.x.toString());
|
|
2607
|
+
// buffer.push(" ");
|
|
2608
|
+
// buffer.push(this.endPoint.y.toString());
|
|
2609
|
+
// return buffer.join("");
|
|
2610
|
+
console.warn("[Deprecation] Warning: the CubicBezierCurve.toSVGPathData method is deprecated and does not return and valid SVG data any more. Please use `drawutilssvg` instead.");
|
|
2611
|
+
return "";
|
|
2599
2612
|
}
|
|
2600
|
-
;
|
|
2601
2613
|
/**
|
|
2602
2614
|
* Convert this curve to a JSON string.
|
|
2603
2615
|
*
|
|
@@ -2610,18 +2622,33 @@ class CubicBezierCurve {
|
|
|
2610
2622
|
toJSON(prettyFormat) {
|
|
2611
2623
|
var jsonString = "{ " + // begin object
|
|
2612
2624
|
(prettyFormat ? "\n\t" : "") +
|
|
2613
|
-
"
|
|
2625
|
+
'"startPoint" : [' +
|
|
2626
|
+
this.getStartPoint().x +
|
|
2627
|
+
"," +
|
|
2628
|
+
this.getStartPoint().y +
|
|
2629
|
+
"], " +
|
|
2614
2630
|
(prettyFormat ? "\n\t" : "") +
|
|
2615
|
-
"
|
|
2631
|
+
'"endPoint" : [' +
|
|
2632
|
+
this.getEndPoint().x +
|
|
2633
|
+
"," +
|
|
2634
|
+
this.getEndPoint().y +
|
|
2635
|
+
"], " +
|
|
2616
2636
|
(prettyFormat ? "\n\t" : "") +
|
|
2617
|
-
"
|
|
2637
|
+
'"startControlPoint": [' +
|
|
2638
|
+
this.getStartControlPoint().x +
|
|
2639
|
+
"," +
|
|
2640
|
+
this.getStartControlPoint().y +
|
|
2641
|
+
"], " +
|
|
2618
2642
|
(prettyFormat ? "\n\t" : "") +
|
|
2619
|
-
"
|
|
2643
|
+
'"endControlPoint" : [' +
|
|
2644
|
+
this.getEndControlPoint().x +
|
|
2645
|
+
"," +
|
|
2646
|
+
this.getEndControlPoint().y +
|
|
2647
|
+
"]" +
|
|
2620
2648
|
(prettyFormat ? "\n\t" : "") +
|
|
2621
2649
|
" }"; // end object
|
|
2622
2650
|
return jsonString;
|
|
2623
2651
|
}
|
|
2624
|
-
;
|
|
2625
2652
|
/**
|
|
2626
2653
|
* Parse a Bézier curve from the given JSON string.
|
|
2627
2654
|
*
|
|
@@ -2636,7 +2663,6 @@ class CubicBezierCurve {
|
|
|
2636
2663
|
var obj = JSON.parse(jsonString);
|
|
2637
2664
|
return CubicBezierCurve.fromObject(obj);
|
|
2638
2665
|
}
|
|
2639
|
-
;
|
|
2640
2666
|
/**
|
|
2641
2667
|
* Try to convert the passed object to a CubicBezierCurve.
|
|
2642
2668
|
*
|
|
@@ -2651,16 +2677,15 @@ class CubicBezierCurve {
|
|
|
2651
2677
|
if (typeof obj !== "object")
|
|
2652
2678
|
throw "Can only build from object.";
|
|
2653
2679
|
if (!obj.startPoint)
|
|
2654
|
-
throw
|
|
2680
|
+
throw 'Object member "startPoint" missing.';
|
|
2655
2681
|
if (!obj.endPoint)
|
|
2656
|
-
throw
|
|
2682
|
+
throw 'Object member "endPoint" missing.';
|
|
2657
2683
|
if (!obj.startControlPoint)
|
|
2658
|
-
throw
|
|
2684
|
+
throw 'Object member "startControlPoint" missing.';
|
|
2659
2685
|
if (!obj.endControlPoint)
|
|
2660
|
-
throw
|
|
2686
|
+
throw 'Object member "endControlPoint" missing.';
|
|
2661
2687
|
return new CubicBezierCurve(new Vertex(obj.startPoint[0], obj.startPoint[1]), new Vertex(obj.endPoint[0], obj.endPoint[1]), new Vertex(obj.startControlPoint[0], obj.startControlPoint[1]), new Vertex(obj.endControlPoint[0], obj.endControlPoint[1]));
|
|
2662
2688
|
}
|
|
2663
|
-
;
|
|
2664
2689
|
/**
|
|
2665
2690
|
* Convert a 4-element array of vertices to a cubic bézier curve.
|
|
2666
2691
|
*
|
|
@@ -2677,7 +2702,6 @@ class CubicBezierCurve {
|
|
|
2677
2702
|
throw "Can only build from array with four elements.";
|
|
2678
2703
|
return new CubicBezierCurve(arr[0], arr[1], arr[2], arr[3]);
|
|
2679
2704
|
}
|
|
2680
|
-
;
|
|
2681
2705
|
}
|
|
2682
2706
|
/** @constant {number} */
|
|
2683
2707
|
CubicBezierCurve.START_POINT = 0;
|
|
@@ -2710,7 +2734,10 @@ CubicBezierCurve.END_POINT = 3;
|
|
|
2710
2734
|
* @modified 2020-07-24 Added the getClosestT(Vertex) function.
|
|
2711
2735
|
* @modified 2020-12-29 Constructor is now private (no explicit use intended).
|
|
2712
2736
|
* @modified 2021-05-25 Added BezierPath.fromReducedList( Array<number> ).
|
|
2713
|
-
* @
|
|
2737
|
+
* @modified 2022-01-31 Added `BezierPath.getEvenDistributionVertices(number)`.
|
|
2738
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
2739
|
+
* @modified 2022-02-02 Cleared the `toSVGString` function (deprecated). Use `drawutilssvg` instead.
|
|
2740
|
+
* @version 2.5.0
|
|
2714
2741
|
*
|
|
2715
2742
|
* @file BezierPath
|
|
2716
2743
|
* @public
|
|
@@ -3599,6 +3626,59 @@ class BezierPath {
|
|
|
3599
3626
|
}
|
|
3600
3627
|
return new Bounds(min, max);
|
|
3601
3628
|
}
|
|
3629
|
+
/**
|
|
3630
|
+
* Get n 'equally' distributed vertices along this Bézier path.
|
|
3631
|
+
*
|
|
3632
|
+
* As the changing curvature of the B slines makes prediction of distances difficult, the
|
|
3633
|
+
* returned vertices' distances are only relatively equal:
|
|
3634
|
+
* - the distance grows where curvature is large.
|
|
3635
|
+
* - the distance shrinks where curvature is small.
|
|
3636
|
+
*
|
|
3637
|
+
* Only the distance mean of all consecutive is 1/n-th of the total arc length.
|
|
3638
|
+
*
|
|
3639
|
+
* Usually this approximation is good enough for most use cases.
|
|
3640
|
+
*
|
|
3641
|
+
* @param {number} pointCount - (must be at least 2) The number of desired points (start and end point included).
|
|
3642
|
+
* @return {Array<Vertex>}
|
|
3643
|
+
*/
|
|
3644
|
+
getEvenDistributionVertices(pointCount) {
|
|
3645
|
+
if (pointCount < 2) {
|
|
3646
|
+
throw new Error("pointCount must be larger than one; is " + pointCount + ".");
|
|
3647
|
+
}
|
|
3648
|
+
const result = [];
|
|
3649
|
+
if (this.bezierCurves.length === 0) {
|
|
3650
|
+
return result;
|
|
3651
|
+
}
|
|
3652
|
+
// Fetch and add the start point from the source polygon
|
|
3653
|
+
var polygonPoint = new Vertex(this.bezierCurves[0].startPoint);
|
|
3654
|
+
result.push(polygonPoint);
|
|
3655
|
+
// if (this.bezierCurves.length === 1) {
|
|
3656
|
+
// return result;
|
|
3657
|
+
// }
|
|
3658
|
+
const perimeter = this.totalArcLength;
|
|
3659
|
+
const stepSize = perimeter / (pointCount - 1);
|
|
3660
|
+
const n = this.bezierCurves.length;
|
|
3661
|
+
let curveIndex = 0;
|
|
3662
|
+
let segmentLength = this.bezierCurves[0].arcLength;
|
|
3663
|
+
let curSegmentU = stepSize;
|
|
3664
|
+
let i = 1;
|
|
3665
|
+
while (i < pointCount && curveIndex < n) {
|
|
3666
|
+
// Check if next eq point is inside this segment
|
|
3667
|
+
if (curSegmentU < segmentLength) {
|
|
3668
|
+
var newPoint = this.bezierCurves[curveIndex].getPoint(curSegmentU);
|
|
3669
|
+
result.push(newPoint);
|
|
3670
|
+
curSegmentU += stepSize;
|
|
3671
|
+
i++;
|
|
3672
|
+
}
|
|
3673
|
+
else {
|
|
3674
|
+
curveIndex++;
|
|
3675
|
+
curSegmentU = curSegmentU - segmentLength;
|
|
3676
|
+
segmentLength = curveIndex < n ? this.bezierCurves[curveIndex].arcLength : 0;
|
|
3677
|
+
}
|
|
3678
|
+
}
|
|
3679
|
+
result.push(new Vertex(this.bezierCurves[n - 1].endPoint));
|
|
3680
|
+
return result;
|
|
3681
|
+
}
|
|
3602
3682
|
/**
|
|
3603
3683
|
* Clone this BezierPath (deep clone).
|
|
3604
3684
|
*
|
|
@@ -3656,19 +3736,30 @@ class BezierPath {
|
|
|
3656
3736
|
* @return {string} The SVG string.
|
|
3657
3737
|
**/
|
|
3658
3738
|
toSVGString(options) {
|
|
3659
|
-
options = options || {};
|
|
3660
|
-
var buffer = [];
|
|
3661
|
-
buffer.push("<path");
|
|
3662
|
-
if (options.className)
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3739
|
+
// options = options || {};
|
|
3740
|
+
// var buffer: Array<string> = [];
|
|
3741
|
+
// buffer.push("<path");
|
|
3742
|
+
// if (options.className) buffer.push(' class="' + options.className + '"');
|
|
3743
|
+
// buffer.push(' d="');
|
|
3744
|
+
// for (var c = 0; c < this.bezierCurves.length; c++) {
|
|
3745
|
+
// if (c > 0) buffer.push(" ");
|
|
3746
|
+
// buffer.push(this.bezierCurves[c].toSVGPathData());
|
|
3747
|
+
// }
|
|
3748
|
+
// buffer.push('" />');
|
|
3749
|
+
// return buffer.join("");
|
|
3750
|
+
console.warn("[Deprecation] Warning: the BezierPath.toSVGString method is deprecated and does not return and valid SVG data any more. Please use `drawutilssvg` instead.");
|
|
3751
|
+
return "";
|
|
3752
|
+
}
|
|
3753
|
+
/**
|
|
3754
|
+
* This function should invalidate any installed listeners and invalidate this object.
|
|
3755
|
+
* After calling this function the object might not hold valid data any more and
|
|
3756
|
+
* should not be used.
|
|
3757
|
+
*/
|
|
3758
|
+
destroy() {
|
|
3759
|
+
for (var i = 0; i < this.bezierCurves.length; i++) {
|
|
3760
|
+
this.bezierCurves[i].destroy();
|
|
3669
3761
|
}
|
|
3670
|
-
|
|
3671
|
-
return buffer.join("");
|
|
3762
|
+
this.isDestroyed = true;
|
|
3672
3763
|
}
|
|
3673
3764
|
/**
|
|
3674
3765
|
* Create a JSON string representation of this bézier curve.
|
|
@@ -3895,7 +3986,8 @@ BezierPath.END_POINT = 3;
|
|
|
3895
3986
|
* @modified 2020-03-16 The Line.angle(Line) parameter is now optional. The baseline (x-axis) will be used if not defined.
|
|
3896
3987
|
* @modified 2020-03-23 Ported to Typescript from JS.
|
|
3897
3988
|
* @modified 2020-12-04 The `intersection` function returns undefined if both lines are parallel.
|
|
3898
|
-
* @
|
|
3989
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
3990
|
+
* @version 2.2.0
|
|
3899
3991
|
*
|
|
3900
3992
|
* @file Line
|
|
3901
3993
|
* @public
|
|
@@ -3940,20 +4032,19 @@ class Line extends VertTuple {
|
|
|
3940
4032
|
return null;
|
|
3941
4033
|
let a = this.a.y - line.a.y;
|
|
3942
4034
|
let b = this.a.x - line.a.x;
|
|
3943
|
-
const numerator1 = (
|
|
3944
|
-
const numerator2 = (
|
|
4035
|
+
const numerator1 = (line.b.x - line.a.x) * a - (line.b.y - line.a.y) * b;
|
|
4036
|
+
const numerator2 = (this.b.x - this.a.x) * a - (this.b.y - this.a.y) * b;
|
|
3945
4037
|
a = numerator1 / denominator; // NaN if parallel lines
|
|
3946
4038
|
b = numerator2 / denominator;
|
|
3947
4039
|
// Catch NaN?
|
|
3948
|
-
const x = this.a.x +
|
|
3949
|
-
const y = this.a.y +
|
|
4040
|
+
const x = this.a.x + a * (this.b.x - this.a.x);
|
|
4041
|
+
const y = this.a.y + a * (this.b.y - this.a.y);
|
|
3950
4042
|
if (isNaN(a) || isNaN(x) || isNaN(y)) {
|
|
3951
4043
|
return undefined;
|
|
3952
4044
|
}
|
|
3953
4045
|
// if we cast these lines infinitely in both directions, they intersect here:
|
|
3954
4046
|
return new Vertex(x, y);
|
|
3955
4047
|
}
|
|
3956
|
-
;
|
|
3957
4048
|
/**
|
|
3958
4049
|
* Create an SVG representation of this line.
|
|
3959
4050
|
*
|
|
@@ -3966,19 +4057,20 @@ class Line extends VertTuple {
|
|
|
3966
4057
|
* @memberof Line
|
|
3967
4058
|
**/
|
|
3968
4059
|
toSVGString(options) {
|
|
3969
|
-
options = options || {};
|
|
3970
|
-
var buffer = [];
|
|
3971
|
-
buffer.push('<line');
|
|
3972
|
-
if
|
|
3973
|
-
|
|
3974
|
-
buffer.push(' x1="' + this.a.x + '"');
|
|
3975
|
-
buffer.push(' y1="' + this.a.y + '"');
|
|
3976
|
-
buffer.push(' x2="' + this.b.x + '"');
|
|
3977
|
-
buffer.push(' y2="' + this.b.y + '"');
|
|
3978
|
-
buffer.push(' />');
|
|
3979
|
-
return buffer.join('');
|
|
4060
|
+
// options = options || {};
|
|
4061
|
+
// var buffer = [];
|
|
4062
|
+
// buffer.push( '<line' );
|
|
4063
|
+
// if( options.className )
|
|
4064
|
+
// buffer.push( ' class="' + options.className + '"' );
|
|
4065
|
+
// buffer.push( ' x1="' + this.a.x + '"' );
|
|
4066
|
+
// buffer.push( ' y1="' + this.a.y + '"' );
|
|
4067
|
+
// buffer.push( ' x2="' + this.b.x + '"' );
|
|
4068
|
+
// buffer.push( ' y2="' + this.b.y + '"' );
|
|
4069
|
+
// buffer.push( ' />' );
|
|
4070
|
+
// return buffer.join('');
|
|
4071
|
+
console.warn("[Deprecation] Warning: the Line.toSVGString method is deprecated and does not return and valid SVG data any more. Please use `drawutilssvg` instead.");
|
|
4072
|
+
return "";
|
|
3980
4073
|
}
|
|
3981
|
-
;
|
|
3982
4074
|
}
|
|
3983
4075
|
|
|
3984
4076
|
/**
|
|
@@ -3990,7 +4082,9 @@ class Line extends VertTuple {
|
|
|
3990
4082
|
* @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.
|
|
3991
4083
|
* @modified 2020-10-16 Added the containsCircle(...) function.
|
|
3992
4084
|
* @modified 2021-01-20 Added UID.
|
|
3993
|
-
* @
|
|
4085
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
4086
|
+
* @modified 2022-02-02 Cleared the `toSVGString` function (deprecated). Use `drawutilssvg` instead.
|
|
4087
|
+
* @version 1.3.0
|
|
3994
4088
|
**/
|
|
3995
4089
|
/**
|
|
3996
4090
|
* @classdesc A simple circle: center point and radius.
|
|
@@ -4021,7 +4115,6 @@ class Circle {
|
|
|
4021
4115
|
this.center = center;
|
|
4022
4116
|
this.radius = radius;
|
|
4023
4117
|
}
|
|
4024
|
-
;
|
|
4025
4118
|
/**
|
|
4026
4119
|
* Check if the given circle is fully contained inside this circle.
|
|
4027
4120
|
*
|
|
@@ -4034,7 +4127,6 @@ class Circle {
|
|
|
4034
4127
|
containsCircle(circle) {
|
|
4035
4128
|
return this.center.distance(circle.center) + circle.radius < this.radius;
|
|
4036
4129
|
}
|
|
4037
|
-
;
|
|
4038
4130
|
/**
|
|
4039
4131
|
* Calculate the distance from this circle to the given line.
|
|
4040
4132
|
*
|
|
@@ -4053,7 +4145,6 @@ class Circle {
|
|
|
4053
4145
|
const closestPointOnLine = line.getClosestPoint(this.center);
|
|
4054
4146
|
return closestPointOnLine.distance(this.center) - this.radius;
|
|
4055
4147
|
}
|
|
4056
|
-
;
|
|
4057
4148
|
/**
|
|
4058
4149
|
* Get the vertex on the this circle for the given angle.
|
|
4059
4150
|
*
|
|
@@ -4067,7 +4158,6 @@ class Circle {
|
|
|
4067
4158
|
// Find the point on the circle respective the angle. Then move relative to center.
|
|
4068
4159
|
return Circle.circleUtils.vertAt(angle, this.radius).add(this.center);
|
|
4069
4160
|
}
|
|
4070
|
-
;
|
|
4071
4161
|
/**
|
|
4072
4162
|
* Get a tangent line of this circle for a given angle.
|
|
4073
4163
|
*
|
|
@@ -4084,7 +4174,6 @@ class Circle {
|
|
|
4084
4174
|
// Construct the perpendicular of the line in point a. Then move relative to center.
|
|
4085
4175
|
return new Vector(pointA, new Vertex(0, 0)).add(this.center).perp();
|
|
4086
4176
|
}
|
|
4087
|
-
;
|
|
4088
4177
|
/**
|
|
4089
4178
|
* Calculate the intersection points (if exists) with the given circle.
|
|
4090
4179
|
*
|
|
@@ -4124,48 +4213,56 @@ class Circle {
|
|
|
4124
4213
|
// x4 = P2.x - h*(P1.y - P0.y)/d;
|
|
4125
4214
|
// y4 = P2.y + h*(P1.x - P0.x)/d;
|
|
4126
4215
|
// return pair<Point, Point>(Point(x3, y3), Point(x4, y4));
|
|
4127
|
-
// }
|
|
4216
|
+
// }
|
|
4128
4217
|
var p0 = this.center;
|
|
4129
4218
|
var p1 = circle.center;
|
|
4130
4219
|
var d = p0.distance(p1);
|
|
4131
4220
|
var a = (this.radius * this.radius - circle.radius * circle.radius + d * d) / (2 * d);
|
|
4132
4221
|
var h = Math.sqrt(this.radius * this.radius - a * a);
|
|
4133
4222
|
var p2 = p1.clone().scale(a / d, p0);
|
|
4134
|
-
var x3 = p2.x + h * (p1.y - p0.y) / d;
|
|
4135
|
-
var y3 = p2.y - h * (p1.x - p0.x) / d;
|
|
4136
|
-
var x4 = p2.x - h * (p1.y - p0.y) / d;
|
|
4137
|
-
var y4 = p2.y + h * (p1.x - p0.x) / d;
|
|
4223
|
+
var x3 = p2.x + (h * (p1.y - p0.y)) / d;
|
|
4224
|
+
var y3 = p2.y - (h * (p1.x - p0.x)) / d;
|
|
4225
|
+
var x4 = p2.x - (h * (p1.y - p0.y)) / d;
|
|
4226
|
+
var y4 = p2.y + (h * (p1.x - p0.x)) / d;
|
|
4138
4227
|
return new Line(new Vertex(x3, y3), new Vertex(x4, y4));
|
|
4139
4228
|
}
|
|
4140
|
-
;
|
|
4141
4229
|
/**
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4230
|
+
* Create an SVG representation of this circle.
|
|
4231
|
+
*
|
|
4232
|
+
* @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
|
|
4233
|
+
* @method toSVGString
|
|
4234
|
+
* @param {object=} options - An optional set of options, like 'className'.
|
|
4235
|
+
* @return {string} A string representing the SVG code for this vertex.
|
|
4236
|
+
* @instance
|
|
4237
|
+
* @memberof Circle
|
|
4238
|
+
*/
|
|
4151
4239
|
toSVGString(options) {
|
|
4152
|
-
options = options || {};
|
|
4153
|
-
var buffer = [];
|
|
4154
|
-
buffer.push(
|
|
4155
|
-
if (options.className)
|
|
4156
|
-
|
|
4157
|
-
buffer.push('
|
|
4158
|
-
buffer.push('
|
|
4159
|
-
buffer.push(
|
|
4160
|
-
buffer.
|
|
4161
|
-
return
|
|
4240
|
+
// options = options || {};
|
|
4241
|
+
// var buffer: Array<string> = [];
|
|
4242
|
+
// buffer.push("<circle");
|
|
4243
|
+
// if (options.className) buffer.push(' class="' + options.className + '"');
|
|
4244
|
+
// buffer.push(' cx="' + this.center.x + '"');
|
|
4245
|
+
// buffer.push(' cy="' + this.center.y + '"');
|
|
4246
|
+
// buffer.push(' r="' + this.radius + '"');
|
|
4247
|
+
// buffer.push(" />");
|
|
4248
|
+
// return buffer.join("");
|
|
4249
|
+
console.warn("[Deprecation] Warning: the Circle.toSVGString method is deprecated and does not return and valid SVG data any more. Please use `drawutilssvg` instead.");
|
|
4250
|
+
return "";
|
|
4251
|
+
}
|
|
4252
|
+
/**
|
|
4253
|
+
* This function should invalidate any installed listeners and invalidate this object.
|
|
4254
|
+
* After calling this function the object might not hold valid data any more and
|
|
4255
|
+
* should not be used.
|
|
4256
|
+
*/
|
|
4257
|
+
destroy() {
|
|
4258
|
+
this.center.destroy();
|
|
4259
|
+
this.isDestroyed = true;
|
|
4162
4260
|
}
|
|
4163
|
-
;
|
|
4164
4261
|
} // END class
|
|
4165
4262
|
Circle.circleUtils = {
|
|
4166
4263
|
vertAt: (angle, radius) => {
|
|
4167
4264
|
/* return new Vertex( Math.sin(angle) * radius,
|
|
4168
|
-
|
|
4265
|
+
Math.cos(angle) * radius ); */
|
|
4169
4266
|
return new Vertex(Math.cos(angle) * radius, Math.sin(angle) * radius);
|
|
4170
4267
|
}
|
|
4171
4268
|
};
|
|
@@ -4206,27 +4303,42 @@ class CircleSector {
|
|
|
4206
4303
|
this.startAngle = startAngle;
|
|
4207
4304
|
this.endAngle = endAngle;
|
|
4208
4305
|
}
|
|
4209
|
-
;
|
|
4210
4306
|
/**
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4307
|
+
* Create an SVG representation of this circle.
|
|
4308
|
+
*
|
|
4309
|
+
* @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
|
|
4310
|
+
* @method toSVGString
|
|
4311
|
+
* @param {object=} options - An optional set of options, like 'className'.
|
|
4312
|
+
* @return {string} A string representing the SVG code for this vertex.
|
|
4313
|
+
* @instance
|
|
4314
|
+
* @memberof Circle
|
|
4315
|
+
*/
|
|
4219
4316
|
toSVGString(options) {
|
|
4220
|
-
options = options || {};
|
|
4221
|
-
var buffer = [];
|
|
4222
|
-
buffer.push(
|
|
4223
|
-
if (options.className)
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4317
|
+
// options = options || {};
|
|
4318
|
+
// var buffer: Array<string> = [];
|
|
4319
|
+
// buffer.push("<path ");
|
|
4320
|
+
// if (options.className) buffer.push(' class="' + options.className + '"');
|
|
4321
|
+
// const data: SVGPathParams = CircleSector.circleSectorUtils.describeSVGArc(
|
|
4322
|
+
// this.circle.center.x,
|
|
4323
|
+
// this.circle.center.y,
|
|
4324
|
+
// this.circle.radius,
|
|
4325
|
+
// this.startAngle,
|
|
4326
|
+
// this.endAngle
|
|
4327
|
+
// );
|
|
4328
|
+
// buffer.push(' d="' + data.join(" ") + '" />');
|
|
4329
|
+
// return buffer.join("");
|
|
4330
|
+
console.warn("[Deprecation] Warning: the CircleSector.toSVGString method is deprecated and does not return and valid SVG data any more. Please use `drawutilssvg` instead.");
|
|
4331
|
+
return "";
|
|
4332
|
+
}
|
|
4333
|
+
/**
|
|
4334
|
+
* This function should invalidate any installed listeners and invalidate this object.
|
|
4335
|
+
* After calling this function the object might not hold valid data any more and
|
|
4336
|
+
* should not be used.
|
|
4337
|
+
*/
|
|
4338
|
+
destroy() {
|
|
4339
|
+
this.circle.destroy();
|
|
4340
|
+
this.isDestroyed = true;
|
|
4228
4341
|
}
|
|
4229
|
-
;
|
|
4230
4342
|
} // END class
|
|
4231
4343
|
CircleSector.circleSectorUtils = {
|
|
4232
4344
|
/**
|
|
@@ -4235,11 +4347,11 @@ CircleSector.circleSectorUtils = {
|
|
|
4235
4347
|
* TODO: generalize for ellipses (two radii).
|
|
4236
4348
|
*
|
|
4237
4349
|
* @param {number} angle - The angle in radians.
|
|
4238
|
-
|
|
4350
|
+
*/
|
|
4239
4351
|
polarToCartesian: (centerX, centerY, radius, angle) => {
|
|
4240
4352
|
return {
|
|
4241
|
-
x: centerX +
|
|
4242
|
-
y: centerY +
|
|
4353
|
+
x: centerX + radius * Math.cos(angle),
|
|
4354
|
+
y: centerY + radius * Math.sin(angle)
|
|
4243
4355
|
};
|
|
4244
4356
|
},
|
|
4245
4357
|
/**
|
|
@@ -4252,7 +4364,7 @@ CircleSector.circleSectorUtils = {
|
|
|
4252
4364
|
* @return [ 'A', radiusx, radiusy, rotation=0, largeArcFlag=1|0, sweepFlag=0, endx, endy ]
|
|
4253
4365
|
*/
|
|
4254
4366
|
describeSVGArc: (x, y, radius, startAngle, endAngle, options) => {
|
|
4255
|
-
if (typeof options ===
|
|
4367
|
+
if (typeof options === "undefined")
|
|
4256
4368
|
options = { moveToStart: true };
|
|
4257
4369
|
const end = CircleSector.circleSectorUtils.polarToCartesian(x, y, radius, endAngle);
|
|
4258
4370
|
const start = CircleSector.circleSectorUtils.polarToCartesian(x, y, radius, startAngle);
|
|
@@ -4277,7 +4389,7 @@ CircleSector.circleSectorUtils = {
|
|
|
4277
4389
|
}
|
|
4278
4390
|
const pathData = [];
|
|
4279
4391
|
if (options.moveToStart) {
|
|
4280
|
-
pathData.push(
|
|
4392
|
+
pathData.push("M", start.x, start.y);
|
|
4281
4393
|
}
|
|
4282
4394
|
pathData.push("A", radius, radius, 0, largeArcFlag, sweepFlag, end.x, end.y);
|
|
4283
4395
|
return pathData;
|
|
@@ -7067,7 +7179,9 @@ class GLU {
|
|
|
7067
7179
|
* @modified 2020-12-28 Added the `getArea` function.
|
|
7068
7180
|
* @modified 2021-01-20 Added UID.
|
|
7069
7181
|
* @modified 2021-01-22 Always updating circumcircle when retieving it.
|
|
7070
|
-
* @
|
|
7182
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
7183
|
+
* @modified 2022-02-02 Cleared the `Triangle.toSVGString` function (deprecated). Use `drawutilssvg` instead.
|
|
7184
|
+
* @version 2.6.0
|
|
7071
7185
|
*
|
|
7072
7186
|
* @file Triangle
|
|
7073
7187
|
* @fileoverview A simple triangle class: three vertices.
|
|
@@ -7128,7 +7242,6 @@ class Triangle {
|
|
|
7128
7242
|
throw `Cannot create triangle from array with less than three vertices (${arr.length})`;
|
|
7129
7243
|
return new Triangle(arr[0], arr[1], arr[2]);
|
|
7130
7244
|
}
|
|
7131
|
-
;
|
|
7132
7245
|
/**
|
|
7133
7246
|
* Get the area of this triangle. The returned area is never negative.
|
|
7134
7247
|
*
|
|
@@ -7144,7 +7257,6 @@ class Triangle {
|
|
|
7144
7257
|
getArea() {
|
|
7145
7258
|
return Math.abs(Triangle.utils.signedArea(this.a.x, this.a.y, this.b.x, this.b.y, this.c.x, this.c.y));
|
|
7146
7259
|
}
|
|
7147
|
-
;
|
|
7148
7260
|
/**
|
|
7149
7261
|
* Get the centroid of this triangle.
|
|
7150
7262
|
*
|
|
@@ -7158,7 +7270,6 @@ class Triangle {
|
|
|
7158
7270
|
getCentroid() {
|
|
7159
7271
|
return new Vertex((this.a.x + this.b.x + this.c.x) / 3, (this.a.y + this.b.y + this.c.y) / 3);
|
|
7160
7272
|
}
|
|
7161
|
-
;
|
|
7162
7273
|
/**
|
|
7163
7274
|
* Scale the triangle towards its centroid.
|
|
7164
7275
|
*
|
|
@@ -7175,7 +7286,6 @@ class Triangle {
|
|
|
7175
7286
|
this.c.scale(factor, centroid);
|
|
7176
7287
|
return this;
|
|
7177
7288
|
}
|
|
7178
|
-
;
|
|
7179
7289
|
/**
|
|
7180
7290
|
* Get the circumcircle of this triangle.
|
|
7181
7291
|
*
|
|
@@ -7192,11 +7302,10 @@ class Triangle {
|
|
|
7192
7302
|
* @memberof Triangle
|
|
7193
7303
|
*/
|
|
7194
7304
|
getCircumcircle() {
|
|
7195
|
-
// if( !this.center || !this.radius )
|
|
7305
|
+
// if( !this.center || !this.radius )
|
|
7196
7306
|
this.calcCircumcircle();
|
|
7197
7307
|
return new Circle(this.center.clone(), this.radius);
|
|
7198
7308
|
}
|
|
7199
|
-
;
|
|
7200
7309
|
/**
|
|
7201
7310
|
* Check if this triangle and the passed triangle share an
|
|
7202
7311
|
* adjacent edge.
|
|
@@ -7216,7 +7325,6 @@ class Triangle {
|
|
|
7216
7325
|
var c = this.c.equals(tri.a) || this.c.equals(tri.b) || this.c.equals(tri.c);
|
|
7217
7326
|
return (a && b) || (a && c) || (b && c);
|
|
7218
7327
|
}
|
|
7219
|
-
;
|
|
7220
7328
|
/**
|
|
7221
7329
|
* Get that vertex of this triangle (a,b,c) that is not vert1 nor vert2 of
|
|
7222
7330
|
* the passed two.
|
|
@@ -7229,14 +7337,13 @@ class Triangle {
|
|
|
7229
7337
|
* @memberof Triangle
|
|
7230
7338
|
*/
|
|
7231
7339
|
getThirdVertex(vert1, vert2) {
|
|
7232
|
-
if (this.a.equals(vert1) && this.b.equals(vert2) || this.a.equals(vert2) && this.b.equals(vert1))
|
|
7340
|
+
if ((this.a.equals(vert1) && this.b.equals(vert2)) || (this.a.equals(vert2) && this.b.equals(vert1)))
|
|
7233
7341
|
return this.c;
|
|
7234
|
-
if (this.b.equals(vert1) && this.c.equals(vert2) || this.b.equals(vert2) && this.c.equals(vert1))
|
|
7342
|
+
if ((this.b.equals(vert1) && this.c.equals(vert2)) || (this.b.equals(vert2) && this.c.equals(vert1)))
|
|
7235
7343
|
return this.a;
|
|
7236
7344
|
//if( this.c.equals(vert1) && this.a.equals(vert2) || this.c.equals(vert2) && this.a.equals(vert1) )
|
|
7237
7345
|
return this.b;
|
|
7238
7346
|
}
|
|
7239
|
-
;
|
|
7240
7347
|
/**
|
|
7241
7348
|
* Re-compute the circumcircle of this triangle (if the vertices
|
|
7242
7349
|
* have changed).
|
|
@@ -7276,8 +7383,7 @@ class Triangle {
|
|
|
7276
7383
|
}
|
|
7277
7384
|
this.radius_squared = dx * dx + dy * dy;
|
|
7278
7385
|
this.radius = Math.sqrt(this.radius_squared);
|
|
7279
|
-
}
|
|
7280
|
-
; // END calcCircumcircle
|
|
7386
|
+
} // END calcCircumcircle
|
|
7281
7387
|
/**
|
|
7282
7388
|
* Check if the passed vertex is inside this triangle's
|
|
7283
7389
|
* circumcircle.
|
|
@@ -7292,9 +7398,8 @@ class Triangle {
|
|
|
7292
7398
|
const dx = this.center.x - v.x;
|
|
7293
7399
|
const dy = this.center.y - v.y;
|
|
7294
7400
|
const dist_squared = dx * dx + dy * dy;
|
|
7295
|
-
return
|
|
7401
|
+
return dist_squared <= this.radius_squared;
|
|
7296
7402
|
}
|
|
7297
|
-
;
|
|
7298
7403
|
/**
|
|
7299
7404
|
* Get the rectangular bounds for this triangle.
|
|
7300
7405
|
*
|
|
@@ -7306,7 +7411,6 @@ class Triangle {
|
|
|
7306
7411
|
bounds() {
|
|
7307
7412
|
return new Bounds(new 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(Triangle.utils.max3(this.a.x, this.b.x, this.c.x), Triangle.utils.max3(this.a.y, this.b.y, this.c.y)));
|
|
7308
7413
|
}
|
|
7309
|
-
;
|
|
7310
7414
|
/**
|
|
7311
7415
|
* Convert this triangle to a polygon instance.
|
|
7312
7416
|
*
|
|
@@ -7320,7 +7424,6 @@ class Triangle {
|
|
|
7320
7424
|
toPolygon() {
|
|
7321
7425
|
return new Polygon([this.a, this.b, this.c]);
|
|
7322
7426
|
}
|
|
7323
|
-
;
|
|
7324
7427
|
/**
|
|
7325
7428
|
* Get the determinant of this triangle.
|
|
7326
7429
|
*
|
|
@@ -7333,7 +7436,6 @@ class Triangle {
|
|
|
7333
7436
|
// (b.y - a.y)*(c.x - b.x) - (c.y - b.y)*(b.x - a.x);
|
|
7334
7437
|
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);
|
|
7335
7438
|
}
|
|
7336
|
-
;
|
|
7337
7439
|
/**
|
|
7338
7440
|
* Checks if the passed vertex (p) is inside this triangle.
|
|
7339
7441
|
*
|
|
@@ -7348,7 +7450,6 @@ class Triangle {
|
|
|
7348
7450
|
containsPoint(p) {
|
|
7349
7451
|
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);
|
|
7350
7452
|
}
|
|
7351
|
-
;
|
|
7352
7453
|
/**
|
|
7353
7454
|
* Get that inner triangle which defines the maximal incircle.
|
|
7354
7455
|
*
|
|
@@ -7367,7 +7468,6 @@ class Triangle {
|
|
|
7367
7468
|
const circleIntersC = lineC.getClosestPoint(intersection);
|
|
7368
7469
|
return new Triangle(circleIntersA, circleIntersB, circleIntersC);
|
|
7369
7470
|
}
|
|
7370
|
-
;
|
|
7371
7471
|
/**
|
|
7372
7472
|
* Get the incircle of this triangle. That is the circle that touches each side
|
|
7373
7473
|
* of this triangle in exactly one point.
|
|
@@ -7379,7 +7479,6 @@ class Triangle {
|
|
|
7379
7479
|
getIncircle() {
|
|
7380
7480
|
return this.getIncircularTriangle().getCircumcircle();
|
|
7381
7481
|
}
|
|
7382
|
-
;
|
|
7383
7482
|
/**
|
|
7384
7483
|
* Get the incenter of this triangle (which is the center of the circumcircle).
|
|
7385
7484
|
*
|
|
@@ -7393,7 +7492,6 @@ class Triangle {
|
|
|
7393
7492
|
this.calcCircumcircle();
|
|
7394
7493
|
return this.center.clone();
|
|
7395
7494
|
}
|
|
7396
|
-
;
|
|
7397
7495
|
/**
|
|
7398
7496
|
* Converts this triangle into a human-readable string.
|
|
7399
7497
|
*
|
|
@@ -7403,9 +7501,8 @@ class Triangle {
|
|
|
7403
7501
|
* @memberof Triangle
|
|
7404
7502
|
*/
|
|
7405
7503
|
toString() {
|
|
7406
|
-
return
|
|
7504
|
+
return "{ a : " + this.a.toString() + ", b : " + this.b.toString() + ", c : " + this.c.toString() + "}";
|
|
7407
7505
|
}
|
|
7408
|
-
;
|
|
7409
7506
|
/**
|
|
7410
7507
|
* Create an SVG representation of this triangle.
|
|
7411
7508
|
*
|
|
@@ -7417,32 +7514,43 @@ class Triangle {
|
|
|
7417
7514
|
* @memberof Triangle
|
|
7418
7515
|
**/
|
|
7419
7516
|
toSVGString(options) {
|
|
7420
|
-
options = options || {};
|
|
7421
|
-
var buffer = [];
|
|
7422
|
-
buffer.push(
|
|
7423
|
-
if (options.className)
|
|
7424
|
-
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
buffer.
|
|
7443
|
-
return
|
|
7517
|
+
// options = options || {};
|
|
7518
|
+
// var buffer = [];
|
|
7519
|
+
// buffer.push("<path");
|
|
7520
|
+
// if (options.className) buffer.push(' class="' + options.className + '"');
|
|
7521
|
+
// buffer.push(' d="');
|
|
7522
|
+
// var vertices = [this.a, this.b, this.c];
|
|
7523
|
+
// if (vertices.length > 0) {
|
|
7524
|
+
// buffer.push("M ");
|
|
7525
|
+
// buffer.push(vertices[0].x);
|
|
7526
|
+
// buffer.push(" ");
|
|
7527
|
+
// buffer.push(vertices[0].y);
|
|
7528
|
+
// for (var i = 1; i < vertices.length; i++) {
|
|
7529
|
+
// buffer.push(" L ");
|
|
7530
|
+
// buffer.push(vertices[i].x);
|
|
7531
|
+
// buffer.push(" ");
|
|
7532
|
+
// buffer.push(vertices[i].y);
|
|
7533
|
+
// }
|
|
7534
|
+
// //if( !this.isOpen ) {
|
|
7535
|
+
// buffer.push(" Z");
|
|
7536
|
+
// //}
|
|
7537
|
+
// }
|
|
7538
|
+
// buffer.push('" />');
|
|
7539
|
+
// return buffer.join("");
|
|
7540
|
+
console.warn("[Deprecation] Warning: the Triangle.toSVGString method is deprecated and does not return and valid SVG data any more. Please use `drawutilssvg` instead.");
|
|
7541
|
+
return "";
|
|
7542
|
+
}
|
|
7543
|
+
/**
|
|
7544
|
+
* This function should invalidate any installed listeners and invalidate this object.
|
|
7545
|
+
* After calling this function the object might not hold valid data any more and
|
|
7546
|
+
* should not be used.
|
|
7547
|
+
*/
|
|
7548
|
+
destroy() {
|
|
7549
|
+
this.a.destroy();
|
|
7550
|
+
this.b.destroy();
|
|
7551
|
+
this.c.destroy();
|
|
7552
|
+
this.isDestroyed = true;
|
|
7444
7553
|
}
|
|
7445
|
-
;
|
|
7446
7554
|
}
|
|
7447
7555
|
/**
|
|
7448
7556
|
* An epsilon for comparison.
|
|
@@ -7454,10 +7562,10 @@ Triangle.EPSILON = 1.0e-6;
|
|
|
7454
7562
|
Triangle.utils = {
|
|
7455
7563
|
// Used in the bounds() function.
|
|
7456
7564
|
max3(a, b, c) {
|
|
7457
|
-
return
|
|
7565
|
+
return a >= b && a >= c ? a : b >= a && b >= c ? b : c;
|
|
7458
7566
|
},
|
|
7459
7567
|
min3(a, b, c) {
|
|
7460
|
-
return
|
|
7568
|
+
return a <= b && a <= c ? a : b <= a && b <= c ? b : c;
|
|
7461
7569
|
},
|
|
7462
7570
|
signedArea(p0x, p0y, p1x, p1y, p2x, p2y) {
|
|
7463
7571
|
return 0.5 * (-p1y * p2x + p0y * (-p1x + p2x) + p0x * (p1y - p2y) + p1x * p2y);
|
|
@@ -7473,9 +7581,9 @@ Triangle.utils = {
|
|
|
7473
7581
|
// http://stackoverflow.com/questions/2049582/how-to-determine-a-point-in-a-2d-triangle
|
|
7474
7582
|
// var area : number = 1/2*(-p1y*p2x + p0y*(-p1x + p2x) + p0x*(p1y - p2y) + p1x*p2y);
|
|
7475
7583
|
var area = Triangle.utils.signedArea(p0x, p0y, p1x, p1y, p2x, p2y);
|
|
7476
|
-
var s = 1 / (2 * area) * (p0y * p2x - p0x * p2y + (p2y - p0y) * px + (p0x - p2x) * py);
|
|
7477
|
-
var t = 1 / (2 * area) * (p0x * p1y - p0y * p1x + (p0y - p1y) * px + (p1x - p0x) * py);
|
|
7478
|
-
return s > 0 && t > 0 &&
|
|
7584
|
+
var s = (1 / (2 * area)) * (p0y * p2x - p0x * p2y + (p2y - p0y) * px + (p0x - p2x) * py);
|
|
7585
|
+
var t = (1 / (2 * area)) * (p0x * p1y - p0y * p1x + (p0y - p1y) * px + (p1x - p0x) * py);
|
|
7586
|
+
return s > 0 && t > 0 && 1 - s - t > 0;
|
|
7479
7587
|
}
|
|
7480
7588
|
};
|
|
7481
7589
|
|
|
@@ -7646,7 +7754,8 @@ Grid.utils = {
|
|
|
7646
7754
|
* @modified 2020-07-28 Changed the `delete` key code from 8 to 46.
|
|
7647
7755
|
* @modified 2020-10-04 Changed `window` to `globalThis`.
|
|
7648
7756
|
* @modified 2020-10-04 Added extended JSDoc.
|
|
7649
|
-
* @
|
|
7757
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
7758
|
+
* @version 1.1.0
|
|
7650
7759
|
*
|
|
7651
7760
|
* @file KeyHandler
|
|
7652
7761
|
* @public
|
|
@@ -7677,7 +7786,7 @@ class KeyHandler {
|
|
|
7677
7786
|
* @memberof KeyHandler
|
|
7678
7787
|
* @param {HTMLElement} options.element (optional) The HTML element to listen on; if null then 'window' will be used.
|
|
7679
7788
|
* @param {boolean} options.trackAll (optional) Set to true if you want to keep track of _all_ keys (keyStatus).
|
|
7680
|
-
|
|
7789
|
+
**/
|
|
7681
7790
|
constructor(options) {
|
|
7682
7791
|
this.downListeners = [];
|
|
7683
7792
|
this.pressListeners = [];
|
|
@@ -7696,7 +7805,6 @@ class KeyHandler {
|
|
|
7696
7805
|
// Install the listeners
|
|
7697
7806
|
this.installListeners();
|
|
7698
7807
|
}
|
|
7699
|
-
;
|
|
7700
7808
|
/**
|
|
7701
7809
|
* A helper function to fire key events from this KeyHandler.
|
|
7702
7810
|
*
|
|
@@ -7714,7 +7822,6 @@ class KeyHandler {
|
|
|
7714
7822
|
}
|
|
7715
7823
|
return hasListener;
|
|
7716
7824
|
}
|
|
7717
|
-
;
|
|
7718
7825
|
/**
|
|
7719
7826
|
* Internal function to fire a new keydown event to all listeners.
|
|
7720
7827
|
* You should not call this function on your own unless you know what you do.
|
|
@@ -7730,10 +7837,9 @@ class KeyHandler {
|
|
|
7730
7837
|
fireDownEvent(e, handler) {
|
|
7731
7838
|
if (handler.fireEvent(e, handler.downListeners) || handler.trackAllKeys) {
|
|
7732
7839
|
// Down event has listeners. Update key state.
|
|
7733
|
-
handler.keyStates[e.keyCode] =
|
|
7840
|
+
handler.keyStates[e.keyCode] = "down";
|
|
7734
7841
|
}
|
|
7735
7842
|
}
|
|
7736
|
-
;
|
|
7737
7843
|
/**
|
|
7738
7844
|
* Internal function to fire a new keypress event to all listeners.
|
|
7739
7845
|
* You should not call this function on your own unless you know what you do.
|
|
@@ -7749,7 +7855,6 @@ class KeyHandler {
|
|
|
7749
7855
|
firePressEvent(e, handler) {
|
|
7750
7856
|
handler.fireEvent(e, handler.pressListeners);
|
|
7751
7857
|
}
|
|
7752
|
-
;
|
|
7753
7858
|
/**
|
|
7754
7859
|
* Internal function to fire a new keyup event to all listeners.
|
|
7755
7860
|
* You should not call this function on your own unless you know what you do.
|
|
@@ -7768,20 +7873,18 @@ class KeyHandler {
|
|
|
7768
7873
|
delete handler.keyStates[e.keyCode];
|
|
7769
7874
|
}
|
|
7770
7875
|
}
|
|
7771
|
-
;
|
|
7772
7876
|
/**
|
|
7773
7877
|
* Resolve the key/name code.
|
|
7774
7878
|
*/
|
|
7775
7879
|
static key2code(key) {
|
|
7776
|
-
if (typeof key ==
|
|
7880
|
+
if (typeof key == "number")
|
|
7777
7881
|
return key;
|
|
7778
|
-
if (typeof key !=
|
|
7882
|
+
if (typeof key != "string")
|
|
7779
7883
|
throw "Unknown key name or key type (should be a string or integer): " + key;
|
|
7780
7884
|
if (KeyHandler.KEY_CODES[key])
|
|
7781
7885
|
return KeyHandler.KEY_CODES[key];
|
|
7782
7886
|
throw "Unknown key (cannot resolve key code): " + key;
|
|
7783
7887
|
}
|
|
7784
|
-
;
|
|
7785
7888
|
/**
|
|
7786
7889
|
* Install the required listeners into the initially passed element.
|
|
7787
7890
|
*
|
|
@@ -7790,20 +7893,24 @@ class KeyHandler {
|
|
|
7790
7893
|
*/
|
|
7791
7894
|
installListeners() {
|
|
7792
7895
|
var _self = this;
|
|
7793
|
-
this.element.addEventListener(
|
|
7794
|
-
|
|
7795
|
-
|
|
7896
|
+
this.element.addEventListener("keydown", (this._keyDownListener = (e) => {
|
|
7897
|
+
_self.fireDownEvent(e, _self);
|
|
7898
|
+
}));
|
|
7899
|
+
this.element.addEventListener("keypress", (this._keyPressListener = (e) => {
|
|
7900
|
+
_self.firePressEvent(e, _self);
|
|
7901
|
+
}));
|
|
7902
|
+
this.element.addEventListener("keyup", (this._keyUpListener = (e) => {
|
|
7903
|
+
_self.fireUpEvent(e, _self);
|
|
7904
|
+
}));
|
|
7796
7905
|
}
|
|
7797
|
-
;
|
|
7798
7906
|
/**
|
|
7799
7907
|
* Remove all installed event listeners from the underlying element.
|
|
7800
7908
|
*/
|
|
7801
7909
|
releaseListeners() {
|
|
7802
|
-
this.element.removeEventListener(
|
|
7803
|
-
this.element.removeEventListener(
|
|
7804
|
-
this.element.removeEventListener(
|
|
7910
|
+
this.element.removeEventListener("keydown", this._keyDownListener);
|
|
7911
|
+
this.element.removeEventListener("keypress", this._keyPressListener);
|
|
7912
|
+
this.element.removeEventListener("keyup", this._keyUpListener);
|
|
7805
7913
|
}
|
|
7806
|
-
;
|
|
7807
7914
|
/**
|
|
7808
7915
|
* Listen for key down. This function allows chaining.
|
|
7809
7916
|
*
|
|
@@ -7820,7 +7927,6 @@ class KeyHandler {
|
|
|
7820
7927
|
this.downListeners.push({ key: key, keyCode: KeyHandler.key2code(key), listener: listener });
|
|
7821
7928
|
return this;
|
|
7822
7929
|
}
|
|
7823
|
-
;
|
|
7824
7930
|
/**
|
|
7825
7931
|
* Listen for key press.
|
|
7826
7932
|
*
|
|
@@ -7837,7 +7943,6 @@ class KeyHandler {
|
|
|
7837
7943
|
this.pressListeners.push({ key: key, keyCode: KeyHandler.key2code(key), listener: listener });
|
|
7838
7944
|
return this;
|
|
7839
7945
|
}
|
|
7840
|
-
;
|
|
7841
7946
|
/**
|
|
7842
7947
|
* Listen for key up.
|
|
7843
7948
|
*
|
|
@@ -7854,23 +7959,31 @@ class KeyHandler {
|
|
|
7854
7959
|
this.upListeners.push({ key: key, keyCode: KeyHandler.key2code(key), listener: listener });
|
|
7855
7960
|
return this;
|
|
7856
7961
|
}
|
|
7857
|
-
;
|
|
7858
7962
|
/**
|
|
7859
7963
|
* Check if a specific key is currently held pressed.
|
|
7860
7964
|
*
|
|
7861
7965
|
* @param {string|number} key - Any key identifier, key code or one from the KEY_CODES list.
|
|
7862
7966
|
*/
|
|
7863
7967
|
isDown(key) {
|
|
7864
|
-
if (typeof key ==
|
|
7968
|
+
if (typeof key == "number")
|
|
7865
7969
|
return this.keyStates[key] ? true : false;
|
|
7866
7970
|
else
|
|
7867
7971
|
return this.keyStates[KeyHandler.key2code(key)] ? true : false;
|
|
7868
7972
|
}
|
|
7973
|
+
/**
|
|
7974
|
+
* This function should invalidate any installed listeners and invalidate this object.
|
|
7975
|
+
* After calling this function the object might not hold valid data any more and
|
|
7976
|
+
* should not be used any more.
|
|
7977
|
+
*/
|
|
7978
|
+
destroy() {
|
|
7979
|
+
this.releaseListeners();
|
|
7980
|
+
}
|
|
7869
7981
|
}
|
|
7870
7982
|
/**
|
|
7871
7983
|
* Source:
|
|
7872
7984
|
* https://keycode.info/
|
|
7873
7985
|
*/
|
|
7986
|
+
// prettier-ignore
|
|
7874
7987
|
KeyHandler.KEY_CODES = {
|
|
7875
7988
|
'break': 3,
|
|
7876
7989
|
'backspace': 8,
|
|
@@ -8187,41 +8300,41 @@ class MouseHandler {
|
|
|
8187
8300
|
// | drag offset, ...) to the callbacks.
|
|
8188
8301
|
// +-------------------------------------------------
|
|
8189
8302
|
const _self = this;
|
|
8190
|
-
this.handlers[
|
|
8303
|
+
this.handlers["mousemove"] = (e) => {
|
|
8191
8304
|
if (_self.listeners.mousemove)
|
|
8192
|
-
_self.listeners.mousemove(_self.mkParams(e,
|
|
8305
|
+
_self.listeners.mousemove(_self.mkParams(e, "mousemove"));
|
|
8193
8306
|
if (_self.mouseDragPos && _self.listeners.drag)
|
|
8194
|
-
_self.listeners.drag(_self.mkParams(e,
|
|
8307
|
+
_self.listeners.drag(_self.mkParams(e, "drag"));
|
|
8195
8308
|
if (_self.mouseDownPos)
|
|
8196
8309
|
_self.mouseDragPos = _self.relPos(e);
|
|
8197
8310
|
};
|
|
8198
|
-
this.handlers[
|
|
8311
|
+
this.handlers["mouseup"] = (e) => {
|
|
8199
8312
|
if (_self.listeners.mouseup)
|
|
8200
|
-
_self.listeners.mouseup(_self.mkParams(e,
|
|
8313
|
+
_self.listeners.mouseup(_self.mkParams(e, "mouseup"));
|
|
8201
8314
|
_self.mouseDragPos = undefined;
|
|
8202
8315
|
_self.mouseDownPos = undefined;
|
|
8203
8316
|
_self.mouseButton = -1;
|
|
8204
8317
|
};
|
|
8205
|
-
this.handlers[
|
|
8318
|
+
this.handlers["mousedown"] = (e) => {
|
|
8206
8319
|
_self.mouseDragPos = _self.relPos(e);
|
|
8207
8320
|
_self.mouseDownPos = _self.relPos(e);
|
|
8208
8321
|
_self.mouseButton = e.button;
|
|
8209
8322
|
if (_self.listeners.mousedown)
|
|
8210
|
-
_self.listeners.mousedown(_self.mkParams(e,
|
|
8323
|
+
_self.listeners.mousedown(_self.mkParams(e, "mousedown"));
|
|
8211
8324
|
};
|
|
8212
|
-
this.handlers[
|
|
8325
|
+
this.handlers["click"] = (e) => {
|
|
8213
8326
|
if (_self.listeners.click)
|
|
8214
|
-
_self.listeners.click(_self.mkParams(e,
|
|
8327
|
+
_self.listeners.click(_self.mkParams(e, "click"));
|
|
8215
8328
|
};
|
|
8216
|
-
this.handlers[
|
|
8329
|
+
this.handlers["wheel"] = (e) => {
|
|
8217
8330
|
if (_self.listeners.wheel)
|
|
8218
|
-
_self.listeners.wheel(_self.mkParams(e,
|
|
8331
|
+
_self.listeners.wheel(_self.mkParams(e, "wheel"));
|
|
8219
8332
|
};
|
|
8220
|
-
this.element.addEventListener(
|
|
8221
|
-
this.element.addEventListener(
|
|
8222
|
-
this.element.addEventListener(
|
|
8223
|
-
this.element.addEventListener(
|
|
8224
|
-
this.element.addEventListener(
|
|
8333
|
+
this.element.addEventListener("mousemove", this.handlers["mousemove"]);
|
|
8334
|
+
this.element.addEventListener("mouseup", this.handlers["mouseup"]);
|
|
8335
|
+
this.element.addEventListener("mousedown", this.handlers["mousedown"]);
|
|
8336
|
+
this.element.addEventListener("click", this.handlers["click"]);
|
|
8337
|
+
this.element.addEventListener("wheel", this.handlers["wheel"]);
|
|
8225
8338
|
}
|
|
8226
8339
|
/**
|
|
8227
8340
|
* Get relative position from the given MouseEvent.
|
|
@@ -8234,11 +8347,8 @@ class MouseHandler {
|
|
|
8234
8347
|
* @return {XYCoords} The relative mouse coordinates.
|
|
8235
8348
|
*/
|
|
8236
8349
|
relPos(e) {
|
|
8237
|
-
return { x: e.offsetX,
|
|
8238
|
-
y: e.offsetY
|
|
8239
|
-
};
|
|
8350
|
+
return { x: e.offsetX, y: e.offsetY };
|
|
8240
8351
|
}
|
|
8241
|
-
;
|
|
8242
8352
|
/**
|
|
8243
8353
|
* Build the extended event params.
|
|
8244
8354
|
*
|
|
@@ -8264,8 +8374,8 @@ class MouseHandler {
|
|
|
8264
8374
|
rightButton: this.mouseButton == 2,
|
|
8265
8375
|
mouseDownPos: this.mouseDownPos,
|
|
8266
8376
|
draggedFrom: this.mouseDragPos,
|
|
8267
|
-
wasDragged:
|
|
8268
|
-
dragAmount:
|
|
8377
|
+
wasDragged: this.mouseDownPos != null && (this.mouseDownPos.x != rel.x || this.mouseDownPos.y != rel.y),
|
|
8378
|
+
dragAmount: this.mouseDownPos != null ? { x: rel.x - this.mouseDragPos.x, y: rel.y - this.mouseDragPos.y } : { x: 0, y: 0 }
|
|
8269
8379
|
};
|
|
8270
8380
|
return xEvent;
|
|
8271
8381
|
}
|
|
@@ -8316,14 +8426,13 @@ class MouseHandler {
|
|
|
8316
8426
|
*/
|
|
8317
8427
|
drag(callback) {
|
|
8318
8428
|
if (this.listeners.drag)
|
|
8319
|
-
this.throwAlreadyInstalled(
|
|
8429
|
+
this.throwAlreadyInstalled("drag");
|
|
8320
8430
|
this.listeners.drag = callback;
|
|
8321
|
-
this.listenFor(
|
|
8322
|
-
this.listenFor(
|
|
8323
|
-
this.listenFor(
|
|
8431
|
+
this.listenFor("mousedown");
|
|
8432
|
+
this.listenFor("mousemove");
|
|
8433
|
+
this.listenFor("mouseup");
|
|
8324
8434
|
return this;
|
|
8325
8435
|
}
|
|
8326
|
-
;
|
|
8327
8436
|
/**
|
|
8328
8437
|
* Installer function to listen for a specific event: mouse-move.
|
|
8329
8438
|
* Pass your callbacks here.
|
|
@@ -8338,12 +8447,11 @@ class MouseHandler {
|
|
|
8338
8447
|
*/
|
|
8339
8448
|
move(callback) {
|
|
8340
8449
|
if (this.listeners.mousemove)
|
|
8341
|
-
this.throwAlreadyInstalled(
|
|
8342
|
-
this.listenFor(
|
|
8450
|
+
this.throwAlreadyInstalled("mousemove");
|
|
8451
|
+
this.listenFor("mousemove");
|
|
8343
8452
|
this.listeners.mousemove = callback;
|
|
8344
8453
|
return this;
|
|
8345
8454
|
}
|
|
8346
|
-
;
|
|
8347
8455
|
/**
|
|
8348
8456
|
* Installer function to listen for a specific event: mouse-up.
|
|
8349
8457
|
* Pass your callbacks here.
|
|
@@ -8358,12 +8466,11 @@ class MouseHandler {
|
|
|
8358
8466
|
*/
|
|
8359
8467
|
up(callback) {
|
|
8360
8468
|
if (this.listeners.mouseup)
|
|
8361
|
-
this.throwAlreadyInstalled(
|
|
8362
|
-
this.listenFor(
|
|
8469
|
+
this.throwAlreadyInstalled("mouseup");
|
|
8470
|
+
this.listenFor("mouseup");
|
|
8363
8471
|
this.listeners.mouseup = callback;
|
|
8364
8472
|
return this;
|
|
8365
8473
|
}
|
|
8366
|
-
;
|
|
8367
8474
|
/**
|
|
8368
8475
|
* Installer function to listen for a specific event: mouse-down.
|
|
8369
8476
|
* Pass your callbacks here.
|
|
@@ -8378,12 +8485,11 @@ class MouseHandler {
|
|
|
8378
8485
|
*/
|
|
8379
8486
|
down(callback) {
|
|
8380
8487
|
if (this.listeners.mousedown)
|
|
8381
|
-
this.throwAlreadyInstalled(
|
|
8382
|
-
this.listenFor(
|
|
8488
|
+
this.throwAlreadyInstalled("mousedown");
|
|
8489
|
+
this.listenFor("mousedown");
|
|
8383
8490
|
this.listeners.mousedown = callback;
|
|
8384
8491
|
return this;
|
|
8385
8492
|
}
|
|
8386
|
-
;
|
|
8387
8493
|
/**
|
|
8388
8494
|
* Installer function to listen for a specific event: mouse-click.
|
|
8389
8495
|
* Pass your callbacks here.
|
|
@@ -8398,12 +8504,11 @@ class MouseHandler {
|
|
|
8398
8504
|
*/
|
|
8399
8505
|
click(callback) {
|
|
8400
8506
|
if (this.listeners.click)
|
|
8401
|
-
this.throwAlreadyInstalled(
|
|
8402
|
-
this.listenFor(
|
|
8507
|
+
this.throwAlreadyInstalled("click");
|
|
8508
|
+
this.listenFor("click");
|
|
8403
8509
|
this.listeners.click = callback;
|
|
8404
8510
|
return this;
|
|
8405
8511
|
}
|
|
8406
|
-
;
|
|
8407
8512
|
/**
|
|
8408
8513
|
* Installer function to listen for a specific event: mouse-wheel.
|
|
8409
8514
|
* Pass your callbacks here.
|
|
@@ -8418,12 +8523,11 @@ class MouseHandler {
|
|
|
8418
8523
|
*/
|
|
8419
8524
|
wheel(callback) {
|
|
8420
8525
|
if (this.listeners.wheel)
|
|
8421
|
-
this.throwAlreadyInstalled(
|
|
8422
|
-
this.listenFor(
|
|
8526
|
+
this.throwAlreadyInstalled("wheel");
|
|
8527
|
+
this.listenFor("wheel");
|
|
8423
8528
|
this.listeners.wheel = callback;
|
|
8424
8529
|
return this;
|
|
8425
8530
|
}
|
|
8426
|
-
;
|
|
8427
8531
|
/**
|
|
8428
8532
|
* An internal function to throw events.
|
|
8429
8533
|
*
|
|
@@ -8437,7 +8541,6 @@ class MouseHandler {
|
|
|
8437
8541
|
throwAlreadyInstalled(name) {
|
|
8438
8542
|
throw `This MouseHandler already has a '${name}' callback. To keep the code simple there is only room for one.`;
|
|
8439
8543
|
}
|
|
8440
|
-
;
|
|
8441
8544
|
/**
|
|
8442
8545
|
* Call this when your work is done.
|
|
8443
8546
|
*
|
|
@@ -8450,16 +8553,16 @@ class MouseHandler {
|
|
|
8450
8553
|
* @return {void}
|
|
8451
8554
|
*/
|
|
8452
8555
|
destroy() {
|
|
8453
|
-
this.unlistenFor(
|
|
8454
|
-
this.unlistenFor(
|
|
8455
|
-
this.unlistenFor(
|
|
8456
|
-
this.unlistenFor(
|
|
8457
|
-
this.unlistenFor(
|
|
8458
|
-
this.element.removeEventListener(
|
|
8459
|
-
this.element.removeEventListener(
|
|
8460
|
-
this.element.removeEventListener(
|
|
8461
|
-
this.element.removeEventListener(
|
|
8462
|
-
this.element.removeEventListener(
|
|
8556
|
+
this.unlistenFor("mousedown");
|
|
8557
|
+
this.unlistenFor("mousemove");
|
|
8558
|
+
this.unlistenFor("moseup");
|
|
8559
|
+
this.unlistenFor("click");
|
|
8560
|
+
this.unlistenFor("wheel");
|
|
8561
|
+
this.element.removeEventListener("mousemove", this.handlers["mousemove"]);
|
|
8562
|
+
this.element.removeEventListener("mouseup", this.handlers["mousedown"]);
|
|
8563
|
+
this.element.removeEventListener("mousedown", this.handlers["mousedown"]);
|
|
8564
|
+
this.element.removeEventListener("click", this.handlers["click"]);
|
|
8565
|
+
this.element.removeEventListener("wheel", this.handlers["wheel"]);
|
|
8463
8566
|
}
|
|
8464
8567
|
}
|
|
8465
8568
|
|
|
@@ -8469,7 +8572,9 @@ class MouseHandler {
|
|
|
8469
8572
|
* @modified 2019-03-23 Added JSDoc tags.
|
|
8470
8573
|
* @modified 2020-03-25 Ported this class from vanilla-JS to Typescript.
|
|
8471
8574
|
* @modified 2021-01-20 Added UID.
|
|
8472
|
-
* @
|
|
8575
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
8576
|
+
* @modified 2022-02-02 Cleared the `PBImage.toSVGString` function (deprecated). Use `drawutilssvg` instead.
|
|
8577
|
+
* @version 1.2.0
|
|
8473
8578
|
*
|
|
8474
8579
|
* @file PBImage
|
|
8475
8580
|
* @fileoverview As native Image objects have only a position and with
|
|
@@ -8504,7 +8609,6 @@ class PBImage {
|
|
|
8504
8609
|
this.upperLeft = upperLeft;
|
|
8505
8610
|
this.lowerRight = lowerRight;
|
|
8506
8611
|
}
|
|
8507
|
-
;
|
|
8508
8612
|
/**
|
|
8509
8613
|
* Convert this vertex to SVG code.
|
|
8510
8614
|
*
|
|
@@ -8519,13 +8623,23 @@ class PBImage {
|
|
|
8519
8623
|
console.warn("PBImage is not yet SVG serializable. Returning empty SVG string.");
|
|
8520
8624
|
return "";
|
|
8521
8625
|
}
|
|
8522
|
-
|
|
8626
|
+
/**
|
|
8627
|
+
* This function should invalidate any installed listeners and invalidate this object.
|
|
8628
|
+
* After calling this function the object might not hold valid data any more and
|
|
8629
|
+
* should not be used.
|
|
8630
|
+
*/
|
|
8631
|
+
destroy() {
|
|
8632
|
+
this.upperLeft.destroy();
|
|
8633
|
+
this.lowerRight.destroy();
|
|
8634
|
+
this.isDestroyed = true;
|
|
8635
|
+
}
|
|
8523
8636
|
}
|
|
8524
8637
|
|
|
8525
8638
|
/**
|
|
8526
8639
|
* @author Ikaros Kappler
|
|
8527
8640
|
* @date 2021-11-16
|
|
8528
|
-
* @
|
|
8641
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
8642
|
+
* @version 1.1.0
|
|
8529
8643
|
**/
|
|
8530
8644
|
/**
|
|
8531
8645
|
* @classdesc A simple text element: position, fontSize, fontFamily, color, textAlign, lineHeight and rotation.
|
|
@@ -8579,6 +8693,15 @@ class PBText {
|
|
|
8579
8693
|
console.warn("[PBText.toSVGString()] This function is not implemented as it defines a deprecated method. Use the 'drawutilssvg.text()' method instead.");
|
|
8580
8694
|
return "";
|
|
8581
8695
|
}
|
|
8696
|
+
/**
|
|
8697
|
+
* This function should invalidate any installed listeners and invalidate this object.
|
|
8698
|
+
* After calling this function the object might not hold valid data any more and
|
|
8699
|
+
* should not be used.
|
|
8700
|
+
*/
|
|
8701
|
+
destroy() {
|
|
8702
|
+
this.anchor.destroy();
|
|
8703
|
+
this.isDestroyed = true;
|
|
8704
|
+
}
|
|
8582
8705
|
} // END class
|
|
8583
8706
|
|
|
8584
8707
|
/* Port from AlloyFinger v0.1.15
|
|
@@ -8982,7 +9105,9 @@ class AlloyFinger {
|
|
|
8982
9105
|
* @modified 2021-03-10 Added the `toCubicBezier` method.
|
|
8983
9106
|
* @modified 2021-03-15 Added `VEllipse.quarterSegmentCount` and `VEllipse.scale` functions.
|
|
8984
9107
|
* @modified 2021-03-19 Added the `VEllipse.rotate` function.
|
|
8985
|
-
* @
|
|
9108
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
9109
|
+
* @modified 2022-02-02 Cleared the `VEllipse.toSVGString` function (deprecated). Use `drawutilssvg` instead.
|
|
9110
|
+
* @version 1.3.0
|
|
8986
9111
|
*
|
|
8987
9112
|
* @file VEllipse
|
|
8988
9113
|
* @fileoverview Ellipses with a center and an x- and a y-axis (stored as a vertex).
|
|
@@ -9308,17 +9433,28 @@ class VEllipse {
|
|
|
9308
9433
|
* @return string The SVG string
|
|
9309
9434
|
*/
|
|
9310
9435
|
toSVGString(options) {
|
|
9311
|
-
options = options || {};
|
|
9312
|
-
var buffer = [];
|
|
9313
|
-
buffer.push("<ellipse");
|
|
9314
|
-
if (options.className)
|
|
9315
|
-
|
|
9316
|
-
buffer.push('
|
|
9317
|
-
buffer.push('
|
|
9318
|
-
buffer.push('
|
|
9319
|
-
buffer.push(
|
|
9320
|
-
buffer.
|
|
9321
|
-
return
|
|
9436
|
+
// options = options || {};
|
|
9437
|
+
// var buffer: Array<string> = [];
|
|
9438
|
+
// buffer.push("<ellipse");
|
|
9439
|
+
// if (options.className) buffer.push(' class="' + options.className + '"');
|
|
9440
|
+
// buffer.push(' cx="' + this.center.x + '"');
|
|
9441
|
+
// buffer.push(' cy="' + this.center.y + '"');
|
|
9442
|
+
// buffer.push(' rx="' + this.axis.x + '"');
|
|
9443
|
+
// buffer.push(' ry="' + this.axis.y + '"');
|
|
9444
|
+
// buffer.push(" />");
|
|
9445
|
+
// return buffer.join("");
|
|
9446
|
+
console.warn("[Deprecation] Warning: the VEllipse.toSVGString method is deprecated and does not return and valid SVG data any more. Please use `drawutilssvg` instead.");
|
|
9447
|
+
return "";
|
|
9448
|
+
}
|
|
9449
|
+
/**
|
|
9450
|
+
* This function should invalidate any installed listeners and invalidate this object.
|
|
9451
|
+
* After calling this function the object might not hold valid data any more and
|
|
9452
|
+
* should not be used.
|
|
9453
|
+
*/
|
|
9454
|
+
destroy() {
|
|
9455
|
+
this.center.destroy();
|
|
9456
|
+
this.axis.destroy();
|
|
9457
|
+
this.isDestroyed = true;
|
|
9322
9458
|
}
|
|
9323
9459
|
}
|
|
9324
9460
|
/**
|
|
@@ -9385,7 +9521,8 @@ VEllipse.utils = {
|
|
|
9385
9521
|
*
|
|
9386
9522
|
* @author Ikaros Kappler
|
|
9387
9523
|
* @date 2021-02-26
|
|
9388
|
-
* @
|
|
9524
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
9525
|
+
* @version 1.1.0
|
|
9389
9526
|
*/
|
|
9390
9527
|
/**
|
|
9391
9528
|
* @classdesc A class for elliptic sectors.
|
|
@@ -9471,6 +9608,15 @@ class VEllipseSector {
|
|
|
9471
9608
|
}
|
|
9472
9609
|
return curves;
|
|
9473
9610
|
}
|
|
9611
|
+
/**
|
|
9612
|
+
* This function should invalidate any installed listeners and invalidate this object.
|
|
9613
|
+
* After calling this function the object might not hold valid data any more and
|
|
9614
|
+
* should not be used.
|
|
9615
|
+
*/
|
|
9616
|
+
destroy() {
|
|
9617
|
+
this.ellipse.destroy();
|
|
9618
|
+
this.isDestroyed = true;
|
|
9619
|
+
}
|
|
9474
9620
|
}
|
|
9475
9621
|
VEllipseSector.ellipseSectorUtils = {
|
|
9476
9622
|
/**
|
|
@@ -10321,7 +10467,7 @@ class PlotBoilerplate {
|
|
|
10321
10467
|
}
|
|
10322
10468
|
}
|
|
10323
10469
|
for (var i = 0; i < this.drawables.length; i++) {
|
|
10324
|
-
if (this.drawables[i] === drawable) {
|
|
10470
|
+
if (this.drawables[i] === drawable || this.drawables[i].uid === drawable.uid) {
|
|
10325
10471
|
this.drawables.splice(i, 1);
|
|
10326
10472
|
if (removeWithVertices) {
|
|
10327
10473
|
// Check if some listeners need to be removed
|