@joint/core 4.1.2 → 4.2.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/geometry.js +128 -123
- package/dist/geometry.min.js +2 -2
- package/dist/joint.d.ts +79 -16
- package/dist/joint.js +2249 -1730
- package/dist/joint.min.js +2 -2
- package/dist/joint.nowrap.js +2248 -1727
- package/dist/joint.nowrap.min.js +2 -2
- package/dist/vectorizer.js +469 -272
- package/dist/vectorizer.min.js +2 -2
- package/dist/version.mjs +1 -1
- package/package.json +28 -22
- package/src/V/create.mjs +51 -0
- package/src/V/index.mjs +69 -154
- package/src/V/namespace.mjs +9 -0
- package/src/V/transform.mjs +183 -0
- package/src/V/traverse.mjs +16 -0
- package/src/anchors/index.mjs +140 -33
- package/src/cellTools/Boundary.mjs +1 -1
- package/src/cellTools/Control.mjs +1 -1
- package/src/connectionPoints/index.mjs +24 -9
- package/src/connectionStrategies/index.mjs +1 -1
- package/src/connectors/jumpover.mjs +1 -1
- package/src/dia/Cell.mjs +6 -2
- package/src/dia/CellView.mjs +47 -39
- package/src/dia/Element.mjs +79 -35
- package/src/dia/ElementView.mjs +9 -3
- package/src/dia/HighlighterView.mjs +32 -11
- package/src/dia/Paper.mjs +134 -22
- package/src/dia/PaperLayer.mjs +9 -2
- package/src/dia/attributes/text.mjs +12 -3
- package/src/dia/layers/GridLayer.mjs +5 -0
- package/src/dia/ports.mjs +152 -39
- package/src/env/index.mjs +1 -1
- package/src/g/rect.mjs +7 -0
- package/src/highlighters/stroke.mjs +1 -1
- package/src/linkAnchors/index.mjs +2 -2
- package/src/linkTools/Anchor.mjs +2 -2
- package/src/linkTools/Vertices.mjs +4 -6
- package/src/mvc/Dom/methods.mjs +2 -2
- package/src/util/util.mjs +1 -1
- package/src/util/utilHelpers.mjs +2 -0
- package/types/geometry.d.ts +2 -0
- package/types/joint.d.ts +81 -20
- package/src/V/annotation.mjs +0 -0
package/dist/vectorizer.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! JointJS v4.
|
|
1
|
+
/*! JointJS v4.2.0-alpha.0 (2025-06-16) - JavaScript diagramming library
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
This Source Code Form is subject to the terms of the Mozilla Public
|
|
@@ -8,14 +8,14 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
8
8
|
(function (global, factory) {
|
|
9
9
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
10
10
|
typeof define === 'function' && define.amd ? define(factory) :
|
|
11
|
-
(global = global || self, global.V = factory());
|
|
12
|
-
}(this, function () { 'use strict';
|
|
11
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.V = factory());
|
|
12
|
+
})(this, (function () { 'use strict';
|
|
13
13
|
|
|
14
14
|
// Declare shorthands to the most used math functions.
|
|
15
15
|
const {
|
|
16
|
-
round,
|
|
16
|
+
round: round$3,
|
|
17
17
|
floor,
|
|
18
|
-
PI
|
|
18
|
+
PI: PI$1
|
|
19
19
|
} = Math;
|
|
20
20
|
const scale = {
|
|
21
21
|
// Return the `value` from the `domain` interval scaled to the `range` interval.
|
|
@@ -29,15 +29,15 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
29
29
|
return angle % 360 + (angle < 0 ? 360 : 0);
|
|
30
30
|
};
|
|
31
31
|
const snapToGrid = function (value, gridSize) {
|
|
32
|
-
return gridSize * round(value / gridSize);
|
|
32
|
+
return gridSize * round$3(value / gridSize);
|
|
33
33
|
};
|
|
34
34
|
const toDeg = function (rad) {
|
|
35
|
-
return 180 * rad / PI % 360;
|
|
35
|
+
return 180 * rad / PI$1 % 360;
|
|
36
36
|
};
|
|
37
37
|
const toRad = function (deg, over360) {
|
|
38
38
|
over360 = over360 || false;
|
|
39
39
|
deg = over360 ? deg : deg % 360;
|
|
40
|
-
return deg * PI / 180;
|
|
40
|
+
return deg * PI$1 / 180;
|
|
41
41
|
};
|
|
42
42
|
|
|
43
43
|
// Return a random integer from the interval [min,max], inclusive.
|
|
@@ -56,10 +56,11 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
56
56
|
};
|
|
57
57
|
|
|
58
58
|
// @return the bearing (cardinal direction) of the line. For example N, W, or SE.
|
|
59
|
+
// @returns {String} One of the following bearings : NE, E, SE, S, SW, W, NW, N.
|
|
59
60
|
const {
|
|
60
|
-
cos,
|
|
61
|
-
sin,
|
|
62
|
-
atan2
|
|
61
|
+
cos: cos$2,
|
|
62
|
+
sin: sin$2,
|
|
63
|
+
atan2: atan2$1
|
|
63
64
|
} = Math;
|
|
64
65
|
const bearing = function (p, q) {
|
|
65
66
|
var lat1 = toRad(p.y);
|
|
@@ -67,9 +68,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
67
68
|
var lon1 = p.x;
|
|
68
69
|
var lon2 = q.x;
|
|
69
70
|
var dLon = toRad(lon2 - lon1);
|
|
70
|
-
var y = sin(dLon) * cos(lat2);
|
|
71
|
-
var x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon);
|
|
72
|
-
var brng = toDeg(atan2(y, x));
|
|
71
|
+
var y = sin$2(dLon) * cos$2(lat2);
|
|
72
|
+
var x = cos$2(lat1) * sin$2(lat2) - sin$2(lat1) * cos$2(lat2) * cos$2(dLon);
|
|
73
|
+
var brng = toDeg(atan2$1(y, x));
|
|
73
74
|
var bearings = ['NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N'];
|
|
74
75
|
var index = brng - 22.5;
|
|
75
76
|
if (index < 0) index += 360;
|
|
@@ -112,16 +113,16 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
112
113
|
* `Point(Point(10, 20))`
|
|
113
114
|
*/
|
|
114
115
|
const {
|
|
115
|
-
abs,
|
|
116
|
+
abs: abs$2,
|
|
116
117
|
cos: cos$1,
|
|
117
118
|
sin: sin$1,
|
|
118
|
-
sqrt,
|
|
119
|
-
min,
|
|
120
|
-
max,
|
|
121
|
-
atan2
|
|
122
|
-
round: round$
|
|
123
|
-
pow,
|
|
124
|
-
PI
|
|
119
|
+
sqrt: sqrt$2,
|
|
120
|
+
min: min$3,
|
|
121
|
+
max: max$3,
|
|
122
|
+
atan2,
|
|
123
|
+
round: round$2,
|
|
124
|
+
pow: pow$3,
|
|
125
|
+
PI
|
|
125
126
|
} = Math;
|
|
126
127
|
const Point = function (x, y) {
|
|
127
128
|
if (!(this instanceof Point)) {
|
|
@@ -145,8 +146,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
145
146
|
// @param {point} [optional] Origin.
|
|
146
147
|
Point.fromPolar = function (distance, angle, origin) {
|
|
147
148
|
origin = new Point(origin);
|
|
148
|
-
var x = abs(distance * cos$1(angle));
|
|
149
|
-
var y = abs(distance * sin$1(angle));
|
|
149
|
+
var x = abs$2(distance * cos$1(angle));
|
|
150
|
+
var y = abs$2(distance * sin$1(angle));
|
|
150
151
|
var deg = normalizeAngle(toDeg(angle));
|
|
151
152
|
if (deg < 90) {
|
|
152
153
|
y = -y;
|
|
@@ -187,8 +188,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
187
188
|
if (r.containsPoint(this)) {
|
|
188
189
|
return this;
|
|
189
190
|
}
|
|
190
|
-
this.x = min(max(this.x, r.x), r.x + r.width);
|
|
191
|
-
this.y = min(max(this.y, r.y), r.y + r.height);
|
|
191
|
+
this.x = min$3(max$3(this.x, r.x), r.x + r.width);
|
|
192
|
+
this.y = min$3(max$3(this.y, r.y), r.y + r.height);
|
|
192
193
|
return this;
|
|
193
194
|
},
|
|
194
195
|
// Compute the angle between vector from me to p1 and the vector from me to p2.
|
|
@@ -254,11 +255,11 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
254
255
|
return new Point((1 - t) * x + t * p.x, (1 - t) * y + t * p.y);
|
|
255
256
|
},
|
|
256
257
|
magnitude: function () {
|
|
257
|
-
return sqrt(this.x * this.x + this.y * this.y) || 0.01;
|
|
258
|
+
return sqrt$2(this.x * this.x + this.y * this.y) || 0.01;
|
|
258
259
|
},
|
|
259
260
|
// Returns a manhattan (taxi-cab) distance between me and point `p`.
|
|
260
261
|
manhattanDistance: function (p) {
|
|
261
|
-
return abs(p.x - this.x) + abs(p.y - this.y);
|
|
262
|
+
return abs$2(p.x - this.x) + abs$2(p.y - this.y);
|
|
262
263
|
},
|
|
263
264
|
// Move point on line starting from ref ending at me by
|
|
264
265
|
// distance distance.
|
|
@@ -315,12 +316,12 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
315
316
|
f = 1000;
|
|
316
317
|
break;
|
|
317
318
|
default:
|
|
318
|
-
f = pow(10, precision);
|
|
319
|
+
f = pow$3(10, precision);
|
|
319
320
|
break;
|
|
320
321
|
}
|
|
321
322
|
}
|
|
322
|
-
this.x = round$
|
|
323
|
-
this.y = round$
|
|
323
|
+
this.x = round$2(this.x * f) / f;
|
|
324
|
+
this.y = round$2(this.y * f) / f;
|
|
324
325
|
return this;
|
|
325
326
|
},
|
|
326
327
|
// Scale point with origin.
|
|
@@ -347,13 +348,13 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
347
348
|
// Invert the y-axis.
|
|
348
349
|
var y = -(p.y - this.y);
|
|
349
350
|
var x = p.x - this.x;
|
|
350
|
-
var rad = atan2
|
|
351
|
+
var rad = atan2(y, x); // defined for all 0 corner cases
|
|
351
352
|
|
|
352
353
|
// Correction for III. and IV. quadrant.
|
|
353
354
|
if (rad < 0) {
|
|
354
|
-
rad = 2 * PI
|
|
355
|
+
rad = 2 * PI + rad;
|
|
355
356
|
}
|
|
356
|
-
return 180 * rad / PI
|
|
357
|
+
return 180 * rad / PI;
|
|
357
358
|
},
|
|
358
359
|
toJSON: function () {
|
|
359
360
|
return {
|
|
@@ -367,7 +368,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
367
368
|
o = o && new Point(o) || new Point(0, 0);
|
|
368
369
|
var x = this.x;
|
|
369
370
|
var y = this.y;
|
|
370
|
-
this.x = sqrt((x - o.x) * (x - o.x) + (y - o.y) * (y - o.y)); // r
|
|
371
|
+
this.x = sqrt$2((x - o.x) * (x - o.x) + (y - o.y) * (y - o.y)); // r
|
|
371
372
|
this.y = toRad(o.theta(new Point(x, y)));
|
|
372
373
|
return this;
|
|
373
374
|
},
|
|
@@ -399,8 +400,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
399
400
|
const point = Point;
|
|
400
401
|
|
|
401
402
|
const {
|
|
402
|
-
max: max$
|
|
403
|
-
min: min$
|
|
403
|
+
max: max$2,
|
|
404
|
+
min: min$2
|
|
404
405
|
} = Math;
|
|
405
406
|
const Line = function (p1, p2) {
|
|
406
407
|
if (!(this instanceof Line)) {
|
|
@@ -420,10 +421,10 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
420
421
|
return this.start.angleBetween(this.end, horizontalPoint);
|
|
421
422
|
},
|
|
422
423
|
bbox: function () {
|
|
423
|
-
var left = min$
|
|
424
|
-
var top = min$
|
|
425
|
-
var right = max$
|
|
426
|
-
var bottom = max$
|
|
424
|
+
var left = min$2(this.start.x, this.end.x);
|
|
425
|
+
var top = min$2(this.start.y, this.end.y);
|
|
426
|
+
var right = max$2(this.start.x, this.end.x);
|
|
427
|
+
var bottom = max$2(this.start.y, this.end.y);
|
|
427
428
|
return new Rect(left, top, right - left, bottom - top);
|
|
428
429
|
},
|
|
429
430
|
// @return the bearing (cardinal direction) of the line. For example N, W, or SE.
|
|
@@ -444,7 +445,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
444
445
|
// @return {number} the normalized length of the closest point on the line to point `p`
|
|
445
446
|
closestPointNormalizedLength: function (p) {
|
|
446
447
|
var product = this.vector().dot(new Line(this.start, p).vector());
|
|
447
|
-
var cpNormalizedLength = min$
|
|
448
|
+
var cpNormalizedLength = min$2(1, max$2(0, product / this.squaredLength()));
|
|
448
449
|
|
|
449
450
|
// cpNormalizedLength returns `NaN` if this line has zero length
|
|
450
451
|
// we can work with that - if `NaN`, return 0
|
|
@@ -650,8 +651,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
650
651
|
|
|
651
652
|
const {
|
|
652
653
|
sqrt: sqrt$1,
|
|
653
|
-
round: round$
|
|
654
|
-
pow: pow$
|
|
654
|
+
round: round$1,
|
|
655
|
+
pow: pow$2
|
|
655
656
|
} = Math;
|
|
656
657
|
const Ellipse = function (c, a, b) {
|
|
657
658
|
if (!(this instanceof Ellipse)) {
|
|
@@ -799,14 +800,14 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
799
800
|
f = 1000;
|
|
800
801
|
break;
|
|
801
802
|
default:
|
|
802
|
-
f = pow$
|
|
803
|
+
f = pow$2(10, precision);
|
|
803
804
|
break;
|
|
804
805
|
}
|
|
805
806
|
}
|
|
806
|
-
this.x = round$
|
|
807
|
-
this.y = round$
|
|
808
|
-
this.a = round$
|
|
809
|
-
this.b = round$
|
|
807
|
+
this.x = round$1(this.x * f) / f;
|
|
808
|
+
this.y = round$1(this.y * f) / f;
|
|
809
|
+
this.a = round$1(this.a * f) / f;
|
|
810
|
+
this.b = round$1(this.b * f) / f;
|
|
810
811
|
return this;
|
|
811
812
|
},
|
|
812
813
|
/** Compute angle between tangent and x axis
|
|
@@ -844,12 +845,12 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
844
845
|
|
|
845
846
|
const {
|
|
846
847
|
abs: abs$1,
|
|
847
|
-
cos
|
|
848
|
-
sin
|
|
849
|
-
min: min$
|
|
850
|
-
max: max$
|
|
851
|
-
round
|
|
852
|
-
pow: pow$
|
|
848
|
+
cos,
|
|
849
|
+
sin,
|
|
850
|
+
min: min$1,
|
|
851
|
+
max: max$1,
|
|
852
|
+
round,
|
|
853
|
+
pow: pow$1
|
|
853
854
|
} = Math;
|
|
854
855
|
const Rect = function (x, y, w, h) {
|
|
855
856
|
if (!(this instanceof Rect)) {
|
|
@@ -870,14 +871,14 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
870
871
|
e = new Ellipse(e);
|
|
871
872
|
return new Rect(e.x - e.a, e.y - e.b, 2 * e.a, 2 * e.b);
|
|
872
873
|
};
|
|
873
|
-
Rect.fromPointUnion = function () {
|
|
874
|
-
if (
|
|
874
|
+
Rect.fromPointUnion = function (...points) {
|
|
875
|
+
if (points.length === 0) return null;
|
|
875
876
|
const p = new Point();
|
|
876
877
|
let minX, minY, maxX, maxY;
|
|
877
878
|
minX = minY = Infinity;
|
|
878
879
|
maxX = maxY = -Infinity;
|
|
879
|
-
for (let i = 0; i <
|
|
880
|
-
p.update(
|
|
880
|
+
for (let i = 0; i < points.length; i++) {
|
|
881
|
+
p.update(points[i]);
|
|
881
882
|
const x = p.x;
|
|
882
883
|
const y = p.y;
|
|
883
884
|
if (x < minX) minX = x;
|
|
@@ -887,14 +888,14 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
887
888
|
}
|
|
888
889
|
return new Rect(minX, minY, maxX - minX, maxY - minY);
|
|
889
890
|
};
|
|
890
|
-
Rect.fromRectUnion = function () {
|
|
891
|
-
if (
|
|
891
|
+
Rect.fromRectUnion = function (...rects) {
|
|
892
|
+
if (rects.length === 0) return null;
|
|
892
893
|
const r = new Rect();
|
|
893
894
|
let minX, minY, maxX, maxY;
|
|
894
895
|
minX = minY = Infinity;
|
|
895
896
|
maxX = maxY = -Infinity;
|
|
896
|
-
for (let i = 0; i <
|
|
897
|
-
r.update(
|
|
897
|
+
for (let i = 0; i < rects.length; i++) {
|
|
898
|
+
r.update(rects[i]);
|
|
898
899
|
const x = r.x;
|
|
899
900
|
const y = r.y;
|
|
900
901
|
const mX = x + r.width;
|
|
@@ -920,8 +921,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
920
921
|
height
|
|
921
922
|
} = this;
|
|
922
923
|
const theta = toRad(angle);
|
|
923
|
-
const st = abs$1(sin
|
|
924
|
-
const ct = abs$1(cos
|
|
924
|
+
const st = abs$1(sin(theta));
|
|
925
|
+
const ct = abs$1(cos(theta));
|
|
925
926
|
const w = width * ct + height * st;
|
|
926
927
|
const h = width * st + height * ct;
|
|
927
928
|
this.x += (width - w) / 2;
|
|
@@ -1022,9 +1023,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
1022
1023
|
|
|
1023
1024
|
// No intersection found
|
|
1024
1025
|
if (rCorner.x <= myOrigin.x || rCorner.y <= myOrigin.y || rOrigin.x >= myCorner.x || rOrigin.y >= myCorner.y) return null;
|
|
1025
|
-
var x = max$
|
|
1026
|
-
var y = max$
|
|
1027
|
-
return new Rect(x, y, min$
|
|
1026
|
+
var x = max$1(myOrigin.x, rOrigin.x);
|
|
1027
|
+
var y = max$1(myOrigin.y, rOrigin.y);
|
|
1028
|
+
return new Rect(x, y, min$1(myCorner.x, rCorner.x) - x, min$1(myCorner.y, rCorner.y) - y);
|
|
1028
1029
|
},
|
|
1029
1030
|
intersectionWithLine: function (line) {
|
|
1030
1031
|
var r = this;
|
|
@@ -1115,13 +1116,13 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
1115
1116
|
sy4 = (this.y + this.height - oy) / (p4.y - oy);
|
|
1116
1117
|
}
|
|
1117
1118
|
return {
|
|
1118
|
-
sx: min$
|
|
1119
|
-
sy: min$
|
|
1119
|
+
sx: min$1(sx1, sx2, sx3, sx4),
|
|
1120
|
+
sy: min$1(sy1, sy2, sy3, sy4)
|
|
1120
1121
|
};
|
|
1121
1122
|
},
|
|
1122
1123
|
maxRectUniformScaleToFit: function (rect, origin) {
|
|
1123
1124
|
var scale = this.maxRectScaleToFit(rect, origin);
|
|
1124
|
-
return min$
|
|
1125
|
+
return min$1(scale.sx, scale.sy);
|
|
1125
1126
|
},
|
|
1126
1127
|
// Move and expand me.
|
|
1127
1128
|
// @param r {rectangle} representing deltas
|
|
@@ -1132,6 +1133,12 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
1132
1133
|
this.height += r.height || 0;
|
|
1133
1134
|
return this;
|
|
1134
1135
|
},
|
|
1136
|
+
moveAroundPoint: function (origin, angle) {
|
|
1137
|
+
const newCenter = this.center().rotate(origin, angle);
|
|
1138
|
+
this.x = newCenter.x - this.width / 2;
|
|
1139
|
+
this.y = newCenter.y - this.height / 2;
|
|
1140
|
+
return this;
|
|
1141
|
+
},
|
|
1135
1142
|
// Normalize the rectangle; i.e., make it so that it has a non-negative width and height.
|
|
1136
1143
|
// If width < 0 the function swaps the left and right corners,
|
|
1137
1144
|
// and it swaps the top and bottom corners if height < 0
|
|
@@ -1203,14 +1210,14 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
1203
1210
|
f = 1000;
|
|
1204
1211
|
break;
|
|
1205
1212
|
default:
|
|
1206
|
-
f = pow$
|
|
1213
|
+
f = pow$1(10, precision);
|
|
1207
1214
|
break;
|
|
1208
1215
|
}
|
|
1209
1216
|
}
|
|
1210
|
-
this.x = round
|
|
1211
|
-
this.y = round
|
|
1212
|
-
this.width = round
|
|
1213
|
-
this.height = round
|
|
1217
|
+
this.x = round(this.x * f) / f;
|
|
1218
|
+
this.y = round(this.y * f) / f;
|
|
1219
|
+
this.width = round(this.width * f) / f;
|
|
1220
|
+
this.height = round(this.height * f) / f;
|
|
1214
1221
|
return this;
|
|
1215
1222
|
},
|
|
1216
1223
|
// Scale rectangle with origin.
|
|
@@ -1800,8 +1807,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
1800
1807
|
}
|
|
1801
1808
|
return this;
|
|
1802
1809
|
},
|
|
1803
|
-
simplify: function () {
|
|
1804
|
-
let opt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1810
|
+
simplify: function (opt = {}) {
|
|
1805
1811
|
const points = this.points;
|
|
1806
1812
|
if (points.length < 3) return this; // we need at least 3 points
|
|
1807
1813
|
|
|
@@ -1948,11 +1954,11 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
1948
1954
|
});
|
|
1949
1955
|
|
|
1950
1956
|
const {
|
|
1951
|
-
abs
|
|
1952
|
-
sqrt
|
|
1953
|
-
min
|
|
1954
|
-
max
|
|
1955
|
-
pow
|
|
1957
|
+
abs,
|
|
1958
|
+
sqrt,
|
|
1959
|
+
min,
|
|
1960
|
+
max,
|
|
1961
|
+
pow
|
|
1956
1962
|
} = Math;
|
|
1957
1963
|
const Curve = function (p1, p2, p3, p4) {
|
|
1958
1964
|
if (!(this instanceof Curve)) {
|
|
@@ -2101,9 +2107,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
2101
2107
|
a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;
|
|
2102
2108
|
c = 3 * y1 - 3 * y0;
|
|
2103
2109
|
}
|
|
2104
|
-
if (abs
|
|
2110
|
+
if (abs(a) < 1e-12) {
|
|
2105
2111
|
// Numerical robustness
|
|
2106
|
-
if (abs
|
|
2112
|
+
if (abs(b) < 1e-12) {
|
|
2107
2113
|
// Numerical robustness
|
|
2108
2114
|
continue;
|
|
2109
2115
|
}
|
|
@@ -2112,7 +2118,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
2112
2118
|
continue;
|
|
2113
2119
|
}
|
|
2114
2120
|
b2ac = b * b - 4 * c * a;
|
|
2115
|
-
sqrtb2ac = sqrt
|
|
2121
|
+
sqrtb2ac = sqrt(b2ac);
|
|
2116
2122
|
if (b2ac < 0) continue;
|
|
2117
2123
|
t1 = (-b + sqrtb2ac) / (2 * a);
|
|
2118
2124
|
if (0 < t1 && t1 < 1) tvalues.push(t1);
|
|
@@ -2153,10 +2159,10 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
2153
2159
|
bounds[0].length = jlen + 2;
|
|
2154
2160
|
bounds[1].length = jlen + 2;
|
|
2155
2161
|
points.length = jlen + 2;
|
|
2156
|
-
var left = min
|
|
2157
|
-
var top = min
|
|
2158
|
-
var right = max
|
|
2159
|
-
var bottom = max
|
|
2162
|
+
var left = min.apply(null, bounds[0]);
|
|
2163
|
+
var top = min.apply(null, bounds[1]);
|
|
2164
|
+
var right = max.apply(null, bounds[0]);
|
|
2165
|
+
var bottom = max.apply(null, bounds[1]);
|
|
2160
2166
|
return new Rect(left, top, right - left, bottom - top);
|
|
2161
2167
|
},
|
|
2162
2168
|
clone: function () {
|
|
@@ -2230,7 +2236,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
2230
2236
|
minSumDist = sumDist;
|
|
2231
2237
|
}
|
|
2232
2238
|
}
|
|
2233
|
-
var precisionRatio = pow
|
|
2239
|
+
var precisionRatio = pow(10, -precision);
|
|
2234
2240
|
|
|
2235
2241
|
// recursively divide investigated subdivision:
|
|
2236
2242
|
// until distance between baselinePoint and closest path endpoint is within 10^(-precision)
|
|
@@ -2241,8 +2247,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
2241
2247
|
// - note that this function is not monotonic = it doesn't converge stably but has "teeth"
|
|
2242
2248
|
// - the function decreases while one of the endpoints is fixed but "jumps" whenever we switch
|
|
2243
2249
|
// - this criterion works well for points lying far away from the curve
|
|
2244
|
-
var startPrecisionRatio = distFromStart ? abs
|
|
2245
|
-
var endPrecisionRatio = distFromEnd ? abs
|
|
2250
|
+
var startPrecisionRatio = distFromStart ? abs(distFromStart - distFromEnd) / distFromStart : 0;
|
|
2251
|
+
var endPrecisionRatio = distFromEnd ? abs(distFromStart - distFromEnd) / distFromEnd : 0;
|
|
2246
2252
|
var hasRequiredPrecision = startPrecisionRatio < precisionRatio || endPrecisionRatio < precisionRatio;
|
|
2247
2253
|
|
|
2248
2254
|
// check if we have reached at least one required minimal distance
|
|
@@ -2409,7 +2415,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
2409
2415
|
var isPoint = !this.isDifferentiable();
|
|
2410
2416
|
if (isPoint) return subdivisions;
|
|
2411
2417
|
var previousLength = this.endpointDistance();
|
|
2412
|
-
var precisionRatio = pow
|
|
2418
|
+
var precisionRatio = pow(10, -precision);
|
|
2413
2419
|
|
|
2414
2420
|
// special case #2: sine-like curves may have the same observed length in iteration 0 and 1 - skip iteration 1
|
|
2415
2421
|
// - not a problem for further iterations because cubic curves cannot have more than two local extrema
|
|
@@ -2641,7 +2647,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
2641
2647
|
// e.g. at precision 1, the length may be underestimated by up to 10% and cause this function to return 1
|
|
2642
2648
|
|
|
2643
2649
|
var curveLength = this.length(localOpt);
|
|
2644
|
-
var precisionRatio = pow
|
|
2650
|
+
var precisionRatio = pow(10, -precision);
|
|
2645
2651
|
|
|
2646
2652
|
// recursively divide investigated subdivision:
|
|
2647
2653
|
// until distance between baselinePoint and closest path endpoint is within 10^(-precision)
|
|
@@ -2776,6 +2782,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
2776
2782
|
}
|
|
2777
2783
|
|
|
2778
2784
|
// Accepts path data string, array of segments, array of Curves and/or Lines, or a Polyline.
|
|
2785
|
+
// Path created is not guaranteed to be a valid (serializable) path (might not start with an M).
|
|
2779
2786
|
const Path = function (arg) {
|
|
2780
2787
|
if (!(this instanceof Path)) {
|
|
2781
2788
|
return new Path(arg);
|
|
@@ -5080,8 +5087,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
5080
5087
|
}
|
|
5081
5088
|
});
|
|
5082
5089
|
}
|
|
5083
|
-
function _polylineWithLine(polyline, line) {
|
|
5084
|
-
let opt = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
5090
|
+
function _polylineWithLine(polyline, line, opt = {}) {
|
|
5085
5091
|
const {
|
|
5086
5092
|
interior = false
|
|
5087
5093
|
} = opt;
|
|
@@ -5114,8 +5120,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
5114
5120
|
}
|
|
5115
5121
|
return false;
|
|
5116
5122
|
}
|
|
5117
|
-
function _polylineWithEllipse(polyline, ellipse) {
|
|
5118
|
-
let opt = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
5123
|
+
function _polylineWithEllipse(polyline, ellipse, opt = {}) {
|
|
5119
5124
|
const {
|
|
5120
5125
|
start,
|
|
5121
5126
|
end,
|
|
@@ -5168,8 +5173,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
5168
5173
|
}
|
|
5169
5174
|
});
|
|
5170
5175
|
}
|
|
5171
|
-
function _polylineWithPolyline(polyline1, polyline2) {
|
|
5172
|
-
let opt = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
5176
|
+
function _polylineWithPolyline(polyline1, polyline2, opt = {}) {
|
|
5173
5177
|
const {
|
|
5174
5178
|
interior = false
|
|
5175
5179
|
} = opt;
|
|
@@ -5261,80 +5265,336 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
5261
5265
|
return m[0][0] * m[1][1] * m[2][2] - m[0][0] * m[1][2] * m[2][1] - m[0][1] * m[1][0] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + m[0][2] * m[1][0] * m[2][1] - m[0][2] * m[1][1] * m[2][0];
|
|
5262
5266
|
}
|
|
5263
5267
|
|
|
5264
|
-
var _intersection =
|
|
5268
|
+
var _intersection = {
|
|
5269
|
+
__proto__: null,
|
|
5270
|
+
ellipseWithEllipse: ellipseWithEllipse,
|
|
5271
|
+
ellipseWithLine: ellipseWithLine,
|
|
5265
5272
|
exists: exists,
|
|
5266
5273
|
lineWithLine: lineWithLine,
|
|
5267
|
-
ellipseWithLine: ellipseWithLine,
|
|
5268
|
-
ellipseWithEllipse: ellipseWithEllipse,
|
|
5269
|
-
rectWithLine: rectWithLine,
|
|
5270
|
-
rectWithEllipse: rectWithEllipse,
|
|
5271
|
-
rectWithRect: rectWithRect,
|
|
5272
|
-
polylineWithLine: polylineWithLine,
|
|
5273
|
-
polylineWithEllipse: polylineWithEllipse,
|
|
5274
|
-
polylineWithRect: polylineWithRect,
|
|
5275
|
-
polylineWithPolyline: polylineWithPolyline,
|
|
5276
|
-
polygonWithLine: polygonWithLine,
|
|
5277
|
-
polygonWithEllipse: polygonWithEllipse,
|
|
5278
|
-
polygonWithRect: polygonWithRect,
|
|
5279
|
-
polygonWithPolyline: polygonWithPolyline,
|
|
5280
|
-
polygonWithPolygon: polygonWithPolygon,
|
|
5281
|
-
pathWithLine: pathWithLine,
|
|
5282
5274
|
pathWithEllipse: pathWithEllipse,
|
|
5283
|
-
|
|
5284
|
-
|
|
5275
|
+
pathWithLine: pathWithLine,
|
|
5276
|
+
pathWithPath: pathWithPath,
|
|
5285
5277
|
pathWithPolygon: pathWithPolygon,
|
|
5286
|
-
|
|
5287
|
-
|
|
5278
|
+
pathWithPolyline: pathWithPolyline,
|
|
5279
|
+
pathWithRect: pathWithRect,
|
|
5280
|
+
polygonWithEllipse: polygonWithEllipse,
|
|
5281
|
+
polygonWithLine: polygonWithLine,
|
|
5282
|
+
polygonWithPolygon: polygonWithPolygon,
|
|
5283
|
+
polygonWithPolyline: polygonWithPolyline,
|
|
5284
|
+
polygonWithRect: polygonWithRect,
|
|
5285
|
+
polylineWithEllipse: polylineWithEllipse,
|
|
5286
|
+
polylineWithLine: polylineWithLine,
|
|
5287
|
+
polylineWithPolyline: polylineWithPolyline,
|
|
5288
|
+
polylineWithRect: polylineWithRect,
|
|
5289
|
+
rectWithEllipse: rectWithEllipse,
|
|
5290
|
+
rectWithLine: rectWithLine,
|
|
5291
|
+
rectWithRect: rectWithRect
|
|
5292
|
+
};
|
|
5288
5293
|
|
|
5289
5294
|
// Geometry library.
|
|
5295
|
+
// -----------------
|
|
5296
|
+
|
|
5290
5297
|
const intersection = _intersection;
|
|
5291
5298
|
|
|
5292
|
-
var g =
|
|
5293
|
-
|
|
5294
|
-
scale: scale,
|
|
5295
|
-
normalizeAngle: normalizeAngle,
|
|
5296
|
-
snapToGrid: snapToGrid,
|
|
5297
|
-
toDeg: toDeg,
|
|
5298
|
-
toRad: toRad,
|
|
5299
|
-
random: random,
|
|
5300
|
-
bezier: bezier,
|
|
5299
|
+
var g = {
|
|
5300
|
+
__proto__: null,
|
|
5301
5301
|
Curve: Curve,
|
|
5302
5302
|
Ellipse: Ellipse,
|
|
5303
|
-
ellipse: ellipse,
|
|
5304
5303
|
Line: Line,
|
|
5305
|
-
line: line,
|
|
5306
5304
|
Path: Path,
|
|
5307
5305
|
Point: Point,
|
|
5308
|
-
point: point,
|
|
5309
|
-
Polyline: Polyline,
|
|
5310
5306
|
Polygon: Polygon,
|
|
5307
|
+
Polyline: Polyline,
|
|
5311
5308
|
Rect: Rect,
|
|
5309
|
+
bezier: bezier,
|
|
5310
|
+
ellipse: ellipse,
|
|
5311
|
+
intersection: intersection,
|
|
5312
|
+
line: line,
|
|
5313
|
+
normalizeAngle: normalizeAngle,
|
|
5314
|
+
point: point,
|
|
5315
|
+
random: random,
|
|
5312
5316
|
rect: rect,
|
|
5317
|
+
scale: scale,
|
|
5318
|
+
snapToGrid: snapToGrid,
|
|
5319
|
+
toDeg: toDeg,
|
|
5320
|
+
toRad: toRad,
|
|
5313
5321
|
types: types
|
|
5314
|
-
}
|
|
5322
|
+
};
|
|
5323
|
+
|
|
5324
|
+
const svg = 'http://www.w3.org/2000/svg';
|
|
5325
|
+
const xmlns = 'http://www.w3.org/2000/xmlns/';
|
|
5326
|
+
const xml = 'http://www.w3.org/XML/1998/namespace';
|
|
5327
|
+
const xlink = 'http://www.w3.org/1999/xlink';
|
|
5328
|
+
const xhtml = 'http://www.w3.org/1999/xhtml';
|
|
5329
|
+
|
|
5330
|
+
var ns = {
|
|
5331
|
+
__proto__: null,
|
|
5332
|
+
svg: svg,
|
|
5333
|
+
xhtml: xhtml,
|
|
5334
|
+
xlink: xlink,
|
|
5335
|
+
xml: xml,
|
|
5336
|
+
xmlns: xmlns
|
|
5337
|
+
};
|
|
5338
|
+
|
|
5339
|
+
/**
|
|
5340
|
+
* @constant {boolean}
|
|
5341
|
+
* @description Indicates the environment supports SVG.
|
|
5342
|
+
*/
|
|
5343
|
+
const isSVGSupported = typeof window === 'object' && !!window.SVGAngle;
|
|
5344
|
+
|
|
5345
|
+
/**
|
|
5346
|
+
* @constant {string}
|
|
5347
|
+
* @description The version of the SVG document.
|
|
5348
|
+
*/
|
|
5349
|
+
const SVG_VERSION = '1.1';
|
|
5350
|
+
|
|
5351
|
+
/**
|
|
5352
|
+
* @constant {SVGSVGElement}
|
|
5353
|
+
* @description The detached SVG document for various internal purposes.
|
|
5354
|
+
* e.g. SVGMatrix has no constructor, so the only way to create it is
|
|
5355
|
+
* to create an SVG document and then call `createSVGMatrix()`.
|
|
5356
|
+
*/
|
|
5357
|
+
const internalSVGDocument = isSVGSupported ? createSVGDocument() : null;
|
|
5358
|
+
|
|
5359
|
+
/**
|
|
5360
|
+
* @constant {SVGGElement}
|
|
5361
|
+
* @description The detached SVG group element for various internal purposes.
|
|
5362
|
+
*/
|
|
5363
|
+
const internalSVGGroup = isSVGSupported ? createSVGElement('g') : null;
|
|
5364
|
+
|
|
5365
|
+
/**
|
|
5366
|
+
* @returns {SVGSVGElement}
|
|
5367
|
+
* @description Creates an SVG document.
|
|
5368
|
+
*/
|
|
5369
|
+
function createSVGDocument() {
|
|
5370
|
+
const svg = createSVGElement('svg');
|
|
5371
|
+
svg.setAttributeNS(xmlns, 'xmlns:xlink', xlink);
|
|
5372
|
+
svg.setAttribute('version', SVG_VERSION);
|
|
5373
|
+
return svg;
|
|
5374
|
+
}
|
|
5375
|
+
|
|
5376
|
+
/**
|
|
5377
|
+
* @param {string} name
|
|
5378
|
+
* @returns {SVGElement}
|
|
5379
|
+
* @description Creates an SVG element with the given name.
|
|
5380
|
+
*/
|
|
5381
|
+
function createSVGElement(name) {
|
|
5382
|
+
return document.createElementNS(svg, name);
|
|
5383
|
+
}
|
|
5384
|
+
|
|
5385
|
+
/**
|
|
5386
|
+
* @param {SVGElement} node1
|
|
5387
|
+
* @param {SVGElement} node2
|
|
5388
|
+
* @returns {SVGElement|null}
|
|
5389
|
+
* @description Finds the common ancestor node of two nodes.
|
|
5390
|
+
*/
|
|
5391
|
+
function getCommonAncestor(node1, node2) {
|
|
5392
|
+
// Find the common ancestor node of two nodes.
|
|
5393
|
+
let parent = node1;
|
|
5394
|
+
do {
|
|
5395
|
+
if (parent.contains(node2)) return parent;
|
|
5396
|
+
parent = parent.parentNode;
|
|
5397
|
+
} while (parent);
|
|
5398
|
+
return null;
|
|
5399
|
+
}
|
|
5400
|
+
|
|
5401
|
+
/**
|
|
5402
|
+
* @returns {SVGMatrix}
|
|
5403
|
+
* @description Creates an identity matrix.
|
|
5404
|
+
*/
|
|
5405
|
+
function createIdentityMatrix() {
|
|
5406
|
+
return internalSVGDocument.createSVGMatrix();
|
|
5407
|
+
}
|
|
5408
|
+
|
|
5409
|
+
/**
|
|
5410
|
+
* @param {Partial<SVGMatrix>} matrixInit
|
|
5411
|
+
* @returns {SVGMatrix}
|
|
5412
|
+
* @description Creates a new SVGMatrix object.
|
|
5413
|
+
* If no matrix is provided, it returns the identity matrix.
|
|
5414
|
+
* If a matrix like object is provided, it sets the matrix values.
|
|
5415
|
+
*/
|
|
5416
|
+
function createMatrix(matrixInit = {}) {
|
|
5417
|
+
const matrix = internalSVGDocument.createSVGMatrix();
|
|
5418
|
+
if (!matrixInit) return matrix;
|
|
5419
|
+
if ('a' in matrixInit) matrix.a = matrixInit.a;
|
|
5420
|
+
if ('b' in matrixInit) matrix.b = matrixInit.b;
|
|
5421
|
+
if ('c' in matrixInit) matrix.c = matrixInit.c;
|
|
5422
|
+
if ('d' in matrixInit) matrix.d = matrixInit.d;
|
|
5423
|
+
if ('e' in matrixInit) matrix.e = matrixInit.e;
|
|
5424
|
+
if ('f' in matrixInit) matrix.f = matrixInit.f;
|
|
5425
|
+
return matrix;
|
|
5426
|
+
}
|
|
5427
|
+
|
|
5428
|
+
/**
|
|
5429
|
+
* @returns {SVGTransform}
|
|
5430
|
+
* @description Creates a new SVGTransform object.
|
|
5431
|
+
*/
|
|
5432
|
+
function createSVGTransform() {
|
|
5433
|
+
return internalSVGDocument.createSVGTransform();
|
|
5434
|
+
}
|
|
5435
|
+
|
|
5436
|
+
/**
|
|
5437
|
+
* @param {SVGElement} node
|
|
5438
|
+
* @returns {SVGMatrix|null}
|
|
5439
|
+
* @description Returns the transformation matrix of the given node.
|
|
5440
|
+
* If the node has no transformation, it returns null.
|
|
5441
|
+
*/
|
|
5442
|
+
function getNodeMatrix(node) {
|
|
5443
|
+
const consolidatedTransformation = node.transform.baseVal.consolidate();
|
|
5444
|
+
return consolidatedTransformation ? consolidatedTransformation.matrix : null;
|
|
5445
|
+
}
|
|
5446
|
+
|
|
5447
|
+
/**
|
|
5448
|
+
* @param {string} transformString
|
|
5449
|
+
* @returns {SVGMatrix}
|
|
5450
|
+
* @description Creates a matrix from the given transform string.
|
|
5451
|
+
*/
|
|
5452
|
+
function createMatrixFromTransformString(transformString) {
|
|
5453
|
+
internalSVGGroup.setAttribute('transform', transformString);
|
|
5454
|
+
return getNodeMatrix(internalSVGGroup);
|
|
5455
|
+
}
|
|
5456
|
+
|
|
5457
|
+
/**
|
|
5458
|
+
* @param {SVGElement} node
|
|
5459
|
+
* @param {Partial<SVGMatrix>} matrixInit
|
|
5460
|
+
* @param {boolean} override
|
|
5461
|
+
* @description Sets the transformation matrix of the given node.
|
|
5462
|
+
* We don't use `node.transform.baseVal` here (@see `transformNode`)
|
|
5463
|
+
* for the following reasons:
|
|
5464
|
+
* - Performance: while Chrome performs slightly better, Firefox
|
|
5465
|
+
* and Safari are significantly slower
|
|
5466
|
+
* https://www.measurethat.net/Benchmarks/Show/34447/1/overriding-svg-transform-attribute
|
|
5467
|
+
* - Limited support: JSDOM does not support `node.transform.baseVal`
|
|
5468
|
+
*/
|
|
5469
|
+
function replaceTransformNode(node, matrixInit) {
|
|
5470
|
+
node.setAttribute('transform', matrixToTransformString(matrixInit));
|
|
5471
|
+
}
|
|
5472
|
+
|
|
5473
|
+
/**
|
|
5474
|
+
* @param {SVGElement} node
|
|
5475
|
+
* @param {Partial<SVGMatrix>} matrixInit
|
|
5476
|
+
* @description Applies a transformation matrix to the given node.
|
|
5477
|
+
* If the node already has a transformation, it appends the new transformation.
|
|
5478
|
+
* If the node has no transformation, it creates a new one.
|
|
5479
|
+
*/
|
|
5480
|
+
function transformNode(node, matrixInit) {
|
|
5481
|
+
const transform = createSVGTransform();
|
|
5482
|
+
const matrix = isSVGMatrix(matrixInit) ? matrixInit : createMatrix(matrixInit);
|
|
5483
|
+
transform.setMatrix(matrix);
|
|
5484
|
+
node.transform.baseVal.appendItem(transform);
|
|
5485
|
+
}
|
|
5486
|
+
const MATRIX_TYPE = '[object SVGMatrix]';
|
|
5487
|
+
|
|
5488
|
+
/**
|
|
5489
|
+
* @param {any} obj
|
|
5490
|
+
* @returns {boolean}
|
|
5491
|
+
* @description Checks if the given object is an SVGMatrix.
|
|
5492
|
+
*/
|
|
5493
|
+
function isSVGMatrix(obj) {
|
|
5494
|
+
return Object.prototype.toString.call(obj) === MATRIX_TYPE;
|
|
5495
|
+
}
|
|
5496
|
+
|
|
5497
|
+
/**
|
|
5498
|
+
* @param {Partial<SVGMatrix>} matrixInit
|
|
5499
|
+
* @returns {string}
|
|
5500
|
+
* @description Converts a matrix to a transform string.
|
|
5501
|
+
* If no matrix is provided, it returns the identity matrix string.
|
|
5502
|
+
*/
|
|
5503
|
+
function matrixToTransformString(matrixInit = {}) {
|
|
5504
|
+
const {
|
|
5505
|
+
a = 1,
|
|
5506
|
+
b = 0,
|
|
5507
|
+
c = 0,
|
|
5508
|
+
d = 1,
|
|
5509
|
+
e = 0,
|
|
5510
|
+
f = 0
|
|
5511
|
+
} = matrixInit;
|
|
5512
|
+
return `matrix(${a},${b},${c},${d},${e},${f})`;
|
|
5513
|
+
}
|
|
5514
|
+
|
|
5515
|
+
/**
|
|
5516
|
+
*
|
|
5517
|
+
* @param {SVGElement} a
|
|
5518
|
+
* @param {SVGElement} b
|
|
5519
|
+
* @returns {SVGMatrix|null}
|
|
5520
|
+
* @description Finds the transformation matrix from `a` to `b`.
|
|
5521
|
+
* It requires that both elements to be visible (in the render tree)
|
|
5522
|
+
* in order to calculate the correct transformation matrix.
|
|
5523
|
+
*/
|
|
5524
|
+
function getRelativeTransformation(a, b) {
|
|
5525
|
+
// Different SVG elements, no transformation possible
|
|
5526
|
+
// Note: SVGSVGElement has no `ownerSVGElement`
|
|
5527
|
+
if ((a.ownerSVGElement || a) !== (b.ownerSVGElement || b)) return null;
|
|
5528
|
+
// Get the transformation matrix from `a` to `b`.
|
|
5529
|
+
const am = b.getScreenCTM();
|
|
5530
|
+
if (!am) return null;
|
|
5531
|
+
const bm = a.getScreenCTM();
|
|
5532
|
+
if (!bm) return null;
|
|
5533
|
+
return am.inverse().multiply(bm);
|
|
5534
|
+
}
|
|
5535
|
+
|
|
5536
|
+
/**
|
|
5537
|
+
* @param {SVGElement} a
|
|
5538
|
+
* @param {SVGElement} b
|
|
5539
|
+
* @returns {SVGMatrix|null}
|
|
5540
|
+
* @description Finds the transformation matrix from `a` to `b`.
|
|
5541
|
+
* A safe way to calculate the transformation matrix between two elements.
|
|
5542
|
+
* It does not require the elements to be visible (in the render tree).
|
|
5543
|
+
*/
|
|
5544
|
+
function getRelativeTransformationSafe(a, b) {
|
|
5545
|
+
if (a === b) {
|
|
5546
|
+
// No transformation needed
|
|
5547
|
+
return createIdentityMatrix();
|
|
5548
|
+
}
|
|
5549
|
+
const position = a.compareDocumentPosition(b);
|
|
5550
|
+
if (position & Node.DOCUMENT_POSITION_CONTAINED_BY) {
|
|
5551
|
+
// `b` is a descendant of `a`
|
|
5552
|
+
return getLinealTransformation(a, b).inverse();
|
|
5553
|
+
} else if (position & Node.DOCUMENT_POSITION_CONTAINS) {
|
|
5554
|
+
// `a` is a descendant of `b`
|
|
5555
|
+
return getLinealTransformation(b, a);
|
|
5556
|
+
}
|
|
5557
|
+
const c = getCommonAncestor(a, b);
|
|
5558
|
+
if (!c) {
|
|
5559
|
+
// No common ancestor
|
|
5560
|
+
return null;
|
|
5561
|
+
}
|
|
5562
|
+
const mca = getLinealTransformation(c, a);
|
|
5563
|
+
const mcb = getLinealTransformation(c, b);
|
|
5564
|
+
return mcb.inverse().multiply(mca);
|
|
5565
|
+
}
|
|
5566
|
+
|
|
5567
|
+
/**
|
|
5568
|
+
* @param {SVGElement} descendant
|
|
5569
|
+
* @param {SVGElement} ancestor
|
|
5570
|
+
* @returns {SVGMatrix}
|
|
5571
|
+
* @description Finds the transformation matrix between the `ancestor` and `descendant`.
|
|
5572
|
+
*/
|
|
5573
|
+
function getLinealTransformation(ancestor, descendant) {
|
|
5574
|
+
const transformations = [];
|
|
5575
|
+
let n = descendant;
|
|
5576
|
+
while (n && n.nodeType === Node.ELEMENT_NODE && n !== ancestor) {
|
|
5577
|
+
const nm = getNodeMatrix(n);
|
|
5578
|
+
if (nm) {
|
|
5579
|
+
transformations.unshift(nm);
|
|
5580
|
+
}
|
|
5581
|
+
n = n.parentNode;
|
|
5582
|
+
}
|
|
5583
|
+
return transformations.reduce((m, t) => m.multiply(t), createIdentityMatrix());
|
|
5584
|
+
}
|
|
5315
5585
|
|
|
5316
5586
|
// Vectorizer.
|
|
5317
|
-
|
|
5318
|
-
var hasSvg = typeof window === 'object' && !!window.SVGAngle;
|
|
5587
|
+
// -----------
|
|
5319
5588
|
|
|
5589
|
+
const V = function () {
|
|
5320
5590
|
// SVG support is required.
|
|
5321
|
-
if (!
|
|
5591
|
+
if (!isSVGSupported) {
|
|
5322
5592
|
// Return a function that throws an error when it is used.
|
|
5323
5593
|
return function () {
|
|
5324
5594
|
throw new Error('SVG is required to use Vectorizer.');
|
|
5325
5595
|
};
|
|
5326
5596
|
}
|
|
5327
5597
|
|
|
5328
|
-
// XML namespaces.
|
|
5329
|
-
var ns = {
|
|
5330
|
-
svg: 'http://www.w3.org/2000/svg',
|
|
5331
|
-
xmlns: 'http://www.w3.org/2000/xmlns/',
|
|
5332
|
-
xml: 'http://www.w3.org/XML/1998/namespace',
|
|
5333
|
-
xlink: 'http://www.w3.org/1999/xlink',
|
|
5334
|
-
xhtml: 'http://www.w3.org/1999/xhtml'
|
|
5335
|
-
};
|
|
5336
|
-
var SVGVersion = '1.1';
|
|
5337
|
-
|
|
5338
5598
|
// Declare shorthands to the most used math functions.
|
|
5339
5599
|
var math = Math;
|
|
5340
5600
|
var PI = math.PI;
|
|
@@ -5379,7 +5639,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
5379
5639
|
}
|
|
5380
5640
|
el = document.importNode(svgDoc.firstChild, true);
|
|
5381
5641
|
} else {
|
|
5382
|
-
el =
|
|
5642
|
+
el = createSVGElement(el);
|
|
5383
5643
|
}
|
|
5384
5644
|
V.ensureId(el);
|
|
5385
5645
|
}
|
|
@@ -5405,17 +5665,19 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
5405
5665
|
* @param {SVGGElement} toElem
|
|
5406
5666
|
* @returns {SVGMatrix}
|
|
5407
5667
|
*/
|
|
5408
|
-
VPrototype.getTransformToElement = function (target) {
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
if (
|
|
5414
|
-
|
|
5668
|
+
VPrototype.getTransformToElement = function (target, opt) {
|
|
5669
|
+
const node = this.node;
|
|
5670
|
+
const targetNode = V.toNode(target);
|
|
5671
|
+
let m;
|
|
5672
|
+
if (V.isSVGGraphicsElement(targetNode) && V.isSVGGraphicsElement(node)) {
|
|
5673
|
+
if (opt && opt.safe) {
|
|
5674
|
+
// Use the traversal method to get the transformation matrix.
|
|
5675
|
+
m = getRelativeTransformationSafe(node, targetNode);
|
|
5676
|
+
} else {
|
|
5677
|
+
m = getRelativeTransformation(node, targetNode);
|
|
5415
5678
|
}
|
|
5416
5679
|
}
|
|
5417
|
-
|
|
5418
|
-
return V.createSVGMatrix();
|
|
5680
|
+
return m || createIdentityMatrix();
|
|
5419
5681
|
};
|
|
5420
5682
|
|
|
5421
5683
|
/**
|
|
@@ -5424,15 +5686,19 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
5424
5686
|
* @returns {Vectorizer|SVGMatrix} Setter / Getter
|
|
5425
5687
|
*/
|
|
5426
5688
|
VPrototype.transform = function (matrix, opt) {
|
|
5427
|
-
|
|
5689
|
+
const node = this.node;
|
|
5690
|
+
|
|
5691
|
+
// Getter
|
|
5428
5692
|
if (V.isUndefined(matrix)) {
|
|
5429
|
-
return
|
|
5693
|
+
return getNodeMatrix(node) || createIdentityMatrix();
|
|
5430
5694
|
}
|
|
5695
|
+
|
|
5696
|
+
// Setter
|
|
5431
5697
|
if (opt && opt.absolute) {
|
|
5432
|
-
|
|
5698
|
+
replaceTransformNode(node, matrix);
|
|
5699
|
+
} else {
|
|
5700
|
+
transformNode(node, matrix);
|
|
5433
5701
|
}
|
|
5434
|
-
var svgTransform = V.createSVGTransform(matrix);
|
|
5435
|
-
node.transform.baseVal.appendItem(svgTransform);
|
|
5436
5702
|
return this;
|
|
5437
5703
|
};
|
|
5438
5704
|
VPrototype.translate = function (tx, ty, opt) {
|
|
@@ -5506,7 +5772,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
5506
5772
|
}
|
|
5507
5773
|
try {
|
|
5508
5774
|
box = node.getBBox();
|
|
5509
|
-
} catch
|
|
5775
|
+
} catch {
|
|
5510
5776
|
// Fallback for IE.
|
|
5511
5777
|
box = {
|
|
5512
5778
|
x: node.clientLeft,
|
|
@@ -5552,7 +5818,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
5552
5818
|
if (!options.recursive) {
|
|
5553
5819
|
try {
|
|
5554
5820
|
outputBBox = node.getBBox();
|
|
5555
|
-
} catch
|
|
5821
|
+
} catch {
|
|
5556
5822
|
// Fallback for IE.
|
|
5557
5823
|
outputBBox = {
|
|
5558
5824
|
x: node.clientLeft,
|
|
@@ -5790,7 +6056,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
5790
6056
|
for (var i = 0, lastI = lines.length - 1; i <= lastI; i++) {
|
|
5791
6057
|
var dy = lineHeight;
|
|
5792
6058
|
var lineClassName = 'v-line';
|
|
5793
|
-
var lineNode = doc.createElementNS(
|
|
6059
|
+
var lineNode = doc.createElementNS(svg, 'tspan');
|
|
5794
6060
|
var line = lines[i];
|
|
5795
6061
|
var lineMetrics;
|
|
5796
6062
|
if (line) {
|
|
@@ -6104,9 +6370,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
6104
6370
|
try {
|
|
6105
6371
|
var globalPoint = p.matrixTransform(svg.getScreenCTM().inverse());
|
|
6106
6372
|
var globalToLocalMatrix = this.getTransformToElement(svg).inverse();
|
|
6107
|
-
} catch
|
|
6373
|
+
} catch {
|
|
6108
6374
|
// IE9 throws an exception in odd cases. (`Unexpected call to method or property access`)
|
|
6109
|
-
// We have to make do with the original
|
|
6375
|
+
// We have to make do with the original coordinates.
|
|
6110
6376
|
return p;
|
|
6111
6377
|
}
|
|
6112
6378
|
return globalPoint.matrixTransform(globalToLocalMatrix);
|
|
@@ -6160,7 +6426,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
6160
6426
|
// 5. Apply transformations and the scale
|
|
6161
6427
|
var transform = V.createSVGTransform();
|
|
6162
6428
|
transform.setMatrix(translateFromOrigin.matrix.multiply(rotateAroundOrigin.matrix.multiply(translateToOrigin.matrix.multiply(ctm.scale(scale.sx, scale.sy)))));
|
|
6163
|
-
this.attr('transform',
|
|
6429
|
+
this.attr('transform', matrixToTransformString(transform.matrix));
|
|
6164
6430
|
return this;
|
|
6165
6431
|
};
|
|
6166
6432
|
VPrototype.animateAlongPath = function (attrs, path) {
|
|
@@ -6174,7 +6440,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
6174
6440
|
this.append(animateMotion);
|
|
6175
6441
|
try {
|
|
6176
6442
|
animateMotion.node.beginElement();
|
|
6177
|
-
} catch
|
|
6443
|
+
} catch {
|
|
6178
6444
|
// Fallback for IE 9.
|
|
6179
6445
|
// Run the animation programmatically if FakeSmile (`http://leunen.me/fakesmile/`) present
|
|
6180
6446
|
if (document.documentElement.getAttribute('smiling') === 'fake') {
|
|
@@ -6437,7 +6703,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
6437
6703
|
// If `content` is passed, it will be used as the SVG content of the `<svg>` root element.
|
|
6438
6704
|
V.createSvgDocument = function (content) {
|
|
6439
6705
|
if (content) {
|
|
6440
|
-
const XMLString = `<svg xmlns="${
|
|
6706
|
+
const XMLString = `<svg xmlns="${svg}" xmlns:xlink="${xlink}" version="${SVG_VERSION}">${content}</svg>`;
|
|
6441
6707
|
const {
|
|
6442
6708
|
documentElement
|
|
6443
6709
|
} = V.parseXML(XMLString, {
|
|
@@ -6445,10 +6711,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
6445
6711
|
});
|
|
6446
6712
|
return documentElement;
|
|
6447
6713
|
}
|
|
6448
|
-
|
|
6449
|
-
svg.setAttributeNS(ns.xmlns, 'xmlns:xlink', ns.xlink);
|
|
6450
|
-
svg.setAttribute('version', SVGVersion);
|
|
6451
|
-
return svg;
|
|
6714
|
+
return createSVGDocument();
|
|
6452
6715
|
};
|
|
6453
6716
|
V.createSVGStyle = function (stylesheet) {
|
|
6454
6717
|
const {
|
|
@@ -6457,8 +6720,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
6457
6720
|
type: 'text/css'
|
|
6458
6721
|
}, [V.createCDATASection(stylesheet)]);
|
|
6459
6722
|
return node;
|
|
6460
|
-
}, V.createCDATASection = function () {
|
|
6461
|
-
let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
6723
|
+
}, V.createCDATASection = function (data = '') {
|
|
6462
6724
|
const xml = document.implementation.createDocument(null, 'xml', null);
|
|
6463
6725
|
return xml.createCDATASection(data);
|
|
6464
6726
|
};
|
|
@@ -6503,7 +6765,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
6503
6765
|
parser.async = opt.async;
|
|
6504
6766
|
}
|
|
6505
6767
|
xml = parser.parseFromString(data, 'text/xml');
|
|
6506
|
-
} catch
|
|
6768
|
+
} catch {
|
|
6507
6769
|
xml = undefined;
|
|
6508
6770
|
}
|
|
6509
6771
|
if (!xml || xml.getElementsByTagName('parsererror').length) {
|
|
@@ -6519,9 +6781,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
6519
6781
|
|
|
6520
6782
|
// List of attributes for which not to split camel case words.
|
|
6521
6783
|
// It contains known SVG attribute names and may be extended with user-defined attribute names.
|
|
6522
|
-
['baseFrequency', 'baseProfile', 'clipPathUnits', 'contentScriptType', 'contentStyleType', 'diffuseConstant', 'edgeMode', 'externalResourcesRequired', 'filterRes',
|
|
6784
|
+
['attributeName', 'baseFrequency', 'baseProfile', 'clipPathUnits', 'contentScriptType', 'contentStyleType', 'diffuseConstant', 'edgeMode', 'externalResourcesRequired', 'filterRes',
|
|
6523
6785
|
// deprecated
|
|
6524
|
-
'filterUnits', 'gradientTransform', 'gradientUnits', 'kernelMatrix', 'kernelUnitLength', 'keyPoints', 'lengthAdjust', 'limitingConeAngle', 'markerHeight', 'markerUnits', 'markerWidth', 'maskContentUnits', 'maskUnits', 'numOctaves', 'pathLength', 'patternContentUnits', 'patternTransform', 'patternUnits', 'pointsAtX', 'pointsAtY', 'pointsAtZ', 'preserveAlpha', 'preserveAspectRatio', 'primitiveUnits', 'refX', 'refY', 'requiredExtensions', 'requiredFeatures', 'specularConstant', 'specularExponent', 'spreadMethod', 'startOffset', 'stdDeviation', 'stitchTiles', 'surfaceScale', 'systemLanguage', 'tableValues', 'targetX', 'targetY', 'textLength', 'viewBox', 'viewTarget',
|
|
6786
|
+
'filterUnits', 'gradientTransform', 'gradientUnits', 'kernelMatrix', 'kernelUnitLength', 'keyPoints', 'lengthAdjust', 'limitingConeAngle', 'markerHeight', 'markerUnits', 'markerWidth', 'maskContentUnits', 'maskUnits', 'numOctaves', 'pathLength', 'patternContentUnits', 'patternTransform', 'patternUnits', 'pointsAtX', 'pointsAtY', 'pointsAtZ', 'preserveAlpha', 'preserveAspectRatio', 'primitiveUnits', 'refX', 'refY', 'requiredExtensions', 'requiredFeatures', 'repeatCount', 'specularConstant', 'specularExponent', 'spreadMethod', 'startOffset', 'stdDeviation', 'stitchTiles', 'surfaceScale', 'systemLanguage', 'tableValues', 'targetX', 'targetY', 'textLength', 'viewBox', 'viewTarget',
|
|
6525
6787
|
// deprecated
|
|
6526
6788
|
'xChannelSelector', 'yChannelSelector', 'zoomAndPan' // deprecated
|
|
6527
6789
|
].forEach(name => _attributeNames[name] = name);
|
|
@@ -6588,86 +6850,19 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
6588
6850
|
// ReDoS mitigation: Use an anchor at the beginning of the match
|
|
6589
6851
|
// ReDoS mitigation: Avoid backtracking (uses `[^()]+` instead of `.*?`)
|
|
6590
6852
|
// ReDoS mitigation: Don't match initial `(` inside repeated part
|
|
6591
|
-
// The following regex needs to use /g (= cannot use capturing groups)
|
|
6592
|
-
V.transformRegex = /\b\w+\([^()]+\)/g;
|
|
6593
6853
|
// The following regexes need to use capturing groups (= cannot use /g)
|
|
6594
6854
|
V.transformFunctionRegex = /\b(\w+)\(([^()]+)\)/;
|
|
6595
6855
|
V.transformTranslateRegex = /\btranslate\(([^()]+)\)/;
|
|
6596
6856
|
V.transformRotateRegex = /\brotate\(([^()]+)\)/;
|
|
6597
6857
|
V.transformScaleRegex = /\bscale\(([^()]+)\)/;
|
|
6598
6858
|
V.transformStringToMatrix = function (transform) {
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
// Note: Multiple transform functions are allowed in `transform` string
|
|
6603
|
-
// `match()` returns `null` if none found
|
|
6604
|
-
const transformMatches = transform && transform.match(V.transformRegex);
|
|
6605
|
-
if (!transformMatches) {
|
|
6606
|
-
// Return identity matrix
|
|
6607
|
-
return transformationMatrix;
|
|
6608
|
-
}
|
|
6609
|
-
const numMatches = transformMatches.length;
|
|
6610
|
-
for (let i = 0; i < numMatches; i++) {
|
|
6611
|
-
const transformMatch = transformMatches[i];
|
|
6612
|
-
// Use same regex as above, but with capturing groups
|
|
6613
|
-
// `match()` returns values of capturing groups as `[1]`, `[2]`
|
|
6614
|
-
const transformFunctionMatch = transformMatch.match(V.transformFunctionRegex);
|
|
6615
|
-
if (transformFunctionMatch) {
|
|
6616
|
-
let sx, sy, tx, ty, angle;
|
|
6617
|
-
let ctm = V.createSVGMatrix();
|
|
6618
|
-
const transformFunction = transformFunctionMatch[1].toLowerCase();
|
|
6619
|
-
const args = transformFunctionMatch[2].split(V.transformSeparatorRegex);
|
|
6620
|
-
switch (transformFunction) {
|
|
6621
|
-
case 'scale':
|
|
6622
|
-
sx = parseFloat(args[0]);
|
|
6623
|
-
sy = args[1] === undefined ? sx : parseFloat(args[1]);
|
|
6624
|
-
ctm = ctm.scaleNonUniform(sx, sy);
|
|
6625
|
-
break;
|
|
6626
|
-
case 'translate':
|
|
6627
|
-
tx = parseFloat(args[0]);
|
|
6628
|
-
ty = parseFloat(args[1]);
|
|
6629
|
-
ctm = ctm.translate(tx, ty);
|
|
6630
|
-
break;
|
|
6631
|
-
case 'rotate':
|
|
6632
|
-
angle = parseFloat(args[0]);
|
|
6633
|
-
tx = parseFloat(args[1]) || 0;
|
|
6634
|
-
ty = parseFloat(args[2]) || 0;
|
|
6635
|
-
if (tx !== 0 || ty !== 0) {
|
|
6636
|
-
ctm = ctm.translate(tx, ty).rotate(angle).translate(-tx, -ty);
|
|
6637
|
-
} else {
|
|
6638
|
-
ctm = ctm.rotate(angle);
|
|
6639
|
-
}
|
|
6640
|
-
break;
|
|
6641
|
-
case 'skewx':
|
|
6642
|
-
angle = parseFloat(args[0]);
|
|
6643
|
-
ctm = ctm.skewX(angle);
|
|
6644
|
-
break;
|
|
6645
|
-
case 'skewy':
|
|
6646
|
-
angle = parseFloat(args[0]);
|
|
6647
|
-
ctm = ctm.skewY(angle);
|
|
6648
|
-
break;
|
|
6649
|
-
case 'matrix':
|
|
6650
|
-
ctm.a = parseFloat(args[0]);
|
|
6651
|
-
ctm.b = parseFloat(args[1]);
|
|
6652
|
-
ctm.c = parseFloat(args[2]);
|
|
6653
|
-
ctm.d = parseFloat(args[3]);
|
|
6654
|
-
ctm.e = parseFloat(args[4]);
|
|
6655
|
-
ctm.f = parseFloat(args[5]);
|
|
6656
|
-
break;
|
|
6657
|
-
default:
|
|
6658
|
-
continue;
|
|
6659
|
-
}
|
|
6660
|
-
|
|
6661
|
-
// Multiply current transformation into result matrix
|
|
6662
|
-
transformationMatrix = transformationMatrix.multiply(ctm);
|
|
6663
|
-
}
|
|
6859
|
+
let matrix;
|
|
6860
|
+
if (V.isString(transform)) {
|
|
6861
|
+
matrix = createMatrixFromTransformString(transform);
|
|
6664
6862
|
}
|
|
6665
|
-
return
|
|
6666
|
-
};
|
|
6667
|
-
V.matrixToTransformString = function (matrix) {
|
|
6668
|
-
matrix || (matrix = true);
|
|
6669
|
-
return 'matrix(' + (matrix.a !== undefined ? matrix.a : 1) + ',' + (matrix.b !== undefined ? matrix.b : 0) + ',' + (matrix.c !== undefined ? matrix.c : 0) + ',' + (matrix.d !== undefined ? matrix.d : 1) + ',' + (matrix.e !== undefined ? matrix.e : 0) + ',' + (matrix.f !== undefined ? matrix.f : 0) + ')';
|
|
6863
|
+
return matrix || createIdentityMatrix();
|
|
6670
6864
|
};
|
|
6865
|
+
V.matrixToTransformString = matrixToTransformString;
|
|
6671
6866
|
V.parseTransformString = function (transform) {
|
|
6672
6867
|
var translate, rotate, scale;
|
|
6673
6868
|
if (transform) {
|
|
@@ -6825,31 +7020,24 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
6825
7020
|
// IE/Edge does not implement SVGGraphicsElement interface, thus check for `getScreenCTM` below
|
|
6826
7021
|
return node instanceof SVGElement && typeof node.getScreenCTM === 'function';
|
|
6827
7022
|
};
|
|
6828
|
-
|
|
6829
|
-
V.createSVGMatrix = function (matrix) {
|
|
6830
|
-
var svgMatrix = svgDocument.createSVGMatrix();
|
|
6831
|
-
for (var component in matrix) {
|
|
6832
|
-
svgMatrix[component] = matrix[component];
|
|
6833
|
-
}
|
|
6834
|
-
return svgMatrix;
|
|
6835
|
-
};
|
|
7023
|
+
V.createSVGMatrix = createMatrix;
|
|
6836
7024
|
V.createSVGTransform = function (matrix) {
|
|
6837
7025
|
if (!V.isUndefined(matrix)) {
|
|
6838
|
-
if (!(matrix
|
|
6839
|
-
matrix =
|
|
7026
|
+
if (!isSVGMatrix(matrix)) {
|
|
7027
|
+
matrix = createMatrix(matrix);
|
|
6840
7028
|
}
|
|
6841
|
-
return
|
|
7029
|
+
return internalSVGDocument.createSVGTransformFromMatrix(matrix);
|
|
6842
7030
|
}
|
|
6843
|
-
return
|
|
7031
|
+
return internalSVGDocument.createSVGTransform();
|
|
6844
7032
|
};
|
|
6845
7033
|
V.createSVGPoint = function (x, y) {
|
|
6846
|
-
var p =
|
|
7034
|
+
var p = internalSVGDocument.createSVGPoint();
|
|
6847
7035
|
p.x = x;
|
|
6848
7036
|
p.y = y;
|
|
6849
7037
|
return p;
|
|
6850
7038
|
};
|
|
6851
7039
|
V.transformRect = function (r, matrix) {
|
|
6852
|
-
var p =
|
|
7040
|
+
var p = internalSVGDocument.createSVGPoint();
|
|
6853
7041
|
p.x = r.x;
|
|
6854
7042
|
p.y = r.y;
|
|
6855
7043
|
var corner1 = p.matrixTransform(matrix);
|
|
@@ -7041,7 +7229,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
7041
7229
|
};
|
|
7042
7230
|
V.convertLineToPathData = function (line) {
|
|
7043
7231
|
line = V(line);
|
|
7044
|
-
var d = ['M', line.attr('x1'), line.attr('y1'), 'L', line.attr('x2'), line.attr('y2')].join(' ');
|
|
7232
|
+
var d = ['M', line.attr('x1') || '0', line.attr('y1') || '0', 'L', line.attr('x2') || '0', line.attr('y2') || '0'].join(' ');
|
|
7045
7233
|
return d;
|
|
7046
7234
|
};
|
|
7047
7235
|
V.convertPolygonToPathData = function (polygon) {
|
|
@@ -7451,10 +7639,6 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
7451
7639
|
case 'V':
|
|
7452
7640
|
path = ['L'].concat(d.x, path[1]);
|
|
7453
7641
|
break;
|
|
7454
|
-
case 'L':
|
|
7455
|
-
break;
|
|
7456
|
-
case 'Z':
|
|
7457
|
-
break;
|
|
7458
7642
|
}
|
|
7459
7643
|
return path;
|
|
7460
7644
|
}
|
|
@@ -7509,7 +7693,20 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
7509
7693
|
return normalize(pathData).join(',').split(',').join(' ');
|
|
7510
7694
|
};
|
|
7511
7695
|
}();
|
|
7512
|
-
|
|
7696
|
+
|
|
7697
|
+
/**
|
|
7698
|
+
*
|
|
7699
|
+
* @param {SVGElement|V} node1
|
|
7700
|
+
* @param {SVGElement|V} node2
|
|
7701
|
+
* @returns {SVGElement|null}
|
|
7702
|
+
*/
|
|
7703
|
+
V.getCommonAncestor = function (node1, node2) {
|
|
7704
|
+
if (!node1 || !node2) return null;
|
|
7705
|
+
return getCommonAncestor(V.toNode(node1), V.toNode(node2));
|
|
7706
|
+
};
|
|
7707
|
+
V.namespace = {
|
|
7708
|
+
...ns
|
|
7709
|
+
};
|
|
7513
7710
|
V.g = g;
|
|
7514
7711
|
return V;
|
|
7515
7712
|
}();
|