NuclearDispersionSystem/ant-design-vue-jeecg/node_modules/@antv/util/lib/path/path2curve.js

281 lines
8.1 KiB
JavaScript
Raw Normal View History

2023-09-14 14:47:11 +08:00
var pathToAbsolute = require('./path2absolute');
var a2c = function a2c(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {
// for more information of where this math came from visit:
// http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
if (rx === ry) {
rx += 1;
}
var _120 = Math.PI * 120 / 180;
var rad = Math.PI / 180 * (+angle || 0);
var res = [];
var xy = void 0;
var f1 = void 0;
var f2 = void 0;
var cx = void 0;
var cy = void 0;
var rotate = function rotate(x, y, rad) {
var X = x * Math.cos(rad) - y * Math.sin(rad);
var Y = x * Math.sin(rad) + y * Math.cos(rad);
return {
x: X,
y: Y
};
};
if (!recursive) {
xy = rotate(x1, y1, -rad);
x1 = xy.x;
y1 = xy.y;
xy = rotate(x2, y2, -rad);
x2 = xy.x;
y2 = xy.y;
if (x1 === x2 && y1 === y2) {
// 若弧的起始点和终点重叠则错开一点
x2 += 1;
y2 += 1;
}
// const cos = Math.cos(Math.PI / 180 * angle);
// const sin = Math.sin(Math.PI / 180 * angle);
var x = (x1 - x2) / 2;
var y = (y1 - y2) / 2;
var h = x * x / (rx * rx) + y * y / (ry * ry);
if (h > 1) {
h = Math.sqrt(h);
rx = h * rx;
ry = h * ry;
}
var rx2 = rx * rx;
var ry2 = ry * ry;
var k = (large_arc_flag === sweep_flag ? -1 : 1) * Math.sqrt(Math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x)));
cx = k * rx * y / ry + (x1 + x2) / 2;
cy = k * -ry * x / rx + (y1 + y2) / 2;
f1 = Math.asin(((y1 - cy) / ry).toFixed(9));
f2 = Math.asin(((y2 - cy) / ry).toFixed(9));
f1 = x1 < cx ? Math.PI - f1 : f1;
f2 = x2 < cx ? Math.PI - f2 : f2;
f1 < 0 && (f1 = Math.PI * 2 + f1);
f2 < 0 && (f2 = Math.PI * 2 + f2);
if (sweep_flag && f1 > f2) {
f1 = f1 - Math.PI * 2;
}
if (!sweep_flag && f2 > f1) {
f2 = f2 - Math.PI * 2;
}
} else {
f1 = recursive[0];
f2 = recursive[1];
cx = recursive[2];
cy = recursive[3];
}
var df = f2 - f1;
if (Math.abs(df) > _120) {
var f2old = f2;
var x2old = x2;
var y2old = y2;
f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
x2 = cx + rx * Math.cos(f2);
y2 = cy + ry * Math.sin(f2);
res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);
}
df = f2 - f1;
var c1 = Math.cos(f1);
var s1 = Math.sin(f1);
var c2 = Math.cos(f2);
var s2 = Math.sin(f2);
var t = Math.tan(df / 4);
var hx = 4 / 3 * rx * t;
var hy = 4 / 3 * ry * t;
var m1 = [x1, y1];
var m2 = [x1 + hx * s1, y1 - hy * c1];
var m3 = [x2 + hx * s2, y2 - hy * c2];
var m4 = [x2, y2];
m2[0] = 2 * m1[0] - m2[0];
m2[1] = 2 * m1[1] - m2[1];
if (recursive) {
return [m2, m3, m4].concat(res);
}
res = [m2, m3, m4].concat(res).join().split(',');
var newres = [];
for (var i = 0, ii = res.length; i < ii; i++) {
newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;
}
return newres;
};
var l2c = function l2c(x1, y1, x2, y2) {
return [x1, y1, x2, y2, x2, y2];
};
var q2c = function q2c(x1, y1, ax, ay, x2, y2) {
var _13 = 1 / 3;
var _23 = 2 / 3;
return [_13 * x1 + _23 * ax, _13 * y1 + _23 * ay, _13 * x2 + _23 * ax, _13 * y2 + _23 * ay, x2, y2];
};
module.exports = function pathTocurve(path, path2) {
var p = pathToAbsolute(path);
var p2 = path2 && pathToAbsolute(path2);
var attrs = {
x: 0,
y: 0,
bx: 0,
by: 0,
X: 0,
Y: 0,
qx: null,
qy: null
};
var attrs2 = {
x: 0,
y: 0,
bx: 0,
by: 0,
X: 0,
Y: 0,
qx: null,
qy: null
};
var pcoms1 = []; // path commands of original path p
var pcoms2 = []; // path commands of original path p2
var pfirst = ''; // temporary holder for original path command
var pcom = ''; // holder for previous path command of original path
var ii = void 0;
var processPath = function processPath(path, d, pcom) {
var nx = void 0,
ny = void 0;
if (!path) {
return ['C', d.x, d.y, d.x, d.y, d.x, d.y];
}!(path[0] in {
T: 1,
Q: 1
}) && (d.qx = d.qy = null);
switch (path[0]) {
case 'M':
d.X = path[1];
d.Y = path[2];
break;
case 'A':
path = ['C'].concat(a2c.apply(0, [d.x, d.y].concat(path.slice(1))));
break;
case 'S':
if (pcom === 'C' || pcom === 'S') {
// In "S" case we have to take into account, if the previous command is C/S.
nx = d.x * 2 - d.bx; // And reflect the previous
ny = d.y * 2 - d.by; // command's control point relative to the current point.
} else {
// or some else or nothing
nx = d.x;
ny = d.y;
}
path = ['C', nx, ny].concat(path.slice(1));
break;
case 'T':
if (pcom === 'Q' || pcom === 'T') {
// In "T" case we have to take into account, if the previous command is Q/T.
d.qx = d.x * 2 - d.qx; // And make a reflection similar
d.qy = d.y * 2 - d.qy; // to case "S".
} else {
// or something else or nothing
d.qx = d.x;
d.qy = d.y;
}
path = ['C'].concat(q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));
break;
case 'Q':
d.qx = path[1];
d.qy = path[2];
path = ['C'].concat(q2c(d.x, d.y, path[1], path[2], path[3], path[4]));
break;
case 'L':
path = ['C'].concat(l2c(d.x, d.y, path[1], path[2]));
break;
case 'H':
path = ['C'].concat(l2c(d.x, d.y, path[1], d.y));
break;
case 'V':
path = ['C'].concat(l2c(d.x, d.y, d.x, path[1]));
break;
case 'Z':
path = ['C'].concat(l2c(d.x, d.y, d.X, d.Y));
break;
default:
break;
}
return path;
};
var fixArc = function fixArc(pp, i) {
if (pp[i].length > 7) {
pp[i].shift();
var pi = pp[i];
while (pi.length) {
pcoms1[i] = 'A'; // if created multiple C:s, their original seg is saved
p2 && (pcoms2[i] = 'A'); // the same as above
pp.splice(i++, 0, ['C'].concat(pi.splice(0, 6)));
}
pp.splice(i, 1);
ii = Math.max(p.length, p2 && p2.length || 0);
}
};
var fixM = function fixM(path1, path2, a1, a2, i) {
if (path1 && path2 && path1[i][0] === 'M' && path2[i][0] !== 'M') {
path2.splice(i, 0, ['M', a2.x, a2.y]);
a1.bx = 0;
a1.by = 0;
a1.x = path1[i][1];
a1.y = path1[i][2];
ii = Math.max(p.length, p2 && p2.length || 0);
}
};
ii = Math.max(p.length, p2 && p2.length || 0);
for (var i = 0; i < ii; i++) {
p[i] && (pfirst = p[i][0]); // save current path command
if (pfirst !== 'C') {
// C is not saved yet, because it may be result of conversion
pcoms1[i] = pfirst; // Save current path command
i && (pcom = pcoms1[i - 1]); // Get previous path command pcom
}
p[i] = processPath(p[i], attrs, pcom); // Previous path command is inputted to processPath
if (pcoms1[i] !== 'A' && pfirst === 'C') pcoms1[i] = 'C'; // A is the only command
// which may produce multiple C:s
// so we have to make sure that C is also C in original path
fixArc(p, i); // fixArc adds also the right amount of A:s to pcoms1
if (p2) {
// the same procedures is done to p2
p2[i] && (pfirst = p2[i][0]);
if (pfirst !== 'C') {
pcoms2[i] = pfirst;
i && (pcom = pcoms2[i - 1]);
}
p2[i] = processPath(p2[i], attrs2, pcom);
if (pcoms2[i] !== 'A' && pfirst === 'C') {
pcoms2[i] = 'C';
}
fixArc(p2, i);
}
fixM(p, p2, attrs, attrs2, i);
fixM(p2, p, attrs2, attrs, i);
var seg = p[i];
var seg2 = p2 && p2[i];
var seglen = seg.length;
var seg2len = p2 && seg2.length;
attrs.x = seg[seglen - 2];
attrs.y = seg[seglen - 1];
attrs.bx = parseFloat(seg[seglen - 4]) || attrs.x;
attrs.by = parseFloat(seg[seglen - 3]) || attrs.y;
attrs2.bx = p2 && (parseFloat(seg2[seg2len - 4]) || attrs2.x);
attrs2.by = p2 && (parseFloat(seg2[seg2len - 3]) || attrs2.y);
attrs2.x = p2 && seg2[seg2len - 2];
attrs2.y = p2 && seg2[seg2len - 1];
}
return p2 ? [p, p2] : p;
};