SVGpath优化

我们的项目中有一个由另一个团队制作的JSON文件,这个文件帮助创build了具有绑定的dynamicSVG。 JSON文件的问题是它包含重复和未优化的path。

我已经决定创build一个NodeJS脚本来扫描文件中包含的path并对其进行优化。

未优化path的示例:

"paths": [ "M59245.1734326687,2320.0L59266.994415716,2320.0L59266.994415716,2320.0L59306.410931336,2320.0L59306.410931336,2320.0L59345.827446956,2320.0L59345.827446956,2320.0L59385.243962576,2320.0L59385.243962576,2320.0L59424.660478196,2320.0L59424.660478196,2320.0L59464.076993816,2320.0L59464.076993816,2320.0L59503.493509436,2320.0L59503.493509436,2320.0L59542.910025056,2320.0L59542.910025056,2320.0L59582.326540676,2320.0L59582.326540676,2320.0L59621.743056296,2320.0L59621.743056296,2320.0L59633.0477129758,2320.0L59633.0477129758,2320.0L59661.159571916,2320.0L59661.159571916,2320.0L59700.576087536,2320.0L59700.576087536,2320.0L59739.992603156,2320.0L59739.992603156,2320.0L59779.409118776,2320.0L59779.409118776,2320.0L59818.825634396,2320.0L59818.825634396,2320.0L59858.242150016,2320.0L59858.242150016,2320.0L59897.658665636,2320.0L59897.658665636,2320.0L59937.075181256,2320.0L59937.075181256,2320.0L59976.491696876,2320.0L59976.491696876,2320.0L60015.908212496,2320.0L60015.908212496,2320.0L60030.5396230941,2320.0L60030.5396230941,2320.0L60055.324728116,2320.0L60055.324728116,2320.0L60094.741243736,2320.0L60094.741243736,2320.0L60134.157759356,2320.0L60134.157759356,2320.0L60173.574274976,2320.0L60173.574274976,2320.0L60212.990790596,2320.0L60212.990790596,2320.0L60252.407306216,2320.0L60252.407306216,2320.0L60291.823821836,2320.0L60291.823821836,2320.0L60331.240337456,2320.0L60331.240337456,2320.0L60370.656853076,2320.0L60370.656853076,2320.0L60410.073368696,2320.0L60410.073368696,2320.0L60428.0157666062,2320.0M60428.0,2320.0L60428.0044472058,2319.99990189987L60428.0044472058,2319.99990189987" ] 

没有重复的path(一半的长度!):

 "paths": [ "M59245.1734326687,2320L59266.994415716,2320,59306.410931336,2320,59345.827446956,2320,59385.243962576,2320,59424.660478196,2320,59464.076993816,2320,59503.493509436,2320,59542.910025056,2320,59582.326540676,2320,59621.743056296,2320,59633.0477129758,2320,59661.159571916,2320,59700.576087536,2320,59739.992603156,2320,59779.409118776,2320,59818.825634396,2320,59858.242150016,2320,59897.658665636,2320,59937.075181256,2320,59976.491696876,2320,60015.908212496,2320,60030.5396230941,2320,60055.324728116,2320,60094.741243736,2320,60134.157759356,2320,60173.574274976,2320,60212.990790596,2320,60252.407306216,2320,60291.823821836,2320,60331.240337456,2320,60370.656853076,2320,60410.073368696,2320,60428.0157666062,2320M60428,2320L60428.0044472058,2319.99990189987" ] 

