svg-path-d
Version:
SVG path data (path[d] attribute content) manipulation library.
183 lines • 7.68 kB
JavaScript
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __spreadArrays = (this && this.__spreadArrays) || function () {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getGroups = exports.split = exports.trisect = exports.bisect = exports.canSplit = void 0;
var math1d_1 = require("./utils/math1d");
var command_assertion_1 = require("./command-assertion");
var path_node_1 = require("./path-node");
var curve_node_1 = require("./curve-node");
var arc_node_1 = require("./arc-node");
function canSplit(item) {
return !(command_assertion_1.isMoveTo(item) || command_assertion_1.isClosePath(item));
}
exports.canSplit = canSplit;
function bisect(item, t) {
if (t === void 0) { t = 1 / 2; }
var prev = item.prev;
if (command_assertion_1.isHLineTo(item)) {
var h1 = { name: 'H', x: math1d_1.lerp(path_node_1.getX(prev), item.x, t), prev: prev };
var h2 = { name: 'H', x: item.x, prev: h1 };
return [h1, h2];
}
else if (command_assertion_1.isVLineTo(item)) {
var v1 = { name: 'V', y: math1d_1.lerp(path_node_1.getY(prev), item.y, t), prev: prev };
var v2 = { name: 'V', y: item.y, prev: v1 };
return [v1, v2];
}
else {
var X0 = path_node_1.getX(prev);
var Y0 = path_node_1.getY(prev);
if (command_assertion_1.isBezierCurve(item)) {
// De Casteljau's Algorithm. https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm
var X1 = curve_node_1.getFirstControlX(item);
var Y1 = curve_node_1.getFirstControlY(item);
if (command_assertion_1.isCurveTo(item) || command_assertion_1.isSmoothCurveTo(item)) {
var X2 = item.x2;
var Y2 = item.y2;
var X12 = math1d_1.lerp(X1, X2, t);
var Y12 = math1d_1.lerp(Y1, Y2, t);
var XB3 = item.x;
var YB3 = item.y;
var XB2 = math1d_1.lerp(X2, XB3, t);
var YB2 = math1d_1.lerp(Y2, YB3, t);
var XB1 = math1d_1.lerp(X12, XB2, t);
var YB1 = math1d_1.lerp(Y12, YB2, t);
var XA1 = math1d_1.lerp(X0, X1, t);
var YA1 = math1d_1.lerp(Y0, Y1, t);
var XA2 = math1d_1.lerp(XA1, X12, t);
var YA2 = math1d_1.lerp(YA1, Y12, t);
var XA3 = math1d_1.lerp(XA2, XB1, t);
var YA3 = math1d_1.lerp(YA2, YB1, t);
var c1 = { name: 'C', x1: XA1, y1: YA1, x2: XA2, y2: YA2, x: XA3, y: YA3, prev: prev };
var c2 = { name: 'C', x1: XB1, y1: YB1, x2: XB2, y2: YB2, x: XB3, y: YB3, prev: c1 };
return [c1, c2];
}
else {
var XB2 = item.x;
var YB2 = item.y;
var XB1 = math1d_1.lerp(X1, XB2, t);
var YB1 = math1d_1.lerp(Y1, YB2, t);
var XA1 = math1d_1.lerp(X0, X1, t);
var YA1 = math1d_1.lerp(Y0, Y1, t);
var XA2 = math1d_1.lerp(XA1, XB1, t);
var YA2 = math1d_1.lerp(YA1, YB1, t);
var q1 = { name: 'Q', x1: XA1, y1: YA1, x: XA2, y: YA2, prev: prev };
var q2 = { name: 'Q', x1: XB1, y1: YB1, x: XB2, y: YB2, prev: q1 };
return [q1, q2];
}
}
else if (command_assertion_1.isEllipticalArc(item)) {
var par = arc_node_1.getCenterParams(item);
if (par.deltaTheta) {
var deltaTheta1 = math1d_1.lerp(0, par.deltaTheta, t);
var p1 = arc_node_1.getEllipsePoint(par, par.theta + deltaTheta1);
var f1 = Math.abs(deltaTheta1) > Math.PI;
var f2 = Math.abs(par.deltaTheta - deltaTheta1) > Math.PI;
var rx = par.rx, ry = par.ry;
var angle = item.angle, sweepFlag = item.sweepFlag;
var a1 = { name: 'A', rx: rx, ry: ry, angle: angle, sweepFlag: sweepFlag, largeArcFlag: f1, x: p1.x, y: p1.y, prev: prev };
var a2 = { name: 'A', rx: rx, ry: ry, angle: angle, sweepFlag: sweepFlag, largeArcFlag: f2, x: item.x, y: item.y, prev: a1 };
return [a1, a2];
}
else {
// Treat this as a straight line from (x1, y1) to (x2, y2).
var x = math1d_1.lerp(X0, item.x, t);
var y = math1d_1.lerp(Y0, item.y, t);
var rx = item.rx, ry = item.ry, angle = item.angle, sweepFlag = item.sweepFlag;
var largeArcFlag = false;
var a1 = { name: 'A', rx: rx, ry: ry, angle: angle, sweepFlag: sweepFlag, largeArcFlag: largeArcFlag, x: x, y: y, prev: prev };
var a2 = { name: 'A', rx: rx, ry: ry, angle: angle, sweepFlag: sweepFlag, largeArcFlag: largeArcFlag, x: item.x, y: item.y, prev: a1 };
return [a1, a2];
}
}
else if (command_assertion_1.isLineTo(item)) {
var l1 = { name: 'L', x: math1d_1.lerp(X0, item.x, t), y: math1d_1.lerp(Y0, item.y, t), prev: prev };
var l2 = { name: 'L', x: item.x, y: item.y, prev: l1 };
return [l1, l2];
}
else {
return [__assign({}, item)];
}
}
}
exports.bisect = bisect;
function trisect(item, t) {
if (t === void 0) { t = 1 / 3; }
var arr = bisect(item, t);
if (arr.length > 1) {
return __spreadArrays([arr[0]], bisect(arr[1]));
}
return arr;
}
exports.trisect = trisect;
function split(item, count) {
count = Math.round(count);
if (count <= 1 || !isFinite(count)) {
return [__assign({}, item)];
}
else if (count === 2) {
return bisect(item);
}
else if (count === 3) {
return trisect(item);
}
else if (count % 2 === 0) {
var arr = bisect(item);
if (arr.length > 1) {
return split(arr[0], count / 2).concat(split(arr[1], count / 2));
}
return arr;
}
else {
var arr = bisect(item, 1 / count);
if (arr.length > 1) {
return __spreadArrays([arr[0]], split(arr[1], count - 1));
}
return arr;
}
}
exports.split = split;
// Split into logic groups
function getGroups(items) {
var groups = [];
var next = undefined;
for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
var item = items_1[_i];
if (!next || command_assertion_1.isMoveTo(item)) {
if (next) {
groups.push(next);
}
next = [item];
}
else {
next.push(item);
}
if (command_assertion_1.isClosePath(item)) {
groups.push(next);
next = undefined;
}
}
if (next) {
groups.push(next);
}
return groups;
}
exports.getGroups = getGroups;
//# sourceMappingURL=splitter.js.map