Jump to content
Search Community

Closing nav animation not working on ie and iphone 6 (maybe other older browser))

romain.gr test
Moderator Tag

Recommended Posts

Hi,

 

I'm trying to do a simple navigation using gsap and it works greats, but on some browser I have a little issue, let me explain,

 

I have 2 different animations,

 

One to open the navigation :

- Animating the clip-path value

- then a fade-in stagger on the navigation items

 

and one to close the navigation :

- The whole navigation block fade-out then display not.

 

Here is the code but you can obviously have a look at the codepen :

 

// Nav

function restartOpenNav(){
    openNav.restart().pause();
}

function restartCloseNav(){
    closeNav.restart().pause();
}

var navIsClosed = true;
var openNav = gsap.timeline({paused: true, onComplete: restartCloseNav});
var closeNav = gsap.timeline({paused: true, onComplete: restartOpenNav});

openNav .set('.main-nav', {autoAlpha: 1, display: 'flex'})
        .fromTo('.main-nav', 1.5, 
        {clipPath:'polygon(0% 0%, 100% 0%, 100% 100%, 100% 0%)'}, 
        {clipPath:'polygon(0% 0%, 0% 100%, 100% 100%, 100% 0%)', ease: Expo.easeInOut})
        .from('.main-nav li', 1, {rotation: '2deg', autoAlpha: 0, y: '20px', stagger: .1, ease: Expo.easeOut}, '-=1');                     

closeNav.to('.main-nav', 1, {autoAlpha: 0, display: 'none'});

$('.trig-nav').on('click', function(e){
    e.preventDefault;

    if(navIsClosed){
        navIsClosed = false;
        //$(this).addClass('trig-nav--is-open');
        openNav.play();
        $('body').css('height', '100vh').css('overflow', 'hidden');
        //console.log('open Nav');
    } else if (!navIsClosed && !openNav.isActive()) {
        navIsClosed = true;
        //$(this).removeClass('trig-nav--is-open').blur();
        closeNav.play();
        $('body').attr('style', '');
        //console.log('close Nav');
    }
    
});

$('.close-nav').on('click', function(e){
    e.preventDefault;
    
    navIsClosed = true;
    // $(this).removeClass('trig-nav--is-open').blur();
    closeNav.play();
    $('body').attr('style', '');
    // console.log('close Nav');
});

As you can see onComplete of the openNav the closeNav animation is restarted same when the closeNav is restarted.

 

All works great except on IE11 and Safari IOS Iphone6 (at least those 2, maybe on other browsers), when the navigation in closed (the whole block fades out) and the close animation is finished the white background reappear suddently without the items, I have no ideas why it does that. Once again it works as expected on modern browser but not IE11.

 

Did I miss something? If anyone has the occasion to try the demo on IE11 or Safari Ios on iphone 6 and can spot the problem it would be great.

 

Thank you

See the Pen vWMRwRewGmqr by romaingranai (@romaingranai) on CodePen

Link to comment
Share on other sites

I don't think it's related to clip-path as the whole nav block is set to display none after the close nav animation is finished, so even if it has clip-path on it, it's display none, clip-path shouldn't interfer with it as it's in display none, but maybe I'm doing a mistake thinking that. The problem is that 'opacity: 1', 'visibility: visible' and 'display: flex', are re-setted to the nav when the close nav animation is finished, I think the problem is in the onComplete callback.  Anyway when clip-path is unselected in the dev console, the nav is still showing.

 

I had a closer look and it seems that 

closeNav.to('.main-nav', 1, {autoAlpha: 0, display: 'none'});

Doesn't really work as it fade-out then put back again opacity: 1. I'm not really sur what's happening. Could you just have a quick look if it work as it should on modern browser. I'm getting confused now...

Link to comment
Share on other sites

I see what you mean. I can recreate it on an iPhone 10.

 

I would try to avoid using two separate timelines to animate the same elements. I think it's much cleaner only using one.

 

With that being said, there does seem to be a minor bug here where a .set() at the start of a timeline is called when the timeline repeats even if the timeline is paused. Adding a small offset fixes the issue. We'll get the bug fixed in the next version release.

See the Pen ExVmqoN?editors=0010 by GreenSock (@GreenSock) on CodePen

 

Link to comment
Share on other sites

Hi Zach,

 

Thank you, to be honest I find your code less readable or clear, I really don't understand how the closing nav part works.

What does addPause() do if you already paused the animation when you set it (paused: true), then why repeat: -1?

I don't find that very explicit, how do you make the animation closed?

 

Here

 

gsap.utils.toArray('.trig-nav, .close-nav').forEach(function(btn) {
    btn.addEventListener("click", function(e) {
        e.preventDefault;

        if(!navTL.isActive()) {
            navTL.play();
        }
    });
});

Where does it say "play the animation till the .addPause" then on clicking on the close btn, go to the end of the timeline?  It's not clear.

Plus I'm unable the play the animation more than once, when the nav is closed and you click on the '.trig-nav' nothing happens.

 

Could you confirm that just adding a small offset fixes the problem on my codepen?

 

Thank you ;)

Link to comment
Share on other sites

Let me explain the basic approach:

  • Setup a timeline that animates between all of your states. 
  • Add a pause before the start of the animations going to a particular state. So in this case, add a pause at the start and before the fade out. Alternatively you could add the pause after each section, it doesn't matter. The trick is to just have the timeline pause once a state has been reached.
  • Add repeat: -1 so that any time the timeline finishes, it starts over again.

The reason I set it up that way is so you can just call .play() on the timeline at any point and it will go to the next stopping point no matter where the playhead is. So you don't have to do any management of "play this timeline at this point, but play this other timeline if this is true".  You don't even need the check to see if it's active or not, I just kept that in there because I thought it might help with your understanding.

 

54 minutes ago, romain.gr said:

What does addPause() do if you already paused the animation when you set it (paused: true), then why repeat: -1?

The addPause at the start is for future repeats of the animation. 

 

Here's the same thing but more prim and proper. It makes use of functions that return timelines to keep the structure more clean. For more information about that, check out my article on animating efficiently under "Modularize your animations" (though the whole thing is worth reading).

See the Pen GRpEZyV by GreenSock (@GreenSock) on CodePen

 

Does that help?

Link to comment
Share on other sites

Hi Zach, 

 

yep it makes sense, I understand a bit better the different steps,  but not your new codepen, first I need to digest the first option, I think I will avoid the second version as it does the exact same thing than the first, it's adding confusion more than help :D.

 

For the first option it still works only once. I'm still unable to play more than once the timeline.

 

Thank you

Link to comment
Share on other sites

12 minutes ago, romain.gr said:

For the first option it still works only once. I'm still unable to play more than once the timeline.

My first demo worked before but now has the behavior that you described. Apparently @GreenSock has been working on the bug and updated the beta file that I was referencing in that pen :) 

 

He says that he's still working on the core issue. So stay tuned for a fix.

Link to comment
Share on other sites

Sorry about any confusion there. I didn't update the beta file at all today until just now. The reason Zach thought he had a workaround was simply due to the fact that the issue only shows up in certain scenarios that are very time-dependent. The playhead needs to land in a very small window in a certain way, and things must get fired in a particular order. So it would look intermittent.

 

I've never seen someone do an addPause() at the very beginning of a repeating timeline, and that posed a bit of a logical challenge because technically the very start is identical to the very end (the wrapping point). Think of it like a circle, where zero degrees is at exactly the same spot as 360 degrees. But I worked on it all day and I believe I've figured out a solution that I'll put in the next release which you can preview at https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/gsap-latest-beta.min.js

 

Please let me know if that works well for you. 

  • Like 1
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...