UNPKG

svg-parse-path-normalized

Version:

Parse svg path data from string and normalize it to calculable value arrays

260 lines (206 loc) 7.7 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Parse pathdata</title> <style> body { font-family: sans-serif; } svg { width: 100%; overflow: visible; border: 1px solid #ccc; } .grd { display: grid; grid-template-columns: 1fr 1fr; gap: 2em; height: 95vh; } .col { height: 100%; display: flex; flex-direction: column; gap: 0; justify-content: flex-start; } .col>* { margin-top: 0; margin-bottom: 1rem; } textarea { width: 100%; display: block; min-height: 10em; flex: 1 1 auto; resize: vertical; } input {} input[type="range"] { width: 100%; display: block; } input[type="checkbox"] { margin-right: 0.5em; } label { display: inline-block; line-height: 1.4em; margin: 0; margin-right: 0.5em; } code { background: #eee; display: block; padding: 0.5em; } #pErrors { font-weight: 700; color: red; } input[type="number"] { width: 4em; } </style> </head> <body> <div class="grd"> <div class="col"> <h1>Parse pathData normalized</h1> <p>Standalone pathData parser – including normalization options: </p> <p>See <a href="https://github.com/herrstrietzel/svg-parse-path-normalized">github repository</a></p> <details> <summary>Usage example</summary> <pre> <code> let options = { toAbsolute: true, toLonghands: true, arcToCubic:true, quadraticToCubic: true, debug: false, decimals: -1 } let d = "M 0 0 ... z" let pathDataAbs = parsepathDataNormalized(d, options) </code> </pre> </details> <fieldset> <legend>Options</legend> <label><input class="inputs" type="checkbox" id="inputtoAbsolute" checked>toAbsolute</label> <label><input class="inputs" type="checkbox" id="inputtoLonghands" checked>toLonghands</label> <label><input class="inputs" type="checkbox" id="inputarcToCubic" checked>arcToCubic</label> <label><input class="inputs" type="checkbox" id="inputquadraticToCubic" checked>quadraticToCubic</label><br> <label><input class="inputs" type="checkbox" id="inputlineToCubic">lines to cubic (for morphing animations)</label> <label><input class="inputs" type="checkbox" id="inputdebug" checked>debug (shows errors in console)</label> <br> <label>Round (-1 = no rounding) <input class="inputs" type="number" value="3" min="-1" id="inputDecimals"></label><br> <label><input class="inputs" type="checkbox" id="inputMinify">minify d output</label> </fieldset> </p> <p id="pErrors"></p> <h3>PathData string input</h3> <textarea id="svgInput"> M+50 0 a50 50 0 110 100 50 50 0 110-100 m0 30a20 20 0 110 40 20 20 0 110-40m0-10q12.42 0 21.21 8.79t8.79 21.21-8.79 21.21-21.21 8.79-21.21-8.79-8.79-21.21 8.79-21.21 21.21-8.79m-40-20a5 5 0 110 10 5 5 0 110-10m80 0a5 5 0 110 10 5 5 0 110-10m0 2.5a2.5 2.5 0 110 5 2.5 2.5 0 110-5m-45 42.5h10v10h-10zm-5-5h20v20h-20zm10-30c22.07 0 40 17.93 40 40 s-17.93 40-40 40-40-17.93-40-40 17.93-40 40-40 </textarea> <h3>PathData out</h3> <textarea id="svgOut"> </textarea> <h3>PathData string output</h3> <textarea id="svgDOut"> </textarea> </div> <div class="col"> <svg id="svg" viewBox="0 0 100 100"> <path fill="none" stroke="black" d=" " /> <path id="path2" fill="none" stroke="green" stroke-width="0.5" /> </svg> </div> </div> <script src="../js/pathDataParseNormalized.js"></script> <script src="../js/pathDataConvert.js"></script> <script> /** * 1. simple parsing */ let pathData = parsePathDataNormalized("m 0 0 .5.5.5.5a 5 10 45 1040 20") //stringify to pathdata d string let minify = false; //let dNew = pathDataToD(pathData, 1, minify); let dNew = pathData.toD(1, minify); console.log(pathData); console.log(dNew); /** * 3. Quick convert */ let pathDataCon = pathData.convert({arcToCubic:true, toRelative:true, decimals:0}) /** * 4. Convert to verbose format */ let pathDataV = parsePathDataNormalized("m 0 0 .5.5.5.5a 5 10 45 1040 20", {normalize:false}) let pVerbose = JSON.stringify(pathDataToVerbose(pathDataV), null) console.log(pVerbose); /** * 2. parsing with normalization options */ // init – otherwise use pathDataBB.getBBoxFromD() let path = document.querySelector("path"); let svg = path.closest("svg"); let d = svgInput.value; updateSVG(); svgInput.addEventListener("input", (e) => { updateSVG(); }); let inputs = document.querySelectorAll(".inputs"); inputs.forEach((inp) => { inp.addEventListener("input", (e) => { updateSVG(); }); }); function updateSVG() { d = svgInput.value; path.setAttribute("d", d); let options = { toAbsolute: inputtoAbsolute.checked, toLonghands: inputtoLonghands.checked, arcToCubic: inputarcToCubic.checked, quadraticToCubic: inputquadraticToCubic.checked, lineToCubic: inputlineToCubic.checked, decimals: +inputDecimals.value, debug: inputdebug.checked }; let pathData = parsePathDataNormalized(d, options); let decimals = +inputDecimals.value; let minify = inputMinify.checked; let dN = pathDataToD(pathData, decimals, minify); let errors = pathData[0].errors ? pathData[0].errors : '' pErrors.textContent = errors path2.setAttribute("d", dN); svgOut.value = JSON.stringify(pathData, null, "").replaceAll('},', '},\n'); svgDOut.value = dN; // adjust viewBox let bb = path.getBBox(); let bbString = [bb.x, bb.y, bb.width, bb.height].join(" "); svg.setAttribute("viewBox", bbString); let { x, y, width, height } = bb; } </script> </body> </html>