/** * Temu Affiliate Funnel * Animations JavaScript File */ document.addEventListener('DOMContentLoaded', function() { // Initialize all animations initializeAnimations(); // Ensure animations run on page load and when changing steps window.addEventListener('load', function() { refreshAnimations(); }); // Add attention-grabbing intro animation animateIntroSection(); // Enhance button animations enhanceButtonAnimations(); }); /** * Initializes all animations for the funnel */ function initializeAnimations() { // Animate the current step or results page animateCurrentStep(); // Animate option items on hover animateOptionItems(); // Animate progress indicators animateProgressIndicators(); // Animate promotion cards animatePromotionCards(); // Add scroll animations addScrollAnimations(); } /** * Refreshes animations when needed (e.g., after page transitions) */ function refreshAnimations() { // Add a small delay to ensure DOM is fully updated setTimeout(function() { animateCurrentStep(); }, 100); } /** * Animates the current funnel step or results page */ function animateCurrentStep() { const currentStep = document.querySelector('.funnel-step, .results-page'); if (currentStep) { currentStep.classList.add('animate-in'); } } /** * Adds hover animations to option items */ function animateOptionItems() { const optionItems = document.querySelectorAll('.option-item label, .interest-item label'); optionItems.forEach(item => { item.addEventListener('mouseover', function() { if (!this.parentElement.querySelector('input').checked) { this.style.transform = 'translateY(-2px)'; this.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.1)'; } }); item.addEventListener('mouseout', function() { if (!this.parentElement.querySelector('input').checked) { this.style.transform = 'translateY(0)'; this.style.boxShadow = 'none'; } }); // Add click animation item.addEventListener('click', function() { this.animate([ { transform: 'scale(0.98)', boxShadow: '0 1px 2px rgba(0, 0, 0, 0.1)' }, { transform: 'scale(1)', boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)' } ], { duration: 300, easing: 'ease' }); }); }); } /** * Animates the progress indicators */ function animateProgressIndicators() { const progressBar = document.querySelector('.progress'); const indicators = document.querySelectorAll('.step-indicator'); if (progressBar) { // Add a smooth animation for the progress bar progressBar.style.transition = 'width 0.8s ease-in-out'; } if (indicators.length > 0) { // Stagger the indicator animations indicators.forEach((indicator, index) => { if (indicator.classList.contains('active')) { setTimeout(() => { indicator.animate([ { transform: 'scale(0.8)', opacity: 0.8 }, { transform: 'scale(1.1)', opacity: 1 }, { transform: 'scale(1)', opacity: 1 } ], { duration: 400, easing: 'ease-out', delay: index * 150 }); }, 300); } }); } } /** * Animates promotion cards and product images */ function animatePromotionCards() { const promotionCard = document.querySelector('.promotion-card'); if (promotionCard) { // Animate promotion card entry setTimeout(() => { promotionCard.style.transition = 'transform 0.5s ease-out, box-shadow 0.5s ease-out'; promotionCard.style.transform = 'translateY(0)'; promotionCard.style.opacity = '1'; promotionCard.style.boxShadow = '0 10px 30px rgba(0, 0, 0, 0.1)'; }, 500); // Animate product images const productImages = document.querySelectorAll('.product-image'); productImages.forEach((image, index) => { setTimeout(() => { image.animate([ { opacity: 0, transform: 'scale(0.9)' }, { opacity: 1, transform: 'scale(1)' } ], { duration: 500, easing: 'ease-out', fill: 'forwards' }); }, 800 + (index * 200)); }); } // Animate other promotion items const promotionItems = document.querySelectorAll('.promotion-item'); promotionItems.forEach((item, index) => { setTimeout(() => { item.animate([ { opacity: 0, transform: 'translateY(20px)' }, { opacity: 1, transform: 'translateY(0)' } ], { duration: 500, easing: 'ease-out', fill: 'forwards' }); }, 1200 + (index * 200)); }); } /** * Adds scroll-based animations */ function addScrollAnimations() { // Function to check if element is in viewport function isInViewport(element) { const rect = element.getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); } // Elements to animate on scroll const scrollAnimElements = document.querySelectorAll('.promotion-showcase, .more-promotions, .restart-funnel'); // Check for elements in viewport on scroll function checkScrollAnimations() { scrollAnimElements.forEach(element => { if (isInViewport(element) && !element.classList.contains('animated')) { element.classList.add('animated'); element.animate([ { opacity: 0, transform: 'translateY(20px)' }, { opacity: 1, transform: 'translateY(0)' } ], { duration: 800, easing: 'ease-out', fill: 'forwards' }); } }); } // Listen for scroll events window.addEventListener('scroll', checkScrollAnimations); // Initial check checkScrollAnimations(); } /** * Add button pulse animations for primary CTAs */ function pulseButtonAnimations() { const primaryButtons = document.querySelectorAll('.btn-primary'); primaryButtons.forEach(button => { // Skip buttons that already have pulse animation if (button.classList.contains('pulse-added')) return; // Mark button to avoid duplicating animations button.classList.add('pulse-added'); // Add pulse animation after a delay setTimeout(() => { button.animate([ { transform: 'scale(1)', boxShadow: '0 0 0 0 rgba(255, 80, 0, 0.5)' }, { transform: 'scale(1.05)', boxShadow: '0 0 0 10px rgba(255, 80, 0, 0)' }, { transform: 'scale(1)', boxShadow: '0 0 0 0 rgba(255, 80, 0, 0)' } ], { duration: 2000, iterations: 2, easing: 'ease-out' }); }, 3000); }); } // Add pulse animations after a delay setTimeout(pulseButtonAnimations, 2000); /** * Custom animation for share buttons */ function initializeShareButtonEffects() { const shareButtons = document.querySelectorAll('.share-button'); shareButtons.forEach(button => { button.addEventListener('mouseover', function() { this.animate([ { transform: 'translateY(0)' }, { transform: 'translateY(-5px)' }, { transform: 'translateY(0)' } ], { duration: 500, easing: 'ease' }); }); }); } // Initialize share button effects setTimeout(initializeShareButtonEffects, 2000); /** * Adds attention-grabbing animations to the intro section */ function animateIntroSection() { const introSection = document.querySelector('.intro-text'); const introBadge = document.querySelector('.intro-badge'); if (introSection) { // Add more pronounced entrance animation with sequential element reveals const introHeading = introSection.querySelector('h2'); const introParagraph = introSection.querySelector('p'); if (introBadge) { setTimeout(() => { introBadge.animate([ { transform: 'scale(0.8)', opacity: 0 }, { transform: 'scale(1.1)', opacity: 1 }, { transform: 'scale(1)', opacity: 1 } ], { duration: 600, easing: 'ease-out', fill: 'forwards' }); }, 300); } if (introHeading) { setTimeout(() => { introHeading.animate([ { transform: 'translateY(20px)', opacity: 0 }, { transform: 'translateY(0)', opacity: 1 } ], { duration: 800, easing: 'ease-out', fill: 'forwards' }); }, 600); } if (introParagraph) { setTimeout(() => { introParagraph.animate([ { transform: 'translateY(20px)', opacity: 0 }, { transform: 'translateY(0)', opacity: 1 } ], { duration: 800, easing: 'ease-out', fill: 'forwards' }); }, 900); } // Add a subtle continue indicator after all intro elements are visible setTimeout(() => { const continueIndicator = document.createElement('div'); continueIndicator.className = 'continue-indicator'; continueIndicator.innerHTML = ''; introSection.appendChild(continueIndicator); continueIndicator.animate([ { transform: 'translateY(0)', opacity: 0 }, { transform: 'translateY(10px)', opacity: 1 } ], { duration: 800, easing: 'ease-out', fill: 'forwards' }); // Add bounce animation setInterval(() => { continueIndicator.animate([ { transform: 'translateY(10px)' }, { transform: 'translateY(20px)' }, { transform: 'translateY(10px)' } ], { duration: 1200, easing: 'ease-in-out' }); }, 2000); }, 1500); } } /** * Enhances button animations for more marketing appeal */ function enhanceButtonAnimations() { const primaryButtons = document.querySelectorAll('.btn-primary'); primaryButtons.forEach(button => { // Add icon animation on hover const icon = button.querySelector('i'); if (icon) { button.addEventListener('mouseover', function() { icon.animate([ { transform: 'translateX(0)' }, { transform: 'translateX(5px)' }, { transform: 'translateX(3px)' } ], { duration: 600, easing: 'ease' }); }); } // Add attention-grabbing animation after page load setTimeout(() => { button.animate([ { transform: 'scale(1)', boxShadow: '0 5px 15px rgba(255, 80, 0, 0.3)' }, { transform: 'scale(1.05)', boxShadow: '0 8px 25px rgba(255, 80, 0, 0.4)' }, { transform: 'scale(1)', boxShadow: '0 5px 15px rgba(255, 80, 0, 0.3)' } ], { duration: 1200, iterations: 1, easing: 'ease-in-out' }); }, 1500); }); // Add shine effect on primary buttons primaryButtons.forEach(button => { // Add shine effect class button.classList.add('shine-effect'); // Create the shine element const shineElement = document.createElement('span'); shineElement.className = 'btn-shine'; button.appendChild(shineElement); // Create the shine animation with a random delay const randomDelay = Math.floor(Math.random() * 5000) + 3000; function startShineAnimation() { shineElement.style.animation = 'none'; setTimeout(() => { shineElement.style.animation = 'shine 3s ease-in-out'; setTimeout(startShineAnimation, randomDelay); }, 50); } setTimeout(startShineAnimation, randomDelay); }); } // Add CSS for the continue indicator and button shine effect (function addDynamicStyles() { const style = document.createElement('style'); style.textContent = ` .continue-indicator { color: white; font-size: 24px; text-align: center; margin-top: 20px; opacity: 0.8; } .shine-effect { position: relative; overflow: hidden; } .btn-shine { position: absolute; top: 0; left: 0; width: 50px; height: 100%; background: linear-gradient( to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.8) 50%, rgba(255, 255, 255, 0) 100% ); transform: skewX(-25deg); pointer-events: none; } @keyframes shine { 0% { left: -100px; } 100% { left: 200%; } } `; document.head.appendChild(style); })();