UNPKG

svg-path-d

Version:

SVG path data (path[d] attribute content) manipulation library.

209 lines 7.54 kB
"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); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.makeInterpolator = exports.align = void 0; var math1d_1 = require("./utils/math1d"); var arc_node_1 = require("./arc-node"); var command_assertion_1 = require("./command-assertion"); var path_node_1 = require("./path-node"); var promoter_1 = require("./promoter"); var splitter_1 = require("./splitter"); var builder_1 = require("./builder"); function stretch(pathGroup, size) { var first = pathGroup[0]; if (!(first && command_assertion_1.isMoveTo(first))) { throw new Error('First node in a path group should be MoveTo!'); } var items = [__assign({}, first)]; var a = pathGroup.length - 1; var b = size - 1; if (a > 0) { // Splitting existing nodes. var r = b % a; var n = (b - r) / a; for (var i = 1; i <= a; i++) { var node = pathGroup[i]; var x = i <= r ? n + 1 : n; if (x > 1) { items.push.apply(items, splitter_1.split(node, x)); } else { items.push(__assign({}, node)); } } } else { // Adding empty nodes. for (var i = 0; i < b; i++) { items.push({ name: 'L', x: first.x, y: first.y }); } } return path_node_1.makePath(items); } function alignGroups(groupA, groupB) { var count = Math.max(groupA.length, groupB.length); if (groupA.length < count) { groupA = stretch(groupA, count); } else if (groupB.length < count) { groupB = stretch(groupB, count); } var itemsA = []; var itemsB = []; for (var i = 0; i < count; i++) { var a = groupA[i]; var b = groupB[i]; if (a.name === b.name) { itemsA.push(__assign({}, a)); itemsB.push(__assign({}, b)); } else if (command_assertion_1.isLineTo(a) && command_assertion_1.isQCurveTo(b)) { itemsA.push(promoter_1.promoteToQCurve(a)); itemsB.push(__assign({}, b)); } else if (command_assertion_1.isLineTo(b) && command_assertion_1.isQCurveTo(a)) { itemsA.push(__assign({}, a)); itemsB.push(promoter_1.promoteToQCurve(b)); } else { itemsA.push(promoter_1.canPromoteToCurve(a) ? promoter_1.promoteToCurve(a) : __assign({}, a)); itemsB.push(promoter_1.canPromoteToCurve(b) ? promoter_1.promoteToCurve(b) : __assign({}, b)); } } return [path_node_1.makePath(itemsA), path_node_1.makePath(itemsB)]; } // type SimpleNode = (MoveTo | LineTo | QCurveTo | CurveTo) & { prev: SimpleNode }; function normalize(path) { var items = []; // Let's start with a MoveTo node. if (path.length <= 0 || !command_assertion_1.isMoveTo(path[0])) { items.push({ name: 'M', x: 0, y: 0 }); } // Get rid of EllipticalArcs and ClosePaths. // Promote H/V Lines and Smooth Bezier Curves. for (var _i = 0, path_1 = path; _i < path_1.length; _i++) { var node = path_1[_i]; if (command_assertion_1.isEllipticalArc(node)) { items.push.apply(items, arc_node_1.approximateEllipticalArc(node)); } else if (command_assertion_1.isClosePath(node)) { var prev = node.prev; var x0 = path_node_1.getX(prev); var y0 = path_node_1.getY(prev); var x = path_node_1.getX(node); var y = path_node_1.getY(node); if (x0 !== x || y0 !== y) { items.push({ name: 'L', x: x, y: y, prev: prev }); } } else if (command_assertion_1.isHLineTo(node) || command_assertion_1.isVLineTo(node)) { items.push(promoter_1.promoteToLine(node)); } else if (command_assertion_1.isSmoothCurveTo(node)) { items.push(promoter_1.promoteToCurve(node)); } else if (command_assertion_1.isSmoothQCurveTo(node)) { items.push(promoter_1.promoteToQCurve(node)); } else { items.push(__assign({}, node)); } } return path_node_1.makePath(items); } function addEmptyGroups(groups, count, stopPoints) { for (var i = 0; i < count; i++) { var lastGroup = groups[groups.length - 1]; var prev = lastGroup[lastGroup.length - 1]; var x = void 0; var y = void 0; if (stopPoints && stopPoints.length > i) { x = stopPoints[i].x; y = stopPoints[i].y; } else { x = path_node_1.getX(prev); y = path_node_1.getY(prev); } groups.push([{ name: 'M', x: x, y: y, prev: prev }]); } } function align(src, dst, options) { var srcGroups = splitter_1.getGroups(normalize(src)); var dstGroups = splitter_1.getGroups(normalize(dst)); var count = srcGroups.length - dstGroups.length; if (count < 0) { addEmptyGroups(srcGroups, -count, options === null || options === void 0 ? void 0 : options.groupClosePoints); } else if (count > 0) { addEmptyGroups(dstGroups, count, options === null || options === void 0 ? void 0 : options.groupClosePoints); } var size = srcGroups.length; var itemsA = []; var itemsB = []; for (var i = 0; i < size; i++) { var _a = alignGroups(srcGroups[i], dstGroups[i]), a = _a[0], b = _a[1]; itemsA.push.apply(itemsA, a); itemsB.push.apply(itemsB, b); } return [path_node_1.makePath(itemsA), path_node_1.makePath(itemsB)]; } exports.align = align; var ARGS_COUNT = { Z: 0, H: 1, V: 1, L: 2, M: 2, T: 2, Q: 4, S: 4, C: 6, A: 7, }; function toPathArray(commands, params, formatter) { var path = []; var i = 0; for (var _i = 0, commands_1 = commands; _i < commands_1.length; _i++) { var c = commands_1[_i]; var buf = c; for (var j = i + ARGS_COUNT[c]; i < j; i++) { buf += ' ' + (formatter ? formatter(params[i]) : params[i].toString()); } path.push(buf); } return path; } function makeInterpolator(src, dst, options) { var commands = []; var srcParams = []; var dstParams = []; var _a = align(src, dst, options), a = _a[0], b = _a[1]; for (var i = 0; i < a.length; i++) { commands.push(a[i].name); builder_1.getParams(a[i], srcParams); builder_1.getParams(b[i], dstParams); } return function (t) { var params = srcParams; if (t >= 1) { params = dstParams; } else if (t > 0) { params = srcParams.map(function (value, index) { return math1d_1.lerp(value, dstParams[index], t); }); } return toPathArray(commands, params, options === null || options === void 0 ? void 0 : options.formatter); }; } exports.makeInterpolator = makeInterpolator; //# sourceMappingURL=interpolator.js.map