rpg-dialogue-js
Version:
A simple roleplay game dialogue engine and editor.
55 lines (49 loc) • 2.7 kB
text/typescript
/**
* Split SVG path data `d` strings.
*
* As this helper function does not detect all possible path data strings it should cover the most daily use-cases.
*
* For more insight see
* https://www.w3.org/TR/SVG/paths.html
*
* @author Ikaros Kappler
* @date 2022-11-22
* @modified 2022-12-21 Ported to Typescript
* @version 0.0.1-alpha
*/
import { SVGPathCommand } from "./types";
/**
* @name splitSVGPathData
* @static
* @param {string} dataString - The SVG path data to split. This should be some string
**/
export const splitSVGPathData = (dataString: string): Array<SVGPathCommand> | null => {
// I used a modified version of this Josh Frank's SVG path data RexEx.
// Source
// https://javascript.plainenglish.io/june-3-parsing-and-validating-svg-paths-with-regex-7bd0e245115
// const validCommand =
// /([ml](\s?-?((\d+(\.\d+)?)|(\.\d+)))[,\s]?(-?((\d+(\.\d+)?)|(\.\d+))))|([hv](\s?-?((\d+(\.\d+)?)|(\.\d+))))|(c(\s?-?((\d+(\.\d+)?)|(\.\d+)))([,\s]?(-?((\d+(\.\d+)?)|(\.\d+)))){5})|(q(\s?-?((\d+(\.\d+)?)|(\.\d+)))([,\s]?(-?((\d+(\.\d+)?)|(\.\d+)))){3}(\s?t?(\s?-?((\d+(\.\d+)?)|(\.\d+)))[,\s]?(-?((\d+(\.\d+)?)|(\.\d+))))*)|(a(\s?-?((\d+(\.\d+)?)|(\.\d+)))([,\s]?(-?((\d+(\.\d+)?)|(\.\d+)))){2}[,\s]?[01][,\s]+[01][,\s]+([,\s]?(-?((\d+(\.\d+)?)|(\.\d+)))){2})|(s(\s?-?((\d+(\.\d+)?)|(\.\d+)))([,\s]?(-?((\d+(\.\d+)?)|(\.\d+)))){3})|z/gi;
//
// My Version allows multiple param sets, too, like 'm|M (x y)+' or 'q|Q (x1 y1 x y)+'. Look at the plus.
const validCommand =
/([ml]((\s?-?((\d+(\.\d+)?)|(\.\d+)))[,\s]?(-?((\d+(\.\d+)?)|(\.\d+))))+)|([hv]((\s?-?((\d+(\.\d+)?)|(\.\d+))))+)|(c((\s?-?((\d+(\.\d+)?)|(\.\d+)))([,\s]?(-?((\d+(\.\d+)?)|(\.\d+)))){5})+)|(q((\s?-?((\d+(\.\d+)?)|(\.\d+)))([,\s]?(-?((\d+(\.\d+)?)|(\.\d+)))){3})+(\s?(t?(\s?-?((\d+(\.\d+)?)|(\.\d+)))[,\s]?(-?((\d+(\.\d+)?)|(\.\d+))))*)+)|(a((\s?-?((\d+(\.\d+)?)|(\.\d+)))([,\s]?(-?((\d+(\.\d+)?)|(\.\d+)))){2}[,\s]?[01][,\s]+[01][,\s]+([,\s]?(-?((\d+(\.\d+)?)|(\.\d+)))){2})+)|(s(\s?-?((\d+(\.\d+)?)|(\.\d+)))([,\s]?(-?((\d+(\.\d+)?)|(\.\d+)))){3})|z/gi;
const dataElements = dataString.match(validCommand);
if (!dataElements) {
return null;
}
const result: Array<SVGPathCommand> = [];
var i = 0;
while (i < dataElements.length) {
const token = dataElements[i];
// Ctwheels comment was really useful here
// https://stackoverflow.com/questions/47801455/what-is-the-regex-that-properly-splits-svg-d-attributes-into-tokens
const dataRaw = token.match(/-?(?:\d*\.)?\d+|[a-z]/gi);
if (dataRaw) {
result.push(dataRaw as SVGPathCommand);
} else {
// throw Error?
}
i++;
}
return result;
}; // END splitSVGPathData