Jump to content
Search Community

Awful Morphing due to (scientific?) float notation

Jeff S test
Moderator Tag

Go to solution Solved by GreenSock,

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Hello,

 

The following code pen example shows unwanted morphing behavior:

 

I played around and realized that the underlying issue is caused by the value in the paths 1e-5 and 10e-6.

 

The following changes:

 

Change 1e-5 to 0 in path1
Change 10e-6 to 0 in path2
 
can be seen in this codepen example:

See the Pen bEmWOp by anon (@anon) on CodePen

 
And this is the expected behavior.
 
I am using Inkscape to create the svgs.  I played around with the precision and saving as an Inkscape SVG, Plain SVG and Optimized SVG, but I didn't have any luck getting rid of the precision whilst preserving the shapes.
 
A quick Google search on how to handle numbers in that notation turned up this stackoverflow:
 
Would it be possible to have the MorphSVG plugin filter the numbers in that way?  Could I get an unminified copy to make the adjustment myself?  Or can anybody offer some other work around advice.
 
Thanks!

See the Pen YwJZBe by anon (@anon) on CodePen

  • Like 1
Link to comment
Share on other sites

Hi Jeff, 

 

Welcome to the forums.

 

Sorry to hear you ran into some issues. I'll have to get back to you regarding what can be done in MorphSVG to fix these things after we look into it.

 

FWIW I sent your svg through SVGOMG (making sure to NOT clean IDs) and it spit back an SVG that seems to work fine.

 

http://codepen.io/GreenSock/pen/GoYvyx

 

Its a great resource if your app of choice is outputting not-so-good code. 

 

--

 

Since you are a Shockingly Green member you should be able to go to your account page, download your bonus zip and get an uncompressed version of all of GSAP including MorphSVG if you want to peek at the code.

 

src / uncompressed / plugins : http://prntscr.com/9zm0dx

 

Let me know if you have any problems.

  • Like 4
Link to comment
Share on other sites

Interesting - I've never seen an authoring tool spit out scientific notation like that. Carl's SVGOMG is a good one, or you could clean out the scientific notation yourself using this logic: 

function clean(selectionText) {
    var e = document.querySelector(selectionText);    
    e.setAttribute("d", e.getAttribute("d").replace(/\d+e[\-\+]\d+/ig, function(m) {
         var n = +m; return (n < 0.0001 && n > -0.0001) ? 0 : m;
    });
}
clean("#path1");
clean("#path2");

But I've added that to the upcoming release of MorphSVGPlugin 0.8.3 which you can preview on codepen using this URL: https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/MorphSVGPlugin.min.js - does that work well for you? 

  • Like 3
Link to comment
Share on other sites

Thank you to Jack and Carl.

 

I did play around with SVGOMG before I posted.  But basically, I want to morph one SVG shape to another by saving them in separate files which could potentially lead to thousands of SVG files.  So adding a step to resave the files to filter them into good form would be tedious.

 

I have taken Jack's code and applied it in my own Javascript class that loads SVGs.  You saved me writing the regex Jack so thank you very much for that!

 

Thanks for the great libraries and great support.  I am very happy with my purchase.

  • Like 2
Link to comment
Share on other sites

I had to make one minor adjustment to the regex:

/\d+e[\-\+]\d+/ig 

needs to be

/(\d\.)?\d+e[\-\+]\d+/ig

This is because sometimes the scientific notation was taking the form 2.6e-4.  Hope you can add this in to the next release.

 

Thanks Jack!

Link to comment
Share on other sites

My intention with the new regex was to  mean that sometimes the scientific notation will take on the form 2.6e-4 but other times it may take be 6e-4.  So the integer followed by the decimal point may or may not exist.

 

But rather than close this off right now, I am going to do some more testing.  I will provide a large list of values that are getting replaced so that we can examine them for an exhaustive and minified regex.

Link to comment
Share on other sites

  • Solution

That is indeed better, Blake, thanks. Is it not necessary to escape the "+" symbol though? And if we're adding "ig" at the end, there's no need to specify both "e" and "E" since it's case-insensitive, right? So perhaps it should be:

/[\-\+]?\d*\.?\d+e[\-\+]?\d+/ig

By the way, I had never seen that regex101.com tool. Amazing!

  • Like 1
Link to comment
Share on other sites

A very helpful tool! I hate trying to figure them out.

 

I went through several iterations, so I initially had [eE] because I wasn't ignoring the case. Now I'm wondering if it's slower to ignore the case.

 

About escaping the "+", I don't think it matters in a character class. It looks like you don't even have to escape the "-" as long as nothing follows it. [+-] is showing up as a literal.

/[+-]?\d*\.?\d+e[+-]?\d+/ig

https://regex101.com/r/nC0uP2/8

  • Like 1
Link to comment
Share on other sites

It was working without the beginning +/- because it was only replacing the value after.   I do think the +/- at the beginning does make it more readable.

 

From the values I saw, in my example (Inkscpae generated svgs), there were never any + signs, but that is not to say some other program wouldn't.  I think this is good.

 

I think Jack might be right about the escaping because you can do stuff like [a-z] in the [] and that means a to z.  If you wanted to include the hyphen I think you would need to use [a-z\-].

 

Also, I just remembered Jack, in the original code I made it return n not m.  So this:

function clean(selectionText) {
    var e = document.querySelector(selectionText);    
    e.setAttribute("d", e.getAttribute("d").replace(/\d+e[\-\+]\d+/ig, function(m) {
         var n = +m; return (n < 0.0001 && n > -0.0001) ? 0 : m;
    });
}

became 

function clean(selectionText) {
    var e = document.querySelector(selectionText);    
    e.setAttribute("d", e.getAttribute("d").replace(/\d+e[\-\+]\d+/ig, function(m) {
         var n = +m; return (n < 0.0001 && n > -0.0001) ? 0 : n;
    });
}

Otherwise it was just giving back the scientific notation.  Not sure if you used that exact code in the library or not, but just a heads up.

 

So this is what I have now.

function clean(selectionText) {
    var e = document.querySelector(selectionText);    
    e.setAttribute("d", e.getAttribute("d").replace(/[\-\+]?\d*\.?\d+e[\-\+]?\d+/ig, function(m) {
         var n = +m; return (n < 0.0001 && n > -0.0001) ? 0 : n;
    });
}
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...