When you are working with CSS Animations, one thing that you would like to improvise would be to hold those animations from running on page load event and then make them run once the section is visible on the viewport which we term here as animate on scroll. You can add a lot of variations in those animations, like, tracking the scroll position and reset the animations once the content is out of viewport. But, here, we will go with the basic one. That essentially means, we will hold the pause the animation until the section is visible on viewport and then let them run.
For convenience, we will add common class name (animate) to all animation added sections and then add another class to define the animation effects. The animate class will pause the effect, that's all we can do to stop the animation using CSS. Make sure that you define animate pause and running property at the end of your CSS.
Alotting a common class name to all animation elements would keep our code short and simple as one block of codes will work for all animations.
Then, we will track the visibilty of the content section on the viewport. Once the content is visible of viewport, we will add another class to the element using jQuery and force the animation effect run at that instance.
Finally, we will need to check the visibily of the content on two events. One when the page loads, so that, all elements visible on the page without scrolling would run on page load. Then, other ones would run on page scroll when they appear on the viewport.
Lets create a function to check if a content is visible on viewport then.
function isInViewport(i) { const rect = $('.animate').get(i).getBoundingClientRect(); return (rect.top >= 0 && rect.bottom <= (window.innerHeight)); }
Here, the function isInViewport() will check if the given index of animate class is visible on the viewport.
getBoundingClientRect() method returns the left, top, right, bottom position of the element relative to the viewport along with its width and height.
We will check the position of the element from the top and bottom of the viewport. If the element has positive value, then, the function will return true else the function will return false.
Now, all we need to do is send the index value of the element we need to check and do the needful.
$(window).on('load',function () { $('.animate').each(function(i){ if(isInViewport(i)){ $('.animate').eq(i).addClass('animated'); }else{ $('.animate').eq(i).removeClass('animated'); } }) });
As mentioned earlier, we are using common class animate for all animated elements. So, all we do is run the each() loop on page load to check if the element is in the viewport and then add class animated to the specific element denoted by index number eq(i) to run the animation or remove it to stop the animation.
We will do the same on page scroll event too as shown below.
$(window).on('scroll',function () { $('.animate').each(function(i){ if(isInViewport(i)){ $('.animate').eq(i).addClass('animated'); }else{ $('.animate').eq(i).removeClass('animated'); } }) });
If you are placing your elements initially far on the right or left, make sure you add overflow hidden on the body.
Here's the CSS, added on this page for the animations.
@keyframes bounce { 0%, 20%, 53%, to { animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); transform: translateZ(0); } 40%, 43% { animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); transform: translate3d(0, -30px, 0) scaleY(1.1); } 70% { animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); transform: translate3d(0, -15px, 0) scaleY(1.05); } 80% { transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); transform: translateZ(0) scaleY(0.95); } 90% { transform: translate3d(0, -4px, 0) scaleY(1.02); } } @keyframes backInRight { 0% { transform: translateX(2000px) scale(0.7); } 80% { transform: translateX(0) scale(0.7); } to { transform: scale(1); } } @keyframes fadeInRight { 0% { opacity: 0; transform: translate3d(100%, 0, 0); } to { opacity: 1; transform: translateZ(0); } } .bounce{ animation: bounce 3s 1; } .backInRight{ animation: backInRight 3s 1; } .fadeInRight{ animation: fadeInRight 3s 1; } .animate{ animation-play-state: paused; } .animate.animated{ animation-play-state: running; } pre{ background: #222; color: #fff; padding: 10px; } body{ overflow: hidden; overflow-y: scroll; }
Leave a comment