0

I'm using several CSS animations on a design. My problem is these animations get triggered only once, when the page first loads. I need them to be triggered every time the user scrolls by them, whether going up or down the page, and nothing seems to be responding to my Javascript. I have a colored box that slides in left, and body copy + header that will fade in from the bottom. I want these two separate animations to be slightly offset in duration, with the text coming in after the box has slid in about half way. I tried nesting these divs into one so that they all are revealed at the same point on scroll, and I've also tried treating them as separate entities within JavaScript.

$(window).scroll(function() {
  $('#Featuring_Animated').each(function() {
    var imagePos = $(this).offset().top;
    var imageHeight = $(this).height();
    var topOfWindow = $(window).scrollTop();

    if (imagePos < topOfWindow + imageHeight && imagePos + imageHeight > topOfWindow) {
      $(this).addClass("slide-in-left");
    } else {
      $(this).removeClass("slide-in-left");
    }
  });
});

$('.element-to-hide').css('visibility', 'hidden');
/**
 * ----------------------------------------
 * animation slide-in-left
 * ----------------------------------------
 */

.Featuring_Textbox {
  -webkit-animation: slide-in-left .5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
  animation: slide-in-left .5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
  visibility: visible !important;
}

@-webkit-keyframes slide-in-left {
  0% {
    -webkit-transform: translateX(-1000px);
    transform: translateX(-1000px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateX(0);
    transform: translateX(0);
    opacity: 1;
  }
}


/**
 * ----------------------------------------
 * animation fade-in-bottom left sections
 * ----------------------------------------
 */

#Featuring_About,
#Featuring_Heading {
  -webkit-animation: fade-in-bottom 0.6s cubic-bezier(0.390, 0.575, 0.565, 1.000) .3s both;
  animation: fade-in-bottom 0.6s cubic-bezier(0.390, 0.575, 0.565, 1.000) .3s both;
  visibility: visible !important;
}

@-webkit-keyframes fade-in-bottom {
  0% {
    -webkit-transform: translateY(50px);
    transform: translateY(50px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    opacity: 1;
  }
}


/**
 * ----------------------------------------
 * animation fade-in-bottom left sections
 * ----------------------------------------
 */

#Featuring_Textbox {
  opacity: 0.9;
  fill: #3B4A5C;
}

.Featuring_Textbox {
  position: absolute;
  overflow: visible;
  width: 640px;
  height: 552px;
  left: 0px;
  top: 0px;
}

#Featuring_About {
  left: 74px;
  top: 238px;
  position: absolute;
  text-align: left;
  font-size: 18px;
  color: white;
}

#Featuring_Heading {
  left: 74px;
  top: 143px;
  position: absolute;
  text-align: left;
  font-size: 40px;
  color: white;
}
<html>
<head>
<script language="JavaScript" type="text/javascript" src="colocation.js"></script>
</head>

<div class="Featuring_Animated element-to-hide" style="visibility:visible;">
  <svg class="Featuring_Textbox">
            <rect id="Featuring_Textbox" rx="0" ry="0" x="0" y="0" width="640" height="552"></rect>
         </svg>
  <div id="Featuring_About">
    <span>Sample Text</span>
  </div>
  <div id="Featuring_Heading">
    <span>FEATURING</span>
  </div>
</div>

</html>

1 Answer 1

1

If you dont want a library you can do this. (cobbled together from other contributors,ty) You can add different effects to different selectors. Animation triggers once when set percentage of element is visible (isInViewport - 2nd parameter, currently set to 35%). Triggered only once.

//every element needs to have a "hidden" class, ie. "visability:hidden" if starting state is hidden (fad-in effects and similar)

var elemList = {elements:[ //add elements and animations here
    {elem:"#home-description", animation:"element-animation"},
    {elem:".nav-item",animation:"slide-in-top"}
]};

var isInViewport = function(el, percentVisible) {
    let
    rect = el.getBoundingClientRect(),
        windowHeight = (window.innerHeight || document.documentElement.clientHeight);

    return !(
        Math.floor(100 - (((rect.top >= 0 ? 0 : rect.top) / +-(rect.height / 1)) * 100)) < percentVisible ||
        Math.floor(100 - ((rect.bottom - windowHeight) / rect.height) * 100) < percentVisible
    )
};



function check(){
    var eArray = elemList.elements;

    if (eArray.length >= 1){  
        eArray.forEach( function(e,i){

            if (e.elem){ //check if empty
                let el = document.querySelectorAll(e.elem);

                if (el.length >= 1){

                    el.forEach( function(x,y){
                        if (isInViewport(x,35)){
                            x.classList.remove("hidden") //remove this if element should be visible
                            x.classList.add(e.animation)
                            eArray.splice(i, 1)

                        }
                    })
                }
            }
        })
    }
}


window.addEventListener('load', function () {
    check();
    document.addEventListener('scroll', function () {
        check();
    })
}, {
    passive: true
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.