Reputation: 17
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>
Upvotes: 0
Views: 883
Reputation: 28
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
});
Upvotes: 1