diff --git a/lib/path.js b/lib/path.js index f37f12ea2..d0854f996 100644 --- a/lib/path.js +++ b/lib/path.js @@ -228,16 +228,29 @@ const stringifyNumber = ({ number, precision }) => { // elliptical arc large-arc and sweep flags are rendered with spaces // because many non-browser environments are not able to parse such paths -const stringifyArgs = ({ args, precision }) => { +const stringifyArgs = ({ + command, + args, + precision, + disableSpaceAfterFlags, +}) => { let result = ''; let prev; for (let i = 0; i < args.length; i += 1) { const number = args[i]; const numberString = stringifyNumber({ number, precision }); - // avoid space before first and negative numbers - if (i === 0 || numberString.startsWith('-')) { + if ( + disableSpaceAfterFlags && + (command === 'A' || command === 'a') && + (i === 4 || i === 5) + ) { + result += numberString; + } else if (i === 0 || numberString.startsWith('-')) { + // avoid space before first and negative numbers result += numberString; } else if (prev.includes('.') && numberString.startsWith('.')) { + // remove space before decimal with zero whole + // only when previous number is also decimal result += numberString; } else { result += ` ${numberString}`; @@ -247,7 +260,7 @@ const stringifyArgs = ({ args, precision }) => { return result; }; -const stringifyPathData = ({ pathData, precision }) => { +const stringifyPathData = ({ pathData, precision, disableSpaceAfterFlags }) => { // combine sequence of the same commands let combined = []; for (let i = 0; i < pathData.length; i += 1) { @@ -281,7 +294,9 @@ const stringifyPathData = ({ pathData, precision }) => { } let result = ''; for (const { command, args } of combined) { - result += command + stringifyArgs({ args, precision }); + result += + command + + stringifyArgs({ command, args, precision, disableSpaceAfterFlags }); } return result; }; diff --git a/lib/path.test.js b/lib/path.test.js index eca120c2b..8268a7319 100644 --- a/lib/path.test.js +++ b/lib/path.test.js @@ -63,8 +63,8 @@ describe('parse path data', () => { l 50,-25 a25,25 -30 0,1 50,-25 25,50 -30 0,1 50,-25 - 25,75 -30 0,1 50,-25 - a25,100 -30 0,1 50,-25 + 25,75 -30 01.2,-25 + a25,100 -30 0150,-25 l 50,-25 ` ) @@ -73,7 +73,7 @@ describe('parse path data', () => { { command: 'l', args: [50, -25] }, { command: 'a', args: [25, 25, -30, 0, 1, 50, -25] }, { command: 'a', args: [25, 50, -30, 0, 1, 50, -25] }, - { command: 'a', args: [25, 75, -30, 0, 1, 50, -25] }, + { command: 'a', args: [25, 75, -30, 0, 1, 0.2, -25] }, { command: 'a', args: [25, 100, -30, 0, 1, 50, -25] }, { command: 'l', args: [50, -25] }, ]); @@ -163,4 +163,23 @@ describe('stringify path data', () => { }) ).to.equal('M0-2 0 3 100 200'); }); + it('allows to avoid spaces after arc flags', () => { + const pathData = [ + { command: 'M', args: [0, 0] }, + { command: 'A', args: [50, 50, 10, 1, 0, 0.2, 20] }, + { command: 'a', args: [50, 50, 10, 1, 0, 0.2, 20] }, + ]; + expect( + stringifyPathData({ + pathData, + disableSpaceAfterFlags: false, + }) + ).to.equal('M0 0A50 50 10 1 0 .2 20a50 50 10 1 0 .2 20'); + expect( + stringifyPathData({ + pathData, + disableSpaceAfterFlags: true, + }) + ).to.equal('M0 0A50 50 10 10.2 20a50 50 10 10.2 20'); + }); }); diff --git a/plugins/_path.js b/plugins/_path.js index efb4df2ae..ff8764c7e 100644 --- a/plugins/_path.js +++ b/plugins/_path.js @@ -553,6 +553,7 @@ exports.js2path = function (path, data, params) { path.attr('d').value = stringifyPathData({ pathData, precision: params.floatPrecision, + disableSpaceAfterFlags: params.noSpaceAfterFlags, }); };