svg / svgo

⚙️ Node.js tool for optimizing SVG files
https://svgo.dev/
MIT License
20.77k stars 1.38k forks source link

altered paths #1858

Open nschloe opened 9 months ago

nschloe commented 9 months ago

Running

svgo in.svg

on

in

gives

in-opti

This is with svgo 3.0.4.

SethFalco commented 9 months ago

Hey! Thanks for reporting the issue.

The issue is caused due to rounding. By default, SVGO reduces the precision of floating-point numbers to 5 decimal places.

In most cases, this is fine. However, in this SVG some of the numbers are super inflated, with matrixes applied that are really miniscule.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 673 205">
  <path d="M0 0L6235704.138785 2260595.537351" transform="matrix(0.0000431728,0,0,0.0000431865,60.47463,20.8221)" stroke-width="12700" stroke="black"/>
</svg>

Here is a trimmed down version of the SVG that showcases the issue. See how the path commands use numbers like 6,235,704, and then to scale it down to fit in the viewport a transform is applied using numbers like 0.0000431728. The 0.0000431728 is being rounded down to 0.00004. With numbers at this scale, this ends up making a significant difference.

For now, a workaround you can do is increase the transform precision of the convertTransform plugin. You can create the following config in the directory you're running the command in, then try again.

svgo.config.js

module.exports = {
  plugins: [
    {
      name: "preset-default",
      params: {
        overrides: {
          convertTransform: {
            transformPrecision: 10
          }
        }
      }
    }
  ]
}
nschloe commented 9 months ago

Interesting! Is there a way to disable the float clipping entirely?

SethFalco commented 9 months ago

As far as I know (reviewing documentation and the current implementation) we don't have anything to disable the rounding entirely. (Apart from disabling the plugin.)

Later, I can review if we should allow passing false to precision parameters to disable modifying the value for floating points at all, beyond trimming redundant zeros and the like.