| | |
| | 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)); |
| | }); |
| | }); |