331 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			331 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
 | 
						|
var displayedMenu = "";
 | 
						|
var hamburgerShown = false;
 | 
						|
let width = screen.width;
 | 
						|
var isMobile = width < 1024;
 | 
						|
 | 
						|
function readingTime() {
 | 
						|
    let articles = document.querySelectorAll(".article");
 | 
						|
    let times = document.querySelectorAll(".time");
 | 
						|
    const wpm = 225;
 | 
						|
    let words;
 | 
						|
    for (var i = 0; i < articles.length; i++) {
 | 
						|
        words = articles[i].innerText.trim().split(/\s+/).length;
 | 
						|
        let time = Math.ceil(words / wpm);
 | 
						|
        times[i].innerText = `${time} minute read`
 | 
						|
    }
 | 
						|
}
 | 
						|
readingTime()
 | 
						|
 | 
						|
function toggleMenu(button) {
 | 
						|
    if (displayedMenu === button.id.split("-")[0]) {
 | 
						|
        button.className = button.className.replace(" text-gray-800 bg-stone-200 sm:bg-transparent", " text-gray-900");
 | 
						|
        hideMenu(button.id.split("-")[0]);
 | 
						|
        button.lastElementChild.className = button.lastElementChild.className.replace("rotate-0", "-rotate-90")
 | 
						|
        displayedMenu = "";
 | 
						|
    } else {
 | 
						|
        showMenu(button.id.split("-")[0]);
 | 
						|
        button.lastElementChild.className = button.lastElementChild.className.replace("-rotate-90", "rotate-0")
 | 
						|
        button.className = button.className.replace(" text-gray-900", " text-gray-800 bg-stone-200 sm:bg-transparent");
 | 
						|
        displayedMenu = button.id.split("-")[0]
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
function handleClick(button) {
 | 
						|
    if (button.id === "hamburger-btn" || button.id === "close-hamburger-btn") {
 | 
						|
        toggleHamburger()
 | 
						|
    }
 | 
						|
    if (button.id.indexOf("menu") !== -1) {
 | 
						|
        toggleMenu(button)
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
function toggleHamburger() {
 | 
						|
    if (hamburgerShown) {
 | 
						|
        hideHamburger();
 | 
						|
        hamburgerShown = false;
 | 
						|
    } else {
 | 
						|
        showHamburger();
 | 
						|
        hamburgerShown = true;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
function showMenu(menuName) {
 | 
						|
    var menuId = menuName + (isMobile ? '-mobile-menu' : '-menu');
 | 
						|
    var menuBtnId = menuName + (isMobile ? '-mobile-menu' : '-menu');
 | 
						|
    var menuElement = document.getElementById(menuId)
 | 
						|
    menuElement.className = menuElement.className.replace(" hidden", "");
 | 
						|
    let children = document.querySelectorAll('.nav_menu')
 | 
						|
    for (let i = 0; i < children.length; i++) {
 | 
						|
        if (menuElement !== children[i]) {
 | 
						|
            let btnId = `${children[i].id}-btn`;
 | 
						|
            let btn = document.getElementById(btnId);
 | 
						|
            if (btn && !children[i].classList.contains('hidden')) {
 | 
						|
                children[i].classList.add('hidden')
 | 
						|
                btn.lastElementChild.classList.replace("rotate-0", "-rotate-90")
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    setTimeout(function () {
 | 
						|
        menuElement.className = menuElement.className.replace("duration-200 ease-in opacity-0 -translate-y-1", "duration-150 ease-out opacity-1 -translate-y-0");
 | 
						|
    }, 10);
 | 
						|
}
 | 
						|
 | 
						|
function hideMenu(menuName) {
 | 
						|
    var menuId = menuName + (isMobile ? '-mobile-menu' : '-menu');
 | 
						|
    var menuElement = document.getElementById(menuId)
 | 
						|
    menuElement.className = menuElement.className.replace("duration-150 ease-out opacity-1 -translate-y-0", "duration-200 ease-in opacity-0 -translate-y-1");
 | 
						|
    setTimeout(function () {
 | 
						|
        menuElement.className = menuElement.className + " hidden"
 | 
						|
    }, 300);
 | 
						|
}
 | 
						|
 | 
						|
function showHamburger() {
 | 
						|
    document.getElementById('header-container').className = "overflow-hidden";
 | 
						|
    document.getElementById('hamburger').className = "fixed mt-28 z-20 top-0 inset-x-0 transition transform origin-top-right";
 | 
						|
    document.getElementById('hamburger-btn').className = "hidden lg:hidden inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 focus:text-gray-500 transition duration-150 ease-in-out";
 | 
						|
    document.getElementById('close-hamburger-btn').className = "inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 focus:text-gray-500 transition duration-150 ease-in-out";
 | 
						|
}
 | 
						|
 | 
						|
function hideHamburger() {
 | 
						|
    document.getElementById('header-container').className = "";
 | 
						|
    document.getElementById('hamburger').className = "hidden absolute z-20 top-0 inset-x-0 transition transform origin-top-right lg:hidden";
 | 
						|
    document.getElementById('hamburger-btn').className = "inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 focus:text-gray-500 transition duration-150 ease-in-out";
 | 
						|
    document.getElementById('close-hamburger-btn').className = "hidden lg:hidden inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 focus:text-gray-500 transition duration-150 ease-in-out";
 | 
						|
    if (displayedMenu !== "") {
 | 
						|
        hideMenu(displayedMenu);
 | 
						|
    }
 | 
						|
}
 | 
						|
function toggleFilter() {
 | 
						|
    var filterMenu = document.getElementById("filter-menu")
 | 
						|
    if (filterMenu.className.includes("hidden")) {
 | 
						|
        filterMenu.className = filterMenu.className.replace("hidden", " ")
 | 
						|
    } else {
 | 
						|
        filterMenu.className = filterMenu.className + " hidden"
 | 
						|
    }
 | 
						|
}
 | 
						|
// Smooth scrolling function for anchor links
 | 
						|
function smoothScrollToElement(targetId) {
 | 
						|
    const element = document.getElementById(targetId);
 | 
						|
    if (element) {
 | 
						|
        const headerHeight = document.getElementById('header-container') ? 
 | 
						|
            document.getElementById('header-container').offsetHeight : 80;
 | 
						|
        const elementPosition = element.offsetTop - headerHeight - 20;
 | 
						|
        
 | 
						|
        window.scrollTo({
 | 
						|
            top: elementPosition,
 | 
						|
            behavior: 'smooth'
 | 
						|
        });
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
// Handle anchor link clicks
 | 
						|
function handleAnchorClick(event, link) {
 | 
						|
    const href = link.getAttribute('href');
 | 
						|
    if (href && href.startsWith('#')) {
 | 
						|
        event.preventDefault();
 | 
						|
        const targetId = href.substring(1);
 | 
						|
        smoothScrollToElement(targetId);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
window.onload = function () {
 | 
						|
    let elements = document.getElementsByTagName("button");
 | 
						|
    let buttons = [...elements]
 | 
						|
 | 
						|
    buttons.forEach((button) => {
 | 
						|
        button.addEventListener('click', function () {
 | 
						|
            handleClick(button)
 | 
						|
        });
 | 
						|
    })
 | 
						|
 | 
						|
    var links = document.links;
 | 
						|
    var internal_hosts = [
 | 
						|
        'www.ourworld.tf',
 | 
						|
        'ourworld.tf',
 | 
						|
        'www2.ourworld.tf',
 | 
						|
        'www2.freezone.ourworld.tf',
 | 
						|
        'freezone.ourworld.tf',
 | 
						|
        'localhost',
 | 
						|
        '127.0.0.1'
 | 
						|
    ]
 | 
						|
    for (var i = 0, linksLength = links.length; i < linksLength; i++) {
 | 
						|
        if (!internal_hosts.includes(links[i].hostname)) {
 | 
						|
            links[i].target = '_blank';
 | 
						|
        }
 | 
						|
        
 | 
						|
        // Add smooth scrolling for anchor links
 | 
						|
        if (links[i].getAttribute('href') && links[i].getAttribute('href').startsWith('#')) {
 | 
						|
            links[i].addEventListener('click', function(event) {
 | 
						|
                handleAnchorClick(event, this);
 | 
						|
            });
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // Add smooth scrolling behavior to html element
 | 
						|
    document.documentElement.style.scrollBehavior = 'smooth';
 | 
						|
 | 
						|
    document.getElementById("filter-btn").addEventListener('click', toggleFilter);
 | 
						|
}
 | 
						|
 | 
						|
function openInNewTab(url) {
 | 
						|
    window.open(url, '_blank').focus()
 | 
						|
}
 | 
						|
 | 
						|
// Animation System for Homepage Components
 | 
						|
class AnimationController {
 | 
						|
    constructor() {
 | 
						|
        this.observer = null;
 | 
						|
        this.isPageLoaded = false;
 | 
						|
        this.init();
 | 
						|
    }
 | 
						|
 | 
						|
    init() {
 | 
						|
        // Set up intersection observer for scroll animations
 | 
						|
        this.setupIntersectionObserver();
 | 
						|
        
 | 
						|
        // Handle initial page load animations
 | 
						|
        this.handlePageLoad();
 | 
						|
        
 | 
						|
        // Initialize animations when DOM is ready
 | 
						|
        if (document.readyState === 'loading') {
 | 
						|
            document.addEventListener('DOMContentLoaded', () => this.initializeAnimations());
 | 
						|
        } else {
 | 
						|
            this.initializeAnimations();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    setupIntersectionObserver() {
 | 
						|
        const options = {
 | 
						|
            root: null,
 | 
						|
            rootMargin: '0px 0px -10% 0px', // Trigger when element is 10% visible
 | 
						|
            threshold: 0.1
 | 
						|
        };
 | 
						|
 | 
						|
        this.observer = new IntersectionObserver((entries) => {
 | 
						|
            entries.forEach(entry => {
 | 
						|
                if (entry.isIntersecting) {
 | 
						|
                    this.animateElement(entry.target);
 | 
						|
                }
 | 
						|
            });
 | 
						|
        }, options);
 | 
						|
    }
 | 
						|
 | 
						|
    animateElement(element) {
 | 
						|
        // Add visible class to trigger CSS animations
 | 
						|
        element.classList.add('animate-visible');
 | 
						|
        
 | 
						|
        // Animate child elements with stagger effect
 | 
						|
        const children = element.querySelectorAll('.animate-stagger-1, .animate-stagger-2, .animate-stagger-3, .animate-stagger-4, .animate-stagger-5');
 | 
						|
        children.forEach((child, index) => {
 | 
						|
            setTimeout(() => {
 | 
						|
                child.classList.add('animate-visible');
 | 
						|
            }, index * 100);
 | 
						|
        });
 | 
						|
 | 
						|
        // Stop observing this element once animated
 | 
						|
        this.observer.unobserve(element);
 | 
						|
    }
 | 
						|
 | 
						|
    handlePageLoad() {
 | 
						|
        // Add loading class initially
 | 
						|
        document.body.classList.add('page-loading');
 | 
						|
        
 | 
						|
        window.addEventListener('load', () => {
 | 
						|
            this.isPageLoaded = true;
 | 
						|
            document.body.classList.remove('page-loading');
 | 
						|
            document.body.classList.add('page-loaded');
 | 
						|
            
 | 
						|
            // Animate hero section immediately on load
 | 
						|
            this.animateHeroSection();
 | 
						|
        });
 | 
						|
    }
 | 
						|
 | 
						|
    animateHeroSection() {
 | 
						|
        const heroElements = document.querySelectorAll('.hero-title, .hero-subtitle, .hero-button');
 | 
						|
        heroElements.forEach(element => {
 | 
						|
            element.classList.add('animate-visible');
 | 
						|
        });
 | 
						|
    }
 | 
						|
 | 
						|
    initializeAnimations() {
 | 
						|
        // Find all elements that should be animated
 | 
						|
        const animatedElements = document.querySelectorAll(
 | 
						|
            '.animate-fade-in, .animate-slide-left, .animate-slide-right, .animate-scale-up, .animate-text-content, .animate-image'
 | 
						|
        );
 | 
						|
 | 
						|
        // Start observing each element
 | 
						|
        animatedElements.forEach(element => {
 | 
						|
            this.observer.observe(element);
 | 
						|
        });
 | 
						|
 | 
						|
        // Add animation classes to row containers
 | 
						|
        this.addAnimationClassesToRows();
 | 
						|
    }
 | 
						|
 | 
						|
    addAnimationClassesToRows() {
 | 
						|
        // Get all row containers from the homepage
 | 
						|
        const rows = document.querySelectorAll('[id*="row"], .relative.justify-center.flex.overflow-hidden');
 | 
						|
        
 | 
						|
        rows.forEach((row, index) => {
 | 
						|
            // Add different animation types based on position
 | 
						|
            const animationType = this.getAnimationTypeForRow(index);
 | 
						|
            row.classList.add(animationType);
 | 
						|
            
 | 
						|
            // Add text content animation to text columns
 | 
						|
            const textColumns = row.querySelectorAll('div[class*="flex-1"]');
 | 
						|
            textColumns.forEach(column => {
 | 
						|
                if (this.hasTextContent(column)) {
 | 
						|
                    column.classList.add('animate-text-content');
 | 
						|
                }
 | 
						|
                
 | 
						|
                // Add image animation to image containers
 | 
						|
                const images = column.querySelectorAll('img');
 | 
						|
                images.forEach(img => {
 | 
						|
                    img.parentElement.classList.add('animate-image');
 | 
						|
                });
 | 
						|
            });
 | 
						|
        });
 | 
						|
    }
 | 
						|
 | 
						|
    getAnimationTypeForRow(index) {
 | 
						|
        const animations = ['animate-fade-in', 'animate-slide-left', 'animate-slide-right', 'animate-scale-up'];
 | 
						|
        return animations[index % animations.length];
 | 
						|
    }
 | 
						|
 | 
						|
    hasTextContent(element) {
 | 
						|
        const textElements = element.querySelectorAll('h1, h2, h3, h4, p, button, a');
 | 
						|
        return textElements.length > 0;
 | 
						|
    }
 | 
						|
 | 
						|
    // Method to trigger animations on scroll direction change
 | 
						|
    handleScrollDirection() {
 | 
						|
        let lastScrollTop = 0;
 | 
						|
        
 | 
						|
        window.addEventListener('scroll', () => {
 | 
						|
            const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
 | 
						|
            const scrollDirection = scrollTop > lastScrollTop ? 'down' : 'up';
 | 
						|
            
 | 
						|
            // You can add specific animations based on scroll direction here
 | 
						|
            document.body.setAttribute('data-scroll-direction', scrollDirection);
 | 
						|
            
 | 
						|
            lastScrollTop = scrollTop <= 0 ? 0 : scrollTop;
 | 
						|
        }, false);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
// Initialize animation system
 | 
						|
let animationController;
 | 
						|
 | 
						|
// Enhanced window.onload to include animations
 | 
						|
const originalWindowOnload = window.onload;
 | 
						|
window.onload = function() {
 | 
						|
    // Call original onload function
 | 
						|
    if (originalWindowOnload) {
 | 
						|
        originalWindowOnload();
 | 
						|
    }
 | 
						|
    
 | 
						|
    // Initialize animation controller
 | 
						|
    animationController = new AnimationController();
 | 
						|
}
 |