Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SVGLoader - Incorrect/mangled path rendering #20608

Closed
M-Ro opened this issue Nov 3, 2020 · 18 comments · Fixed by #21485
Closed

SVGLoader - Incorrect/mangled path rendering #20608

M-Ro opened this issue Nov 3, 2020 · 18 comments · Fixed by #21485

Comments

@M-Ro
Copy link

M-Ro commented Nov 3, 2020

Describe the bug

Hello, it appears that with SVG's which have been exported from Adobe XD, SVGLoader fails to convert the paths reliably.

This might be the same issue as #18560

Alternatively, is there a tool/script which can convert/re-export the SVG paths into a format Three can parse?

Live example
Here is how the SVG renders as a browser element

Screenshots

Here is how the SVG appears when imported into the ThreeJS editor (https://threejs.org/editor/)

image

Platform:

  • Device: [Desktop,]
  • OS: [Windows]
  • Browser: [Chrome]
  • Three.js version: [r120.1]
@Mugen87 Mugen87 added the Loaders label Nov 3, 2020
@mrdoob
Copy link
Owner

mrdoob commented Nov 3, 2020

Can you attach the svg file here?

@M-Ro
Copy link
Author

M-Ro commented Nov 3, 2020

Can you attach the svg file here?

Apologies, I had left the SVG inlined in the JS fiddle. File has been attached below.

tooth.svg.zip

@M-Ro
Copy link
Author

M-Ro commented Nov 3, 2020

My mistake - This doesn't appear to be caused by Paths exported from XD. I was unaware SVGO 'optimizes' paths by default which changes the delimiter inside the path.

For now I can just disable path optimization in SVGO.

I've attached below a zip with 2 SVG's, the clean export from XD which Three loads fine, and the mangled one.
svgs.zip

The only difference appears to be here

Clean export (Loads Fine):

<path id="tooth-solid-export" d="M16.035,3.479A4.679,4.679,0,0,0,12.711.092,3.836,3.836,0,0,0,9.49.971a2.413,2.413,0,0,1-.379.2l1.023.658a.578.578,0,0,1-.625.972L5.877.465A3.324,3.324,0,0,0,3.463.092,4.679,4.679,0,0,0,.139,3.479a4.739,4.739,0,0,0,.777,3.99,7.51,7.51,0,0,1,1.311,3.879,38.586,38.586,0,0,0,.757,5.07l.282,1.227a1.1,1.1,0,0,0,2.139.02l1.245-5a1.479,1.479,0,0,1,2.873,0l1.245,5a1.1,1.1,0,0,0,2.139-.02l.282-1.227a38.638,38.638,0,0,0,.757-5.07,7.509,7.509,0,0,1,1.311-3.879,4.735,4.735,0,0,0,.778-3.99Z" transform="translate(0.006 -0.001)" fill="#fff"/>
vs Optimized (mangled):

<path id="tooth-solid-export" d="M16.035 3.479A4.679 4.679 0 0012.711.092 3.836 3.836 0 009.49.971a2.413 2.413 0 01-.379.2l1.023.658a.578.578 0 01-.625.972L5.877.465A3.324 3.324 0 003.463.092 4.679 4.679 0 00.139 3.479a4.739 4.739 0 00.777 3.99 7.51 7.51 0 011.311 3.879 38.586 38.586 0 00.757 5.07l.282 1.227a1.1 1.1 0 002.139.02l1.245-5a1.479 1.479 0 012.873 0l1.245 5a1.1 1.1 0 002.139-.02l.282-1.227a38.638 38.638 0 00.757-5.07 7.509 7.509 0 011.311-3.879 4.735 4.735 0 00.778-3.99z" fill="#fff"></path>

@makc
Copy link
Contributor

makc commented Nov 3, 2020

0,0,0,12 vs 0 0012 ? is this even supported by browsers

edit: it is! browsers read this just fine

@mrdoob
Copy link
Owner

mrdoob commented Nov 3, 2020

You can use https://yqnn.github.io/svg-path-editor/ to compare the d commands.

@Mugen87 Mugen87 added the Bug label Dec 22, 2020
@karimbeyrouti
Copy link
Contributor

karimbeyrouti commented Mar 18, 2021

We've hit that one too.

Wondering you have any plans to visit this bug at the moment ?

SVG:

<path d="M27.24 23.917L15.01 2.736a1.167 1.167 0 00-2.02 0L.76 23.916c-.448.778.113 1.75 1.011 1.75h24.457c.899 0 1.46-.972 1.011-1.75zM13.416 9.333h1.166v8.75h-1.166v-8.75zM14 21.583a.875.875 0 110-1.75.875.875 0 010 1.75z"></path>

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 18, 2021

Unfortunately, even the improved parseFloats() function from #21195 which landed in r126 and which is based on svg-numbers is not able to handle this use case. I guess we need another go here...

@karimbeyrouti
Copy link
Contributor

That would be amazing.

About to start looking if we can change our SVG export scripts to get it working from there.

@karimbeyrouti
Copy link
Contributor

Wow that was fast, thank you for fixing this one !

@karimbeyrouti
Copy link
Contributor

Currently going through our SVG's this is so nice / much improved thank you again.

@Mugen87 Think I have another path which is not working / with the current dev version:

<path fill-rule="evenodd" clip-rule="evenodd" d="M21 13.82l-5 2.892v5.847a8.947 8.947 0 01-4 .941 8.932 8.932 0 01-4-.94v-5.848l-5-2.893V5.162a1 1 0 01.5-.865l3.25-1.88a10.435 10.435 0 0110.5-.001l3.25 1.88a1 1 0 01.5.866v8.657zm-1.5-2.444c0-.97-.543-1.803-1.337-2.239L12.5 12.413l3.114 1.801 3.796-2.196c.054-.206.09-.418.09-.642zm-15 0c0 .224.036.437.09.642l3.796 2.196 3.114-1.801-5.663-3.276a2.551 2.551 0 00-1.337 2.24zm6 4.627l1.502 2.596L13.5 16l-3 .003z"/>

Found another one which is getting mangled on dev (as of today). Should be showing this:

SvgPathEditor

@karimbeyrouti
Copy link
Contributor

karimbeyrouti commented Mar 26, 2021

and these ones too:

<path fill-rule="evenodd" clip-rule="evenodd" d="M37.928 18.635C37.213 11.573 31.25 6.062 24 6.062c-7.262 0-13.233 5.53-13.932 12.61C5.424 20.326 2.1 24.763 2.1 29.976c0 6.628 5.372 12 12 12H34c6.627 0 12-5.372 12-12 0-5.252-3.374-9.715-8.072-11.342zM20.61 22.602a3.402 3.402 0 116.805 0V25H30v10.8H18V25h2.61v-2.398zm4.805 0V25H22.61v-2.398a1.402 1.402 0 112.805 0z"/>

<path fill-rule="evenodd" clip-rule="evenodd" d="M1 12C1 5.925 5.925 1 12 1s11 4.925 11 11-4.925 11-11 11S1 18.075 1 12zm17.039 7V5h-12v14h12zm-2-12h-8v4h8V7zm0 6h-8v4h8v-4z"/>

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 26, 2021

I tested these SVGs on dev and I see the following:

image

image

image

When opening them in Chrome, I see the same result. Are you sure you are using the latest version of SVGLoader?

@karimbeyrouti
Copy link
Contributor

Our package.json was pointing at: "three": "github:mrdoob/three.js#dev" - so I presumed it was... will double check.
Again, thank you so much for getting back so quickly...

@gpaluk
Copy link

gpaluk commented Mar 30, 2021

Hi. There seems to be an interesting edge case around the usage of the library, such that the SVGs above are displayed incorrectly when using the SVGResultPaths[] and path.toShapes(...) to build ShapeGeometry instances. This is mostly because the toShapes method requires a winding direction. This winding direction doesn't seem to be passed down with the results and therefore choosing either true or false can lead to issues when those directions change.

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 30, 2021

@gpaluk Should be fixed via #21380. Available with r127.

@gpaluk
Copy link

gpaluk commented Mar 30, 2021

@gpaluk Should be fixed via #21380. Available with r127.

This still occurs in the latest build due to the fact that the toShapes(true|false) is undetermined. Is there a way to know the winding from the SVGResultPath?

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 30, 2021

The idea is that you don't use toShapes() in context of SVGLoader anymore since you don't know the winding order of SVGResultPath. SVGLoader.createShapes() takes care of this now.

@gpaluk
Copy link

gpaluk commented Mar 31, 2021

That's great thank you. I see now that the issue was that @types don't seem to reflect the update.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants