website/script.js
2025-09-29 08:24:59 +00:00

330 lines
10 KiB
JavaScript

// Script principal pour le site 4NK
document.addEventListener('DOMContentLoaded', function() {
// Animation d'apparition des éléments au scroll
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver(function(entries) {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('fade-in-up');
}
});
}, observerOptions);
// Observer tous les éléments à animer
const animatedElements = document.querySelectorAll('.service-card, .about-text, .about-visual, .contact-info, .contact-form');
animatedElements.forEach(el => {
observer.observe(el);
});
// Navigation smooth scroll
const navLinks = document.querySelectorAll('.nav-link');
navLinks.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const targetId = this.getAttribute('href');
const targetSection = document.querySelector(targetId);
if (targetSection) {
const headerHeight = document.querySelector('.header').offsetHeight;
const targetPosition = targetSection.offsetTop - headerHeight;
window.scrollTo({
top: targetPosition,
behavior: 'smooth'
});
}
});
});
// Effet de parallaxe sur le logo principal
const heroLogo = document.querySelector('.hero-logo-img');
window.addEventListener('scroll', function() {
const scrolled = window.pageYOffset;
const rate = scrolled * -0.5;
if (heroLogo) {
heroLogo.style.transform = `translateY(${rate}px) rotate(${scrolled * 0.1}deg)`;
}
});
// Animation du header au scroll
const header = document.querySelector('.header');
window.addEventListener('scroll', function() {
if (window.scrollY > 100) {
header.style.background = 'rgba(10, 10, 10, 0.98)';
header.style.boxShadow = '0 2px 20px rgba(255, 107, 53, 0.1)';
} else {
header.style.background = 'rgba(10, 10, 10, 0.95)';
header.style.boxShadow = 'none';
}
});
// Effet de typing pour le titre principal
function typeWriter(element, text, speed = 100) {
let i = 0;
element.innerHTML = '';
function type() {
if (i < text.length) {
element.innerHTML += text.charAt(i);
i++;
setTimeout(type, speed);
}
}
type();
}
// Animation des icônes de services
const serviceIcons = document.querySelectorAll('.service-svg');
serviceIcons.forEach(icon => {
icon.addEventListener('mouseenter', function() {
this.style.animation = 'serviceIconPulse 1s ease-in-out infinite';
});
icon.addEventListener('mouseleave', function() {
this.style.animation = 'serviceIconPulse 3s ease-in-out infinite';
});
});
// Effet de particules flottantes
function createParticles() {
const particlesContainer = document.createElement('div');
particlesContainer.className = 'particles';
document.body.appendChild(particlesContainer);
for (let i = 0; i < 20; i++) {
const particle = document.createElement('div');
particle.className = 'particle';
particle.style.left = Math.random() * 100 + '%';
particle.style.animationDelay = Math.random() * 10 + 's';
particle.style.animationDuration = (Math.random() * 10 + 10) + 's';
particlesContainer.appendChild(particle);
}
}
// Créer les particules
createParticles();
// Effet de glow sur les boutons
const buttons = document.querySelectorAll('.btn');
buttons.forEach(button => {
button.addEventListener('mouseenter', function() {
this.style.boxShadow = '0 8px 25px rgba(255, 107, 53, 0.5), 0 0 20px rgba(255, 107, 53, 0.3)';
});
button.addEventListener('mouseleave', function() {
if (this.classList.contains('btn-primary')) {
this.style.boxShadow = '0 4px 15px rgba(255, 107, 53, 0.3)';
} else {
this.style.boxShadow = 'none';
}
});
});
// Gestion du formulaire de contact
const contactForm = document.querySelector('.contact-form form');
if (contactForm) {
contactForm.addEventListener('submit', async function(e) {
e.preventDefault();
const submitBtn = this.querySelector('.btn-primary');
const originalText = submitBtn.textContent;
submitBtn.textContent = 'Sending...';
submitBtn.disabled = true;
const name = this.querySelector('input[placeholder="Name"]').value.trim();
const email = this.querySelector('input[placeholder="Email"]').value.trim();
const message = this.querySelector('textarea[placeholder="Message"]').value.trim();
try {
const resp = await fetch('/contact', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, email, message })
});
if (!resp.ok) throw new Error('Failed');
submitBtn.textContent = 'Message sent!';
submitBtn.style.background = '#4CAF50';
setTimeout(() => {
submitBtn.textContent = originalText;
submitBtn.disabled = false;
submitBtn.style.background = '';
this.reset();
}, 2000);
} catch (err) {
submitBtn.textContent = 'Send failed';
submitBtn.style.background = '#E53935';
setTimeout(() => {
submitBtn.textContent = originalText;
submitBtn.disabled = false;
submitBtn.style.background = '';
}, 2000);
}
});
}
// Effet de cursor personnalisé
const cursor = document.createElement('div');
cursor.className = 'custom-cursor';
cursor.style.cssText = `
position: fixed;
width: 20px;
height: 20px;
background: radial-gradient(circle, rgba(255, 107, 53, 0.8) 0%, transparent 70%);
border-radius: 50%;
pointer-events: none;
z-index: 9999;
transition: transform 0.1s ease;
display: none;
`;
document.body.appendChild(cursor);
// Suivi du curseur
document.addEventListener('mousemove', function(e) {
cursor.style.left = e.clientX - 10 + 'px';
cursor.style.top = e.clientY - 10 + 'px';
cursor.style.display = 'block';
});
// Cacher le curseur personnalisé quand on quitte la page
document.addEventListener('mouseleave', function() {
cursor.style.display = 'none';
});
// Effet de hover sur les liens
const links = document.querySelectorAll('a, .btn');
links.forEach(link => {
link.addEventListener('mouseenter', function() {
cursor.style.transform = 'scale(1.5)';
cursor.style.background = 'radial-gradient(circle, rgba(255, 215, 0, 0.8) 0%, transparent 70%)';
});
link.addEventListener('mouseleave', function() {
cursor.style.transform = 'scale(1)';
cursor.style.background = 'radial-gradient(circle, rgba(255, 107, 53, 0.8) 0%, transparent 70%)';
});
});
// Animation des logos images
const logos = document.querySelectorAll('.logo-img, .hero-logo-img, .showcase-logo-img, .footer-logo-img');
logos.forEach(logo => {
logo.addEventListener('mouseenter', function() {
this.style.filter = 'drop-shadow(0 0 20px var(--primary-orange)) drop-shadow(0 0 40px var(--accent-orange))';
});
logo.addEventListener('mouseleave', function() {
// Restaurer le filtre original selon le type de logo
if (this.classList.contains('hero-logo-img')) {
this.style.filter = 'drop-shadow(0 0 20px var(--primary-orange))';
} else if (this.classList.contains('showcase-logo-img')) {
this.style.filter = 'drop-shadow(0 0 15px var(--primary-orange))';
} else if (this.classList.contains('footer-logo-img')) {
this.style.filter = 'drop-shadow(0 0 8px var(--primary-orange))';
} else {
this.style.filter = 'drop-shadow(0 0 10px var(--primary-orange))';
}
});
});
// Effet de parallaxe sur les sections
const parallaxElements = document.querySelectorAll('.hero, .services, .about, .contact');
window.addEventListener('scroll', function() {
const scrolled = window.pageYOffset;
parallaxElements.forEach((element, index) => {
const rate = scrolled * -0.5;
const sectionOffset = element.offsetTop;
const sectionHeight = element.offsetHeight;
if (scrolled + window.innerHeight > sectionOffset && scrolled < sectionOffset + sectionHeight) {
element.style.transform = `translateY(${rate * 0.1}px)`;
}
});
});
// Animation des cartes de services au scroll
const serviceCards = document.querySelectorAll('.service-card');
const serviceObserver = new IntersectionObserver(function(entries) {
entries.forEach((entry, index) => {
if (entry.isIntersecting) {
setTimeout(() => {
entry.target.style.opacity = '1';
entry.target.style.transform = 'translateY(0)';
}, index * 200);
}
});
}, { threshold: 0.1 });
serviceCards.forEach(card => {
card.style.opacity = '0';
card.style.transform = 'translateY(50px)';
card.style.transition = 'all 0.6s ease';
serviceObserver.observe(card);
});
// Effet de glow sur le texte principal
const brandName = document.querySelector('.brand-name');
if (brandName) {
setInterval(() => {
const intensity = Math.random() * 0.5 + 0.5;
brandName.style.textShadow = `0 0 ${30 * intensity}px rgba(255, 107, 53, ${intensity}), 0 0 ${50 * intensity}px rgba(255, 165, 0, ${intensity * 0.5})`;
}, 1000);
}
// Animation de chargement initial
window.addEventListener('load', function() {
document.body.style.opacity = '0';
document.body.style.transition = 'opacity 1s ease';
setTimeout(() => {
document.body.style.opacity = '1';
}, 100);
});
// Gestion du menu mobile (si nécessaire)
const navToggle = document.createElement('button');
navToggle.className = 'nav-toggle';
navToggle.innerHTML = '☰';
navToggle.style.cssText = `
display: none;
background: none;
border: none;
color: var(--text-light);
font-size: 1.5rem;
cursor: pointer;
padding: 0.5rem;
`;
// Ajouter le toggle au nav si on est sur mobile
if (window.innerWidth <= 768) {
const nav = document.querySelector('.nav');
nav.appendChild(navToggle);
navToggle.addEventListener('click', function() {
const navMenu = document.querySelector('.nav-menu');
navMenu.style.display = navMenu.style.display === 'flex' ? 'none' : 'flex';
});
}
// Mise à jour du menu mobile au redimensionnement
window.addEventListener('resize', function() {
const navMenu = document.querySelector('.nav-menu');
if (window.innerWidth > 768) {
navMenu.style.display = 'flex';
navToggle.style.display = 'none';
} else {
navToggle.style.display = 'block';
navMenu.style.display = 'none';
}
});
console.log('Site 4NK chargé avec succès !');
});