/* 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 */ /* FUNCTIONS ========= fAnimatePanelOneWrapper() - Animation logic for the panel one wrapper fAnimatePanelTwoWrapper() - Animation logic for the panel two wrapper fAnimateCategoiresWrapper() - Animation logic for the categories section fAnimateBlogWrapper() - Animation logic for the blog section fHasScrolledIntoView() - Checks if an element has scrolled into viewport fOnScrollUpate() - Called when the user has scrolled, must be called from fRequestScrollTick() fRequestScrollTick() - To prevent frequent scroll calls, this function limits the amount we can call fOnScrollUpate */ (function () { /* DECALRE REQUIRED VARIABLES ========================== */ // Store the banner top text var oBannerText = ""; // Store the hompage var oLandingPageBlock = ""; // Store the categories wrapper var oCategoriesWrapper = ""; // Store the blog wrapper var oBlogWrapper = ""; // Store the Blog view all column var oBlogViewAllColumn = ""; // Store the panel one wrapper var oPanelOneWrapper = ""; // Store the panel two wrapper var oPanelTwoWrapper = ""; // Store the value if frame is ticking or not var bScrollTicking = false; // Store if we've animated the categories wrapper or not var bHasAnimatedCategoriesWrapper = false; // Store if we've animated the blog wrapper or not var bHasAnimatedBlogWrapper = false; // Store if we've animated the panel 1 wrapper or not var bHasAnimatedPanelOneWrapper = false; // Store if we've animated the panel 1 wrapper or not var bHasAnimatedPanelTwoWrapper = false; /* On Document Loaded ================== Called by Jquery event handler when the document is ready (When content has been loaded) */ $( document ).ready( function() { // try store the banner top text oBannerText = $(".banner-text"); // try store the hompage banner column oLandingPageBlock = $(".homepage-banner-col"); // try store the categories wrapper if it exists oCategoriesWrapper = $("#categories-wrapper"); // try store the blog wrapper if it exists oBlogWrapper = $("#blog-container"); // try store the blog view all column oBlogViewAllColumn = $(".view-all-blog-col"); // try store the panel 1 wrapper oPanelOneWrapper = $("#info-images-wrapper"); // try store the panel 2 wrapper oPanelTwoWrapper = $("#more-info-block"); /* SET INITAL ANIMATION STATE FOR CATEGORIES ========================================= If the user has scrolled past the category wrapper on initialise, then we just sumply set the category wrapper to display instead of animating */ // If the categories wrapper exists if( oCategoriesWrapper.length ) { // If the user has scrolled past the categories when the page is loaded (Meaning they have clicked back button, or loaded from a url) if( $(window).scrollTop() >= oCategoriesWrapper.offset().top ) { // Then we don't need to do anything fancy with the categories, so lets just set their inital state oCategoriesWrapper.children().each( function() { // Store this itteration of the category var oCategory_This = $(this); // Tween set the category into position TweenMax.set( oCategory_This, { paddingTop : 0, opacity : 1 }); }); // Set the animation state to true so we don't animate it bHasAnimatedCategoriesWrapper = true; } } /* SET INITAL ANIMATION STATE FOR BLOG POSTS ========================================= If the user has scrolled past the blog wrapper on initialise, then we just sumply set the blog wrapper to display instead of animating */ // If the categories wrapper exists if( oBlogWrapper.length ) { // If the user has scrolled past the blog when the page is loaded (Meaning they have clicked back button, or loaded from a url) if( $(window).scrollTop() >= oBlogWrapper.offset().top ) { // Loop through each blog oBlogWrapper.find(".left-blog-col").each( function() { // Store this itteration of the blog var oBlog_This = $(this); // Tween the blog into position TweenMax.set( oBlog_This, { paddingTop : 0, opacity : 1 }); }); // Set the animation state to true so we don't animate it bHasAnimatedCategoriesWrapper = true; // If the blog view all column exists if( oBlogViewAllColumn.length ) { // Fade in the the view all blog entries button TweenMax.to(oBlogViewAllColumn, 0.75, { opacity : 1 }); } } } /* SET INITAL ANIMATION STATE FOR PANEL ONE ======================================== We have to do this in javascript, as we don't know if the ID for this element is used elsewhere on the site, so just to be safe we do it here. */ // If the panel one wrapper exists if( oPanelOneWrapper.length ) { // If the user is NOT scrolled into view of panel 1 if( !fHasScrolledIntoView( oPanelOneWrapper, ($(window).height() / 20) ) ) { // Set the inital state of panel 1 so we can animate it TweenMax.set( oPanelOneWrapper, { opacity : 0 }); } } /* SET INITAL ANIMATION STATE FOR PANEL TWO ======================================== We have to do this in javascript, as we don't know if the ID for this element is used elsewhere on the site, so just to be safe we do it here. */ // If the panel one wrapper exists if( oPanelTwoWrapper.length ) { // If the user is NOT scrolled into view of panel 1 if( !fHasScrolledIntoView( oPanelTwoWrapper, ($(window).height() / 20) ) ) { // Set the inital state of panel 1 so we can animate it TweenMax.set( oPanelTwoWrapper, { opacity : 0 }); } } // When the user scrolls $(window).scroll( function() { // Request a scroll tick fRequestScrollTick(); }); // Request a scroll tick on the page load incase the user pressed back fRequestScrollTick(); // Set the padding top of the text to fade in and come in from the bottom TweenMax.to(oBannerText, 0.75, { paddingTop : 0, opacity : 1, }); }); /* fAnimatePanelOneWrapper() ========================= Applys animation to the panel 1 wrapper, this animation is only applied once */ function fAnimatePanelOneWrapper() { // If we haven't animted the panel 1 wrapper already if( !bHasAnimatedPanelOneWrapper ) { // If the element has been scrolled into view, we use the offset so it animates a little after it comes into view if( fHasScrolledIntoView( oPanelOneWrapper, ($(window).height() / 20) ) ) { // Tween the panel into position TweenMax.to( oPanelOneWrapper, 2, { opacity : 1 }); // Set the "has animated" variable to true so we don't animate again bHasAnimatedPanelOneWrapper = true; } } } /* fAnimatePanelTwoWrapper() ========================= Applys animation to the panel 2 wrapper, this animation is only applied once */ function fAnimatePanelTwoWrapper() { // If we haven't animted the panel 2 wrapper already if( !bHasAnimatedPanelTwoWrapper ) { // If the element has been scrolled into view, we use the offset so it animates a little after it comes into view if( fHasScrolledIntoView( oPanelTwoWrapper, ($(window).height() / 20) ) ) { // Tween the panel into position TweenMax.to( oPanelTwoWrapper, 2, { opacity : 1 }); // Set the "has animated" variable to true so we don't animate again bHasAnimatedPanelTwoWrapper = true; } } } /* fAnimateCategoiresWrapper() =========================== Applys animation to the category wrapper, this animation is only applied once */ function fAnimateCategoiresWrapper() { // If we haven't animted the categories wrapper already if( !bHasAnimatedCategoriesWrapper ) { // If the element has been scrolled into view, we use the offset so it animates a little after it comes into view if( fHasScrolledIntoView(oCategoriesWrapper.parent(), ($(window).height() / 20) ) ) { // Store the animation delay var nAnimationDelay = 0.25; // Loop through each category oCategoriesWrapper.children().each( function() { // Store this itteration of the category var oCategory_This = $(this); // Tween the category into position TweenMax.to( oCategory_This, 0.5, { paddingTop : 0, opacity : 1, delay : nAnimationDelay }); // Increase the animation delay nAnimationDelay += 0.15; }); // Set the "has animated" variable to true so we don't animate again bHasAnimatedCategoriesWrapper = true; } } } /* fAnimateBlogWrapper() ===================== Applys animation to the blog wrapper, this animation is only applied once */ function fAnimateBlogWrapper() { // If we haven't animted the blog wrapper already if( !bHasAnimatedBlogWrapper ) { // If the element has been scrolled into view, we use the offset so it animates a little after it comes into view if( fHasScrolledIntoView(oBlogWrapper, ($(window).height() / 40)) ) { // Store the animation delay var nAnimationDelay = 0; // Loop through each blog oBlogWrapper.find(".left-blog-col").each( function() { // Store this itteration of the blog var oBlog_This = $(this); // Tween the blog into position TweenMax.to( oBlog_This, 1, { paddingTop : 0, opacity : 1, delay : nAnimationDelay }); // Increase the animation delay nAnimationDelay += 0.15; }); // If the blog view all column exists if( oBlogViewAllColumn.length ) { // Fade in the the view all blog entries button TweenMax.to(oBlogViewAllColumn, 1, { opacity : 1, delay : nAnimationDelay }); } // Set the "has animated" variable to true so we don't animate again bHasAnimatedBlogWrapper = true; } } } /* fHasScrolledIntoView() ====================== Checks if the element is in view or not, this is used to start an animtaion when coming into view */ function fHasScrolledIntoView( oTarget, nTopOffset) { // Store the scroll top var oViewTop = $(window).scrollTop(); // Store the view bottom var oViewBottom = oViewTop + $(window).height(); // Store the targets top var oTargetTop = oTarget.offset().top + nTopOffset; // Store the target's bottom var oTargetBottom = oTargetTop + oTarget.height(); // Return if the target is in viewport or not return ( (oTargetTop <= oViewBottom) && (oTargetBottom >= oViewTop) ); } /* fOnScrollUpate() ================ This function is called by requestAnimationFrame when we log a tick */ function fOnScrollUpate() { // Store the scroll position var oScrollPos = $(document).scrollTop(); // If the categories wrapper exists if( oCategoriesWrapper.length ) { // Call the animation function fAnimateCategoiresWrapper(); } // If the panel one wrapper exists if( oPanelOneWrapper.length ) { // Call the animation function fAnimatePanelOneWrapper(); } // If the panel two wrapper exists if( oPanelTwoWrapper.length ) { // Call the animation function fAnimatePanelTwoWrapper(); } // If the blog wrapper exists if( oBlogWrapper.length ) { // Call the animation function fAnimateBlogWrapper(); } // If they user hasn't scrolled past the landing page block if( oScrollPos < oLandingPageBlock.height() ) { // Work out the opacity var oOpacity = 1 - ( oScrollPos / ( oLandingPageBlock.height() / 2 ) ); // Set the padding top of the text so it follow the user TweenMax.to(oBannerText, 0.75, { paddingTop : ( oScrollPos / 4), opacity : oOpacity }); } // Set the scroll ticking to be false so it can be called again 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) { // Deley by 100ms for a micro optimisation, this ensures that the function isn't called too frequently // as realistiaclly we don't need to do a check every scroll, just every scroll within 50ms intervals setTimeout( function () { // Prepare the request animation for the next frame requestAnimationFrame(fOnScrollUpate); }, 50); // Set the ticking to be true bScrollTicking = true; } } }());