|
|
|
|
|
document.getElementById('year').textContent = new Date().getFullYear(); |
|
|
|
|
|
|
|
|
const tiltCard = document.getElementById('tiltCard'); |
|
|
if (tiltCard) { |
|
|
let isHovering = false; |
|
|
|
|
|
tiltCard.addEventListener('mouseenter', () => { |
|
|
isHovering = true; |
|
|
}); |
|
|
|
|
|
tiltCard.addEventListener('mouseleave', () => { |
|
|
isHovering = false; |
|
|
tiltCard.style.transform = 'perspective(800px) rotateX(0deg) rotateY(0deg)'; |
|
|
}); |
|
|
|
|
|
tiltCard.addEventListener('mousemove', (e) => { |
|
|
if (!isHovering) return; |
|
|
|
|
|
const rect = tiltCard.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) / 10; |
|
|
const rotateY = (centerX - x) / 10; |
|
|
|
|
|
tiltCard.style.transform = `perspective(800px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; |
|
|
|
|
|
|
|
|
const xPercent = (x / rect.width) * 100; |
|
|
const yPercent = (y / rect.height) * 100; |
|
|
tiltCard.style.setProperty('--mx', `${xPercent}%`); |
|
|
tiltCard.style.setProperty('--my', `${yPercent}%`); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
const magneticButtons = document.querySelectorAll('.magnetic-button'); |
|
|
magneticButtons.forEach(button => { |
|
|
let mousePosition = { x: 0, y: 0 }; |
|
|
let buttonPosition = { x: 0, y: 0 }; |
|
|
|
|
|
button.addEventListener('mousemove', (e) => { |
|
|
const rect = button.getBoundingClientRect(); |
|
|
mousePosition = { x: e.clientX - rect.left, y: e.clientY - rect.top }; |
|
|
|
|
|
|
|
|
const centerX = rect.width / 2; |
|
|
const centerY = rect.height / 2; |
|
|
const deltaX = (mousePosition.x - centerX) * 0.3; |
|
|
const deltaY = (mousePosition.y - centerY) * 0.3; |
|
|
|
|
|
button.style.transform = `translate(${deltaX}px, ${deltaY}px)`; |
|
|
}); |
|
|
|
|
|
button.addEventListener('mouseleave', () => { |
|
|
button.style.transform = 'translate(0px, 0px)'; |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
const rippleButtons = document.querySelectorAll('.ripple-button'); |
|
|
rippleButtons.forEach(button => { |
|
|
button.addEventListener('click', function(e) { |
|
|
|
|
|
const existingRipple = this.querySelector('.ripple'); |
|
|
if (existingRipple) { |
|
|
existingRipple.remove(); |
|
|
} |
|
|
|
|
|
|
|
|
const ripple = document.createElement('span'); |
|
|
ripple.classList.add('ripple'); |
|
|
this.appendChild(ripple); |
|
|
|
|
|
|
|
|
const rect = this.getBoundingClientRect(); |
|
|
const x = e.clientX - rect.left; |
|
|
const y = e.clientY - rect.top; |
|
|
|
|
|
ripple.style.setProperty('--x', `${x}px`); |
|
|
ripple.style.setProperty('--y', `${y}px`); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
ripple.remove(); |
|
|
}, 800); |
|
|
}); |
|
|
}); |
|
|
|
|
|
const ringInput = document.getElementById('ringInput'); |
|
|
const ringProgress = document.getElementById('ringProgress'); |
|
|
const ringPercent = document.getElementById('ringPercent'); |
|
|
|
|
|
if (ringInput && ringProgress && ringPercent) { |
|
|
const updateRing = (value) => { |
|
|
const num = Math.max(0, Math.min(100, parseInt(value) || 0)); |
|
|
ringProgress.style.setProperty('--progress', num); |
|
|
ringPercent.textContent = `${num}%`; |
|
|
|
|
|
|
|
|
if (num > 0) { |
|
|
ringProgress.style.boxShadow = '0 0 20px rgba(148, 163, 184, 0.3)'; |
|
|
} else { |
|
|
ringProgress.style.boxShadow = 'none'; |
|
|
} |
|
|
}; |
|
|
|
|
|
ringInput.addEventListener('input', (e) => { |
|
|
const value = e.target.value.replace(/[^\d]/g, ''); |
|
|
ringInput.value = value; |
|
|
|
|
|
if (value === '' || /^\d+$/.test(value)) { |
|
|
updateRing(value); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
ringInput.addEventListener('keypress', (e) => { |
|
|
if (e.key === 'Enter') { |
|
|
e.preventDefault(); |
|
|
updateRing(ringInput.value); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
updateRing('0'); |
|
|
} |
|
|
|
|
|
const ringReset = document.getElementById('ringReset'); |
|
|
if (ringReset && ringInput) { |
|
|
ringReset.addEventListener('click', () => { |
|
|
ringInput.value = ''; |
|
|
if (ringProgress) { |
|
|
ringProgress.style.setProperty('--progress', 0); |
|
|
} |
|
|
if (ringPercent) { |
|
|
ringPercent.textContent = '0%'; |
|
|
} |
|
|
ringInput.focus(); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
const magneticBtn = document.getElementById('magneticBtn'); |
|
|
if (magneticBtn) { |
|
|
magneticBtn.addEventListener('click', () => { |
|
|
|
|
|
const demoSection = document.getElementById('demo'); |
|
|
if (demoSection) { |
|
|
demoSection.scrollIntoView({ behavior: 'smooth' }); |
|
|
} |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
const form = document.getElementById('notifyForm'); |
|
|
const nameInput = document.getElementById('name'); |
|
|
const emailInput = document.getElementById('email'); |
|
|
const messageInput = document.getElementById('message'); |
|
|
const formProgress = document.getElementById('formProgress'); |
|
|
const charCount = document.getElementById('charCount'); |
|
|
|
|
|
if (form && nameInput && emailInput) { |
|
|
const updateFormProgress = () => { |
|
|
let progress = 0; |
|
|
const maxLength = 200; |
|
|
|
|
|
|
|
|
if (nameInput.value.trim().length > 0) progress += 33; |
|
|
|
|
|
|
|
|
if (emailInput.value.trim().length > 0) { |
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; |
|
|
if (emailRegex.test(emailInput.value)) { |
|
|
progress += 33; |
|
|
} else { |
|
|
progress += 16; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (messageInput && messageInput.value.trim().length > 0) { |
|
|
const messageProgress = Math.min(34, (messageInput.value.length / maxLength) * 34); |
|
|
progress += messageProgress; |
|
|
} |
|
|
|
|
|
|
|
|
if (formProgress) { |
|
|
formProgress.style.width = `${Math.round(progress)}%`; |
|
|
formProgress.nextElementSibling.textContent = `${Math.round(progress)}%`; |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
if (messageInput && charCount) { |
|
|
messageInput.addEventListener('input', () => { |
|
|
const length = messageInput.value.length; |
|
|
charCount.textContent = `${length} / 200`; |
|
|
|
|
|
if (length > 200) { |
|
|
messageInput.value = messageInput.value.substring(0, 200); |
|
|
charCount.textContent = `200 / 200`; |
|
|
} |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
[nameInput, emailInput, messageInput].forEach(input => { |
|
|
if (input) { |
|
|
input.addEventListener('input', updateFormProgress); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
form.addEventListener('submit', (e) => { |
|
|
e.preventDefault(); |
|
|
|
|
|
const name = nameInput.value.trim(); |
|
|
const email = emailInput.value.trim(); |
|
|
const message = messageInput ? messageInput.value.trim() : ''; |
|
|
|
|
|
|
|
|
if (!name) { |
|
|
alert('Please enter your name'); |
|
|
nameInput.focus(); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (!email) { |
|
|
alert('Please enter your email'); |
|
|
emailInput.focus(); |
|
|
return; |
|
|
} |
|
|
|
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; |
|
|
if (!emailRegex.test(email)) { |
|
|
alert('Please enter a valid email address'); |
|
|
emailInput.focus(); |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
const submitBtn = form.querySelector('button[type="submit"]'); |
|
|
const originalText = submitBtn.textContent; |
|
|
|
|
|
submitBtn.textContent = 'Submitting...'; |
|
|
submitBtn.disabled = true; |
|
|
|
|
|
setTimeout(() => { |
|
|
alert('Thank you! We\'ll keep you updated.'); |
|
|
form.reset(); |
|
|
if (formProgress) { |
|
|
formProgress.style.width = '0%'; |
|
|
formProgress.nextElementSibling.textContent = '0%'; |
|
|
} |
|
|
if (charCount) { |
|
|
charCount.textContent = '0 / 200'; |
|
|
} |
|
|
submitBtn.textContent = originalText; |
|
|
submitBtn.disabled = false; |
|
|
}, 1500); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', () => { |
|
|
updateFormProgress(); |
|
|
|
|
|
|
|
|
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' |
|
|
}); |
|
|
} |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', () => { |
|
|
|
|
|
const tiltCard = document.getElementById('tiltCard'); |
|
|
if (tiltCard) { |
|
|
setTimeout(() => { |
|
|
tiltCard.style.opacity = '1'; |
|
|
tiltCard.style.transform = 'perspective(800px) translateY(0px)'; |
|
|
}, 100); |
|
|
} |
|
|
|
|
|
|
|
|
const animatedElements = document.querySelectorAll('.rounded-2xl'); |
|
|
animatedElements.forEach((el, index) => { |
|
|
el.style.opacity = '0'; |
|
|
el.style.transform = 'translateY(20px)'; |
|
|
el.style.transition = 'opacity 0.5s ease, transform 0.5s ease'; |
|
|
|
|
|
setTimeout(() => { |
|
|
el.style.opacity = '1'; |
|
|
el.style.transform = 'translateY(0px)'; |
|
|
}, 200 + (index * 100)); |
|
|
}); |
|
|
}); |