Jumping animated element when scroll is back to the top and class is removed

Viewed 120

I have an issue regarding animation. So I made this simple animation that is supposed to activate on a scroll and move the logo to the left and swing it a bit. Everything is fine but when I scroll back to the top the element jump to its previous position and it doesn't look natural. Is there any way that I could make the transition smoother?

Before when I made a simple transform just with these properties:

.sticky {
    transition: all .3s ease-in .1s;
    transform: translateX(-70px) rotate(25deg);
}

It wasn't jumping back but when I added keyframes and made animation more complex the problem occurred.

#logo {
    max-width: 50px;
    display: inline-block;
    position: fixed;
    transition: all .3s ease-in-out .5s;
    -webkit-transform-origin: 50% 50% 0;        
    transform-origin: 50% 50% 0;
    font-size:50px;
}

.sticky {
    transition: all .3s ease-in-out .5s;    
    -webkit-animation: swinging 4.5s ease-in-out both;
    animation: swinging 4.5s ease-in-out both;
    animation-fill-mode: both;       
}

@keyframes swinging {
    0% {transform: translateX(0px) rotate(-10deg);}
    20% {transform: translateX(-70px) rotate(10deg);}
    40% {transform: translateX(-60px) rotate(-5deg);}
    60% {transform: translateX(-70px) rotate(5deg);}
    80% {transform: translateX(-70px) rotate(-2deg);}
    100% {transform: translateX(-70px) rotate(0deg);}
}

JavaScript

window.onscroll = function() {
    myFunction()
};
        
var header = document.getElementById("logo");
var sticky = header.offsetTop;
        
function myFunction() {
    if (window.pageYOffset > sticky) {        
        header.classList.add("sticky");
    } else {  
        header.classList.remove("sticky");
    }
}

I will be very thankful for any solution and help. Here is a simple codepen that more or less shows the issue: https://codepen.io/tonysnufkin/pen/jOVXbpP

1 Answers

One solution would be to provide a 'counter-animation' which animates the element from the final position of swinging back to initial position. For example:

@keyframes unswing {
  0% {transform: translateX(-70px)} /* final position of swinging transform */
  100% {transform: translateX(0)} /* original position */
}

This has the side effect of animating in on initial page load. If this is not desirable, consider attaching the animation to a class which you can toggle with javascript when you remove sticky.

Updated Codepen

Related