first commit
This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
// Smooth scrolling
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(this.getAttribute('href'));
|
||||
if (target) {
|
||||
target.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'start'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Mobile menu toggle
|
||||
const menuToggle = document.querySelector('.menu-toggle');
|
||||
const navLinks = document.querySelector('.nav-links');
|
||||
let menuOpen = false;
|
||||
|
||||
menuToggle?.addEventListener('click', () => {
|
||||
menuOpen = !menuOpen;
|
||||
if (menuOpen) {
|
||||
navLinks.style.display = 'flex';
|
||||
navLinks.style.position = 'absolute';
|
||||
navLinks.style.top = '100%';
|
||||
navLinks.style.left = '0';
|
||||
navLinks.style.right = '0';
|
||||
navLinks.style.background = 'rgba(0, 0, 0, 0.98)';
|
||||
navLinks.style.flexDirection = 'column';
|
||||
navLinks.style.padding = '1rem';
|
||||
navLinks.style.borderTop = '2px solid #E8A625';
|
||||
|
||||
// Animate menu toggle
|
||||
menuToggle.children[0].style.transform = 'rotate(45deg) translateY(8px)';
|
||||
menuToggle.children[1].style.opacity = '0';
|
||||
menuToggle.children[2].style.transform = 'rotate(-45deg) translateY(-8px)';
|
||||
} else {
|
||||
navLinks.style.display = 'none';
|
||||
|
||||
// Reset menu toggle
|
||||
menuToggle.children[0].style.transform = '';
|
||||
menuToggle.children[1].style.opacity = '1';
|
||||
menuToggle.children[2].style.transform = '';
|
||||
}
|
||||
});
|
||||
|
||||
// Close mobile menu when clicking outside
|
||||
document.addEventListener('click', (e) => {
|
||||
if (menuOpen && !menuToggle.contains(e.target) && !navLinks.contains(e.target)) {
|
||||
menuOpen = false;
|
||||
navLinks.style.display = 'none';
|
||||
menuToggle.children[0].style.transform = '';
|
||||
menuToggle.children[1].style.opacity = '1';
|
||||
menuToggle.children[2].style.transform = '';
|
||||
}
|
||||
});
|
||||
|
||||
// Scroll animations
|
||||
const observerOptions = {
|
||||
threshold: 0.1,
|
||||
rootMargin: '0px 0px -100px 0px'
|
||||
};
|
||||
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.style.animation = 'fadeInUp 0.8s ease both';
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, observerOptions);
|
||||
|
||||
// Observe all cards
|
||||
document.querySelectorAll('.service-card, .project-card, .value-card').forEach(el => {
|
||||
observer.observe(el);
|
||||
});
|
||||
|
||||
// Navbar scroll effect
|
||||
let lastScroll = 0;
|
||||
const nav = document.querySelector('nav');
|
||||
|
||||
window.addEventListener('scroll', () => {
|
||||
const currentScroll = window.pageYOffset;
|
||||
|
||||
if (currentScroll > 100) {
|
||||
nav.style.background = 'rgba(0, 0, 0, 0.98)';
|
||||
nav.style.boxShadow = '0 2px 20px rgba(232, 166, 37, 0.3)';
|
||||
} else {
|
||||
nav.style.background = 'rgba(0, 0, 0, 0.95)';
|
||||
nav.style.boxShadow = '';
|
||||
}
|
||||
|
||||
// Hide/show navbar on scroll
|
||||
if (currentScroll > lastScroll && currentScroll > 500) {
|
||||
nav.style.transform = 'translateY(-100%)';
|
||||
} else {
|
||||
nav.style.transform = 'translateY(0)';
|
||||
}
|
||||
|
||||
lastScroll = currentScroll;
|
||||
});
|
||||
|
||||
// Network animation enhancement
|
||||
function createNetworkLine() {
|
||||
const nodes = document.querySelectorAll('.node');
|
||||
const networkBg = document.querySelector('.network-bg');
|
||||
|
||||
if (nodes.length > 1 && networkBg) {
|
||||
for (let i = 0; i < nodes.length - 1; i++) {
|
||||
const line = document.createElement('div');
|
||||
line.style.position = 'absolute';
|
||||
line.style.height = '1px';
|
||||
line.style.background = 'linear-gradient(90deg, transparent, #E8A625, transparent)';
|
||||
line.style.opacity = '0.2';
|
||||
line.style.animation = `pulse 4s infinite ${i * 0.5}s`;
|
||||
|
||||
const node1 = nodes[i];
|
||||
const node2 = nodes[i + 1];
|
||||
|
||||
// Calculate line position and angle
|
||||
const x1 = parseFloat(node1.style.left);
|
||||
const y1 = parseFloat(node1.style.top);
|
||||
const x2 = parseFloat(node2.style.left);
|
||||
const y2 = parseFloat(node2.style.top);
|
||||
|
||||
const distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
|
||||
const angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
|
||||
|
||||
line.style.width = distance + '%';
|
||||
line.style.left = x1 + '%';
|
||||
line.style.top = y1 + '%';
|
||||
line.style.transform = `rotate(${angle}deg)`;
|
||||
line.style.transformOrigin = '0 0';
|
||||
|
||||
networkBg.appendChild(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize network lines
|
||||
createNetworkLine();
|
||||
|
||||
// Dynamic typing effect for hero subtitle
|
||||
const subtitle = document.querySelector('.hero-subtitle');
|
||||
if (subtitle) {
|
||||
const text = subtitle.textContent;
|
||||
subtitle.textContent = '';
|
||||
let index = 0;
|
||||
|
||||
function typeWriter() {
|
||||
if (index < text.length) {
|
||||
subtitle.textContent += text.charAt(index);
|
||||
index++;
|
||||
setTimeout(typeWriter, 100);
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(typeWriter, 800);
|
||||
}
|
||||
|
||||
// Add hover effect to project cards with tilt
|
||||
document.querySelectorAll('.project-card, .service-card').forEach(card => {
|
||||
card.addEventListener('mousemove', (e) => {
|
||||
const rect = card.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left;
|
||||
const y = e.clientY - rect.top;
|
||||
|
||||
const centerX = rect.width / 2;
|
||||
const centerY = rect.height / 2;
|
||||
|
||||
const rotateX = (y - centerY) / 20;
|
||||
const rotateY = (centerX - x) / 20;
|
||||
|
||||
card.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) translateY(-5px)`;
|
||||
});
|
||||
|
||||
card.addEventListener('mouseleave', () => {
|
||||
card.style.transform = '';
|
||||
});
|
||||
});
|
||||
|
||||
// Easter egg: Konami code
|
||||
const konamiCode = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a'];
|
||||
let konamiIndex = 0;
|
||||
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === konamiCode[konamiIndex]) {
|
||||
konamiIndex++;
|
||||
if (konamiIndex === konamiCode.length) {
|
||||
document.body.style.animation = 'pulse 1s';
|
||||
setTimeout(() => {
|
||||
alert('🎮 Félicitations! Vous avez trouvé le code secret! Bienvenue dans la résistance numérique!');
|
||||
document.body.style.animation = '';
|
||||
}, 1000);
|
||||
konamiIndex = 0;
|
||||
}
|
||||
} else {
|
||||
konamiIndex = 0;
|
||||
}
|
||||
});
|
||||
|
||||
// Progressive enhancement: Add loading states
|
||||
// Disabled - not needed for external links
|
||||
// document.querySelectorAll('.service-link, .project-card').forEach(link => {
|
||||
// link.addEventListener('click', function(e) {
|
||||
// if (this.href && this.href !== '#') {
|
||||
// this.style.opacity = '0.6';
|
||||
// this.innerHTML += ' ⌛';
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
|
||||
// Custom donation handler
|
||||
function handleCustomDonation(type) {
|
||||
const input = document.getElementById(type === 'oneTime' ? 'customAmountOneTime' : 'customAmountMonthly');
|
||||
const amount = input.value;
|
||||
|
||||
if (!amount || amount < 1) {
|
||||
alert('Veuillez entrer un montant valide');
|
||||
return;
|
||||
}
|
||||
|
||||
// Redirect to custom amount Stripe URL
|
||||
const stripeUrl = type === 'oneTime'
|
||||
? 'https://don.o-k-i.net/b/6oE2aO94P88X9u8eV4' // Custom one-time donation
|
||||
: 'https://don.o-k-i.net/b/6oE2aO94P88X9u8eV4'; // Uses same link for custom amounts
|
||||
|
||||
window.location.href = stripeUrl;
|
||||
}
|
||||
Reference in New Issue
Block a user