Files
aivertice/script.js

543 lines
20 KiB
JavaScript

/* ==========================================
AI VERTICE - Premium Interactive Effects
========================================== */
document.addEventListener('DOMContentLoaded', function() {
// ==========================================
// Cursor Glow Effect
// ==========================================
const cursorGlow = document.querySelector('.cursor-glow');
if (cursorGlow && window.innerWidth > 768) {
document.addEventListener('mousemove', (e) => {
cursorGlow.style.left = e.clientX + 'px';
cursorGlow.style.top = e.clientY + 'px';
});
document.addEventListener('mouseenter', () => {
cursorGlow.style.opacity = '1';
});
document.addEventListener('mouseleave', () => {
cursorGlow.style.opacity = '0';
});
}
// ==========================================
// Mobile Menu Toggle
// ==========================================
const mobileMenuBtn = document.querySelector('.mobile-menu-btn');
const navLinks = document.querySelector('.nav-links');
const navActions = document.querySelector('.nav-actions');
if (mobileMenuBtn) {
mobileMenuBtn.addEventListener('click', function() {
this.classList.toggle('active');
let mobileMenu = document.querySelector('.mobile-menu');
if (!mobileMenu) {
mobileMenu = document.createElement('div');
mobileMenu.className = 'mobile-menu';
mobileMenu.innerHTML = `
<div class="mobile-menu-content">
${navLinks ? navLinks.innerHTML : ''}
${navActions ? navActions.innerHTML : ''}
</div>
`;
document.querySelector('.header').appendChild(mobileMenu);
const style = document.createElement('style');
style.textContent = `
.mobile-menu {
position: fixed;
top: 80px;
left: 0;
right: 0;
background: rgba(3, 7, 18, 0.98);
backdrop-filter: blur(20px);
padding: 2rem;
transform: translateY(-100%);
opacity: 0;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 999;
border-bottom: 1px solid rgba(255,255,255,0.1);
}
.mobile-menu.active {
transform: translateY(0);
opacity: 1;
}
.mobile-menu-content {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.mobile-menu a {
display: block;
padding: 0.75rem 0;
color: #d1d5db;
font-size: 1.1rem;
border-bottom: 1px solid rgba(255,255,255,0.05);
}
.mobile-menu a:hover {
color: #fff;
}
.mobile-menu .btn {
margin-top: 1rem;
}
.mobile-menu-btn.active span:nth-child(1) {
transform: rotate(45deg) translate(5px, 5px);
}
.mobile-menu-btn.active span:nth-child(2) {
opacity: 0;
}
.mobile-menu-btn.active span:nth-child(3) {
transform: rotate(-45deg) translate(7px, -6px);
}
`;
document.head.appendChild(style);
}
mobileMenu.classList.toggle('active');
});
}
// ==========================================
// FAQ Accordion
// ==========================================
const faqItems = document.querySelectorAll('.faq-item');
faqItems.forEach(item => {
const question = item.querySelector('.faq-question');
question.addEventListener('click', function() {
const isActive = item.classList.contains('active');
faqItems.forEach(otherItem => {
otherItem.classList.remove('active');
});
if (!isActive) {
item.classList.add('active');
}
});
});
// ==========================================
// Smooth Scroll
// ==========================================
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
const mobileMenu = document.querySelector('.mobile-menu');
const mobileMenuBtn = document.querySelector('.mobile-menu-btn');
if (mobileMenu && mobileMenu.classList.contains('active')) {
mobileMenu.classList.remove('active');
mobileMenuBtn.classList.remove('active');
}
const headerHeight = document.querySelector('.header').offsetHeight;
const targetPosition = target.getBoundingClientRect().top + window.pageYOffset - headerHeight;
window.scrollTo({
top: targetPosition,
behavior: 'smooth'
});
}
});
});
// ==========================================
// Header Background on Scroll
// ==========================================
const header = document.querySelector('.header');
window.addEventListener('scroll', function() {
if (window.pageYOffset > 100) {
header.style.background = 'rgba(3, 7, 18, 0.95)';
header.style.boxShadow = '0 4px 30px rgba(0, 0, 0, 0.3)';
} else {
header.style.background = 'rgba(3, 7, 18, 0.7)';
header.style.boxShadow = 'none';
}
});
// ==========================================
// Intersection Observer for Animations
// ==========================================
const observerOptions = {
root: null,
rootMargin: '0px',
threshold: 0.1
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('animate-in');
observer.unobserve(entry.target);
}
});
}, observerOptions);
const animationStyle = document.createElement('style');
animationStyle.textContent = `
.animate-on-scroll {
opacity: 0;
transform: translateY(40px);
transition: opacity 0.8s cubic-bezier(0.4, 0, 0.2, 1), transform 0.8s cubic-bezier(0.4, 0, 0.2, 1);
}
.animate-on-scroll.animate-in {
opacity: 1;
transform: translateY(0);
}
.animate-on-scroll:nth-child(1) { transition-delay: 0s; }
.animate-on-scroll:nth-child(2) { transition-delay: 0.1s; }
.animate-on-scroll:nth-child(3) { transition-delay: 0.2s; }
.animate-on-scroll:nth-child(4) { transition-delay: 0.3s; }
.animate-on-scroll:nth-child(5) { transition-delay: 0.4s; }
.animate-on-scroll:nth-child(6) { transition-delay: 0.5s; }
`;
document.head.appendChild(animationStyle);
const animateElements = document.querySelectorAll(
'.platform-card, .timeline-item, .use-case-card, .metric-card, .testimonial-card, .feature-card, .faq-item, .integration-category'
);
animateElements.forEach(el => {
el.classList.add('animate-on-scroll');
observer.observe(el);
});
// ==========================================
// Counter Animation
// ==========================================
const counters = document.querySelectorAll('[data-count]');
const animateCounter = (el) => {
const target = parseInt(el.getAttribute('data-count'));
const duration = 2000;
const step = target / (duration / 16);
let current = 0;
const updateCounter = () => {
current += step;
if (current < target) {
el.textContent = Math.floor(current);
requestAnimationFrame(updateCounter);
} else {
el.textContent = target;
}
};
updateCounter();
};
const counterObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
animateCounter(entry.target);
counterObserver.unobserve(entry.target);
}
});
}, { threshold: 0.5 });
counters.forEach(counter => counterObserver.observe(counter));
// ==========================================
// Tilt Effect on Cards
// ==========================================
const tiltCards = document.querySelectorAll('[data-tilt]');
tiltCards.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) translateZ(10px)`;
});
card.addEventListener('mouseleave', () => {
card.style.transform = 'perspective(1000px) rotateX(0) rotateY(0) translateZ(0)';
});
});
// ==========================================
// Form Submission
// ==========================================
const contactForm = document.querySelector('.contact-form');
if (contactForm) {
contactForm.addEventListener('submit', function(e) {
e.preventDefault();
const btn = this.querySelector('button[type="submit"]');
const originalHTML = btn.innerHTML;
btn.innerHTML = '<span>Enviando...</span>';
btn.disabled = true;
btn.style.opacity = '0.7';
setTimeout(() => {
btn.innerHTML = '<span>✓ Mensagem Enviada!</span>';
btn.style.background = 'linear-gradient(135deg, #10b981 0%, #059669 100%)';
btn.style.opacity = '1';
this.reset();
setTimeout(() => {
btn.innerHTML = originalHTML;
btn.style.background = '';
btn.disabled = false;
}, 3000);
}, 1500);
});
}
// ==========================================
// Parallax on Neural Network
// ==========================================
const neuralNetwork = document.querySelector('.neural-network');
const floatingCards = document.querySelectorAll('.floating-card');
if (neuralNetwork && window.innerWidth > 992) {
document.addEventListener('mousemove', (e) => {
const mouseX = (e.clientX / window.innerWidth - 0.5) * 2;
const mouseY = (e.clientY / window.innerHeight - 0.5) * 2;
neuralNetwork.style.transform = `translate(calc(-50% + ${mouseX * 20}px), calc(-50% + ${mouseY * 20}px))`;
floatingCards.forEach((card, index) => {
const speed = (index + 1) * 8;
const baseTransform = card.style.transform || '';
card.style.transform = `translate(${mouseX * speed}px, ${mouseY * speed}px)`;
});
});
}
// ==========================================
// Glitch Effect on Hover
// ==========================================
const glitchText = document.querySelector('.glitch');
if (glitchText) {
const glitchStyle = document.createElement('style');
glitchStyle.textContent = `
.glitch {
position: relative;
}
.glitch:hover::before,
.glitch:hover::after {
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: transparent;
}
.glitch:hover::before {
left: 2px;
text-shadow: -2px 0 #ff00ff;
clip-path: inset(44% 0 56% 0);
animation: glitch-anim-1 0.5s infinite linear alternate-reverse;
}
.glitch:hover::after {
left: -2px;
text-shadow: -2px 0 #00ffff;
clip-path: inset(24% 0 76% 0);
animation: glitch-anim-2 0.5s infinite linear alternate-reverse;
}
@keyframes glitch-anim-1 {
0% { clip-path: inset(44% 0 36% 0); }
20% { clip-path: inset(12% 0 64% 0); }
40% { clip-path: inset(78% 0 2% 0); }
60% { clip-path: inset(32% 0 52% 0); }
80% { clip-path: inset(88% 0 4% 0); }
100% { clip-path: inset(56% 0 24% 0); }
}
@keyframes glitch-anim-2 {
0% { clip-path: inset(24% 0 56% 0); }
20% { clip-path: inset(68% 0 12% 0); }
40% { clip-path: inset(8% 0 72% 0); }
60% { clip-path: inset(96% 0 4% 0); }
80% { clip-path: inset(48% 0 32% 0); }
100% { clip-path: inset(16% 0 64% 0); }
}
`;
document.head.appendChild(glitchStyle);
}
// ==========================================
// Scroll Progress Indicator
// ==========================================
const progressBar = document.createElement('div');
progressBar.className = 'scroll-progress';
document.body.appendChild(progressBar);
const progressStyle = document.createElement('style');
progressStyle.textContent = `
.scroll-progress {
position: fixed;
top: 0;
left: 0;
height: 3px;
background: linear-gradient(90deg, #6366f1, #8b5cf6, #ec4899);
width: 0%;
z-index: 10001;
transition: width 0.1s;
}
`;
document.head.appendChild(progressStyle);
window.addEventListener('scroll', () => {
const scrollTop = document.documentElement.scrollTop;
const scrollHeight = document.documentElement.scrollHeight - window.innerHeight;
const progress = (scrollTop / scrollHeight) * 100;
progressBar.style.width = progress + '%';
});
// ==========================================
// Magnetic Buttons
// ==========================================
const magneticBtns = document.querySelectorAll('.btn-glow');
magneticBtns.forEach(btn => {
btn.addEventListener('mousemove', (e) => {
const rect = btn.getBoundingClientRect();
const x = e.clientX - rect.left - rect.width / 2;
const y = e.clientY - rect.top - rect.height / 2;
btn.style.transform = `translate(${x * 0.2}px, ${y * 0.2}px)`;
});
btn.addEventListener('mouseleave', () => {
btn.style.transform = 'translate(0, 0)';
});
});
// ==========================================
// Typewriter Effect for Hero
// ==========================================
const typewriterText = document.querySelector('.hero-subtitle');
if (typewriterText && window.innerWidth > 768) {
const originalText = typewriterText.innerHTML;
const strongTags = typewriterText.querySelectorAll('strong');
// Highlight strong text on load with animation
strongTags.forEach((tag, index) => {
tag.style.opacity = '0';
tag.style.transform = 'translateY(10px)';
tag.style.transition = 'all 0.5s ease';
tag.style.transitionDelay = `${1 + index * 0.3}s`;
setTimeout(() => {
tag.style.opacity = '1';
tag.style.transform = 'translateY(0)';
}, 100);
});
}
// ==========================================
// Ripple Effect on Buttons
// ==========================================
const buttons = document.querySelectorAll('.btn');
buttons.forEach(button => {
button.addEventListener('click', function(e) {
const ripple = document.createElement('span');
const rect = this.getBoundingClientRect();
const size = Math.max(rect.width, rect.height);
const x = e.clientX - rect.left - size / 2;
const y = e.clientY - rect.top - size / 2;
ripple.style.cssText = `
position: absolute;
width: ${size}px;
height: ${size}px;
left: ${x}px;
top: ${y}px;
background: rgba(255, 255, 255, 0.3);
border-radius: 50%;
transform: scale(0);
animation: ripple 0.6s ease-out;
pointer-events: none;
`;
this.style.position = 'relative';
this.style.overflow = 'hidden';
this.appendChild(ripple);
setTimeout(() => ripple.remove(), 600);
});
});
const rippleStyle = document.createElement('style');
rippleStyle.textContent = `
@keyframes ripple {
to {
transform: scale(4);
opacity: 0;
}
}
`;
document.head.appendChild(rippleStyle);
});
// ==========================================
// Console Easter Egg
// ==========================================
console.log('%c AI Vertice ', 'background: linear-gradient(90deg, #6366f1, #8b5cf6); color: white; font-size: 24px; padding: 10px 20px; border-radius: 8px;');
console.log('%c Transformando dados com IA 🚀', 'color: #8b5cf6; font-size: 14px;');
// ==========================================
// Product Carousel Navigation
document.addEventListener('DOMContentLoaded', () => {
const showcase = document.querySelector('.products-showcase');
const dots = document.querySelectorAll('.product-nav-dot');
if (!showcase || !dots.length) return;
dots.forEach(dot => {
dot.addEventListener('click', () => {
const productId = dot.dataset.product;
const target = document.getElementById('product-' + productId);
if (target) {
target.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
dots.forEach(d => d.classList.remove('active'));
dot.classList.add('active');
}
});
});
// Update active dot on scroll
if ('IntersectionObserver' in window) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const id = entry.target.id.replace('product-', '');
dots.forEach(d => {
d.classList.toggle('active', d.dataset.product === id);
});
}
});
}, { root: showcase, threshold: 0.5 });
showcase.querySelectorAll('.product-hero').forEach(hero => observer.observe(hero));
}
});