在分析结果之后,我得出一个结论,我可以简化路线以减less鞋头线。 所以我决定使用npm package simplify-path来简化每个simplify-path 。 它工作正常:

 Not simplified: [ [ [ 59245.1734326687, 2320 ] ], [ [ 59266.994415716, 2320 ], [ 59306.410931336, 2320 ], [ 59345.827446956, 2320 ], [ 59385.243962576, 2320 ], [ 59424.660478196, 2320 ], [ 59464.076993816, 2320 ], [ 59503.493509436, 2320 ], [ 59542.910025056, 2320 ], [ 59582.326540676, 2320 ], [ 59621.743056296, 2320 ], [ 59633.0477129758, 2320 ], [ 59661.159571916, 2320 ], [ 59700.576087536, 2320 ], [ 59739.992603156, 2320 ], [ 59779.409118776, 2320 ], [ 59818.825634396, 2320 ], [ 59858.242150016, 2320 ], [ 59897.658665636, 2320 ], [ 59937.075181256, 2320 ], [ 59976.491696876, 2320 ], [ 60015.908212496, 2320 ], [ 60030.5396230941, 2320 ], [ 60055.324728116, 2320 ], [ 60094.741243736, 2320 ], [ 60134.157759356, 2320 ], [ 60173.574274976, 2320 ], [ 60212.990790596, 2320 ], [ 60252.407306216, 2320 ], [ 60291.823821836, 2320 ], [ 60331.240337456, 2320 ], [ 60370.656853076, 2320 ], [ 60410.073368696, 2320 ], [ 60428.0157666062, 2320 ] ], [ [ 60428, 2320 ] ], [ [ 60428.0044472058, 2319.99990189987 ] ] ] Simplified: [ 59245.1734326687, 2320, 60428.0044472058, 2319.99990189987 ] 

我怎样才能转换回SVGpath点的简化数组? 有没有任何API?

我从简化SVGpath的代码中删除一部分(RegEx除外,代码不是来自我!):

 // Parse SVG Path to array. var commands = pathArrays[i].paths[j].split(/(?=[LMC])/); // Split the Path array into a Points array. var pointArrays = commands.map(function(d){ var pointsArray = d.slice(1, d.length).split(/[\s,-]+/); if (pointsArray[0] == '') pointsArray.shift(); var pairsArray = []; for(var i = 0; i < pointsArray.length; i += 2){ pairsArray.push([+pointsArray[i], +pointsArray[i+1]]); } return pairsArray; }); // Call simplify method from npm package. var simplifyArray = simplify(pointArrays, 10); // ==> I want to convert array of points to SVG Path <== 

雅,如果你真的没有做曲线等任何事情,那么你刚刚描述了一个多边形。 这也许可以解释为什么我在底部的非简化示例中看不到任何命令? 在这种情况下,你的任务变得非常容易,因为你不需要参与命令,只需要读取点。

如果是这样的话,你可以做一些真正简单的事情,就像这个快速PoC我扔在一起。 希望它有帮助,或者说更多详细的,我们会采取另一个刺。 我对这个挑战很感兴趣。 🙂

 var geometry = [ [ '109,141', '59.073,97.825', '9.146,54.65', '71.5,33', '133.854,11.35', '121.427,76.175' ], [ '133.989,130.188', '86.736,114.757', '47.501,145.276', '47.272,95.175', '6.275,66.815', '53.385,51.282', '67.284,3.237', '96.629,43.738', '146.216,42.404', '117.242,82.968' ], [ '8,80', '58,144', '143,49', '127,6', '60,112', '35,63' ] ], translate = 0, create = function() { for (i=0,r=geometry.length;i<r;i++) { var polygon = geometry[i].join(), colors = '#'+(Math.random()*0xFFFFFF<<0).toString(16), shape = document.createElementNS("http://www.w3.org/2000/svg", "polygon"); shape.setAttribute("points", polygon); shape.setAttribute("fill", colors); shape.setAttribute("transform", "translate(" + translate + ",0)"); translate += 150; document.getElementById("shapes").appendChild(shape); } }; create(); 
 <svg id="shapes" width="450" version="1.1" xmlns="http://www.w3.org/2000/svg" xml:space="preserve"> </svg> 

以下应该做的工作:

 path = 'M' + simplifyArray.join(',');