Greenlens/landing/script.js

89 lines
2.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* ========================================
GreenLens Landing Page Interactions
======================================== */
document.addEventListener('DOMContentLoaded', () => {
// --- Navbar scroll effect ---
const navbar = document.querySelector('.navbar');
const handleScroll = () => {
navbar.classList.toggle('scrolled', window.scrollY > 60);
};
window.addEventListener('scroll', handleScroll, { passive: true });
handleScroll();
// --- Mobile hamburger ---
const hamburger = document.querySelector('.nav-hamburger');
const navLinks = document.querySelector('.nav-links');
if (hamburger) {
hamburger.addEventListener('click', () => {
navLinks.classList.toggle('active');
});
// close on link click
navLinks.querySelectorAll('a').forEach(link => {
link.addEventListener('click', () => {
navLinks.classList.remove('active');
});
});
}
// --- Scroll reveal ---
const revealElements = document.querySelectorAll('.reveal');
const revealObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('active');
revealObserver.unobserve(entry.target);
}
});
}, {
threshold: 0.15,
rootMargin: '0px 0px -50px 0px'
});
revealElements.forEach(el => revealObserver.observe(el));
// --- Counter animation ---
const counters = document.querySelectorAll('[data-count]');
const counterObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const el = entry.target;
const target = parseFloat(el.dataset.count);
const suffix = el.dataset.suffix || '';
const isDecimal = target % 1 !== 0;
const duration = 1500;
const start = performance.now();
const step = (now) => {
const progress = Math.min((now - start) / duration, 1);
const eased = 1 - Math.pow(1 - progress, 3); // ease-out cubic
const current = eased * target;
el.textContent = (isDecimal ? current.toFixed(1) : Math.floor(current)) + suffix;
if (progress < 1) requestAnimationFrame(step);
};
requestAnimationFrame(step);
counterObserver.unobserve(el);
}
});
}, { threshold: 0.5 });
counters.forEach(el => counterObserver.observe(el));
// --- Smooth scroll for anchor links ---
document.querySelectorAll('a[href^="#"]').forEach(link => {
link.addEventListener('click', (e) => {
const target = document.querySelector(link.getAttribute('href'));
if (target) {
e.preventDefault();
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
});
});