/* home-animation.js ================= This file is manually included by the home_inc-js.php file within this themes directory if animations are not disabled. This file is only loaded on the homepage of this theme, and doesn't apply animations across the site. If you wish to apply an animation across the whole site then please do so in global-animation.js Remember that animations are theme specific, meaning this file only effects the current theme that you are animating, and not every theme across the TemplateOTS platform. See detailed documentation here:- https://docs.google.com/document/d/1n5sWQ8SIr-zjOpTv8YnOTHJapO8WdedjDfbeo-lkqMM/edit#heading=h.lmxb59mpcpe2 For detailed documentation on how things in this theme works (not animation specific) -: https://docs.google.com/document/d/1nAW00kGPRfQl4rHOzwR2mlBwuAgOZOkhLoJxjReu3eo/edit */ /* FUNCTIONS ========= fOnScroll() - Called when the user scrolls, handles scroll ticks fOnScrollUpdate() - Called when a tick has been approved, handles all logic fRequestScrollTick() - Invokes the fOnScrollUpdate() */ // Self invoke function (to prevent global leaks) (function () { /* VARIABLE DECLORATION FOR SCROLLING STUFF ======================================== */ // Store the last known scroll position var nLastKnownScrollPosition = 0; // Store the value if frame is ticking or not var bScrollTicking = false; // Store the object var oDocument = $(document); // Store the slideshow object var oSlideshow = false; // Store the delay var nDelay = 0; // Store if the producs animation has been triggered or not var bHasProductsAnimationBeenTriggered = false; // Store if we should animate the slideshow or not var bShouldAnimateSlideshow = true; /* On Document Loaded ================== Called by Jquery event handler when the document is ready (When content has been loaded) */ $( document ).ready( function() { // Store the navigation bar delay var nNavBarDelay = 300; // Loop over all nav bar items $(".nav-item").each( function( index ) { // Store the nav item var oNavItem = $(this); // Set timeout (we have to store in a variable to get the correct reference to oNavItem, just how js works unfortunatly (single threaded goodness) ) var oTimeout = setTimeout( function() { // Set the opacity of this item TweenMax.to( oNavItem, { opacity : 1, ease : Power2.easeIn }, 0.35); }, nNavBarDelay); // Increment delay by 75ms; nNavBarDelay += 50; }); // Loop over all nav bar icons $(".nav-bar-icon").each( function( index ) { // Store the nav icon var oNavIcon = $(this); // Set timeout (we have to store in a variable to get the correct reference to oNavItem, just how js works unfortunatly (single threaded goodness) ) var oTimeout = setTimeout( function() { // Set the opacity of this item oNavIcon.css( { opacity : 1 } ); }, nNavBarDelay); // Increment delay by 75ms; nNavBarDelay += 75; }); // Animate the logo container (fade it in) setTimeout(function () { // Fade logo in $(".logo-container").css ( { opacity : 1 } ); }, 250); // Fade the header in $(".header").css ( { opacity : 1 } ); // Assign the slideshow element oSlideshow = $(".slideshow-container"); // If we have the slideshow enabled if( oSlideshow.length ) { // Fade the slideshow in TweenMax.to( oSlideshow, { opacity : 1, ease : Power2.easeIn }, 0.5); } // If the about content and products are both disabled, we don't want an animation for the slideshow scroll if( $(".about-content" ).length == 0 && $(".products").length == 0 ) { // Store if we should animate the slideshow or not bShouldAnimateSlideshow = false; } // If we are on mobile, thne we also shouldn't animate the slideshow if( $(window).width() < 911 ) { // Store if we should animate the slideshow or not bShouldAnimateSlideshow = false; } // Call scroll update to set inital values fOnScroll(); // On document scroll oDocument.scroll(function() { // Call on scroll fOnScroll(); }); // If we have a products section if( $(".products").length ) { // Loop through every product $(".product").each( function() { // Set the inital state of the product TweenMax.set( $(this), { opacity : 0 } ); }); } }); /* fOnScroll() =========== Simply store the scroll position and request an animation frame. */ function fOnScroll() { // Store the last known scroll position nLastKnownScrollPosition = oDocument.scrollTop(); // Fix safari bug where you can scroll upwards due to the scroll top offset safari allows if( nLastKnownScrollPosition < 0 ) { // Clamp the last known scroll position nLastKnownScrollPosition = 0; } // Request a scroll animation tick fRequestScrollTick(); } /* fOnScrollUpdate() ================ This function is called by requestAnimationFrame when we log a tick. */ function fOnScrollUpdate() { // If the scroll position is less than the window.height if( nLastKnownScrollPosition <= $(window).height() ) { // Work out the height position we need var nSlideshowHeight = 100 - ( $(window).scrollTop() / ($(window).height() * 10) ) * 100; // If the slideshow is greater than 50 if( nSlideshowHeight > 50 ) { // If we have a slideshow if( oSlideshow.length && bShouldAnimateSlideshow ) { // Then we can tween the slideshow's height TweenMax.to(oSlideshow, 0.05, { height : nSlideshowHeight + "%", ease : Linear.easeNone } ); // Also tween the height for the overlay + opaicty for effect TweenMax.to($(".slideshow-overlay"), 0.05, { height : nSlideshowHeight + "%", opacity : $(window).scrollTop() / ( $(window).height() / 2 ), ease : Linear.easeNone } ); } // If the about contact exists if( $(".about-content" ).length ) { // Work out the about section positions var nAboutSectionPosition = ( $(window).width() > 991 && $(".about-content").length ) ? -( $(window).scrollTop() / ($(window).height() * 5) ) * 100 : 0; // Tween the right section offset TweenMax.to($(".right-section"), 0.3, { x : nAboutSectionPosition + "%", ease : Linear.easeNone } ); // Tween the left section offset (same amount just inverted) TweenMax.to($(".left-section"), 0.3, { x : -nAboutSectionPosition + "%", ease : Linear.easeNone } ); } } // If we have the seperator if( $(".carsington-seperator").length ) { // Tween the offset and opacity of the seperator TweenMax.to($(".carsington-seperator"), 0.05, { x : 400, opacity : 0, ease : Power2.easeIn } ); } } // If the scroll position has passed the window height else { // If we have the seperator if( $(".carsington-seperator").length ) { // Store the offset of the seperator var nSeperatorOffset = ( $(".left-section").height() + $(".right-section").height() - ($(window).height() / 4) ) - ( $(window).scrollTop() - ( $(window).height() ) ); // Store the opacity of the seperator var nSeperatorOpacity = (nLastKnownScrollPosition - $(window).height() ) / ($(window).height() / 1.5); // If the offset is less than 0 if( nSeperatorOffset < 0 ) { // Clamp it to 0 nSeperatorOffset = 0; } // Tween the offset and opacity of the seperator TweenMax.to($(".carsington-seperator"), 0.05, { x : nSeperatorOffset, opacity : nSeperatorOpacity, ease : Power2.easeIn } ); } } // If we have a products section if( $(".products").length ) { // Store the products offet in the y axis var nProductsOffet = $(".products").offset().top; // Store where the bottom of the screen is var nBottomOfScreenPosition = $(window).scrollTop() + $(window).innerHeight(); // If the products section is in view and if the products animation has not been triggered if( nBottomOfScreenPosition > nProductsOffet && !bHasProductsAnimationBeenTriggered ) { // Store the count var nCount = 0; // Loop through every product $(".product").each( function() { // If this product doesn't have the data-attribute if( !$(this).data( "animation-triggered" ) ) { // If the product is in view if( nBottomOfScreenPosition > $(this).offset().top && $(window).scrollTop() < $(this).offset().top + $(this).outerHeight() ) { // If we are on desktop if( $(window).width() > 991 ) { // Set the inital state of the product TweenMax.set( $(this), { opacity : 0, scale : 0.9 } ); } // If we are not on desktop else { // Set the inital state of the product TweenMax.set( $(this), { opacity : 0 } ); } // Lerp the product in TweenMax.to( $(this), 1.3, { opacity : 1, scale : 1, delay : nDelay, ease: "back.inOut(1.7)" } ); // Increase the delay nDelay += 0.1; // Store that the animation has been triggered $(this).data( "animation-triggered", "1"); // Incremenet the counter nCount++; } } // Increment the counter else { // Increment the counter nCount++; } }); // Reset the delay nDelay = 0; // If we have executed the animation on every product, the loop is no longer needed if( $(".product").length == nCount ) { // Set the trigger to true bHasProductsAnimationBeenTriggered = true; } } } // Set it so we aren't ticking anymore bScrollTicking = false; } /* fRequestScrollTick() ==================== Simply requests an animation tick, all this function does is check if we have already called a tick, and if not then call a tick. simple. */ function fRequestScrollTick() { // If we aren't currently ticking if(!bScrollTicking) { // Prepare the request animation for the next frame requestAnimationFrame(fOnScrollUpdate); // Set the ticking to be true! bScrollTicking = true; } } }());