// Initialize on DOM load
document.addEventListener('DOMContentLoaded', function() {
// Generate stars for parallax background
generateStars();
// Initialize gallery
populateGallery();
// Initialize counters
initCounters();
// Initialize form
initContactForm();
// Initialize scroll effects
initScrollEffects();
// Initialize parallax
initParallax();
// Initialize typewriter effect
initTypewriter();
});
// Initialize typewriter effect
function initTypewriter() {
const texts = [
"Where Dreams Meet Digital Reality",
"Where Innovation Meets Imagination",
"Where Code Meets Creativity",
"Where Vision Meets Technology"
];
let textIndex = 0;
let charIndex = 0;
let isDeleting = false;
let typewriterElement = document.getElementById('typewriter-text');
if (!typewriterElement) return;
function type() {
const currentText = texts[textIndex];
if (isDeleting) {
typewriterElement.textContent = currentText.substring(0, charIndex - 1);
charIndex--;
} else {
typewriterElement.textContent = currentText.substring(0, charIndex + 1);
charIndex++;
}
let typeSpeed = isDeleting ? 50 : 100;
if (!isDeleting && charIndex === currentText.length) {
typeSpeed = 2000; // Pause at end
isDeleting = true;
} else if (isDeleting && charIndex === 0) {
isDeleting = false;
textIndex = (textIndex + 1) % texts.length;
typeSpeed = 500; // Pause before typing new text
}
setTimeout(type, typeSpeed);
}
// Start the typewriter effect
type();
}
// Generate animated stars
function generateStars() {
const parallaxBg = document.getElementById('parallaxBg');
const starCount = 100;
for (let i = 0; i < starCount; i++) {
const star = document.createElement('div');
star.className = 'star';
star.style.width = Math.random() * 3 + 'px';
star.style.height = star.style.width;
star.style.left = Math.random() * 100 + '%';
star.style.top = Math.random() * 100 + '%';
star.style.animationDelay = Math.random() * 3 + 's';
parallaxBg.appendChild(star);
}
}
// Populate gallery with dynamic content
function populateGallery() {
const gallery = document.getElementById('gallery');
const categories = ['nature', 'technology', 'abstract', 'cityscape', 'workspace', 'food'];
const colors = ['purple', 'blue', 'green', 'pink', 'yellow', 'red'];
for (let i = 0; i < 9; i++) {
const card = document.createElement('div');
const category = categories[i % categories.length];
const color = colors[i % colors.length];
const imageUrl = `https://static.photos/${category}/640x360/${i + 42}`;
card.className = 'card-hover glass-morphism rounded-2xl overflow-hidden group cursor-pointer';
card.innerHTML = `
`;
card.addEventListener('click', function() {
createParticleEffect(event);
});
gallery.appendChild(card);
}
}
// Initialize animated counters
function initCounters() {
const counters = document.querySelectorAll('.counter');
const speed = 200;
const observerOptions = {
threshold: 0.5
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const counter = entry.target;
const target = +counter.getAttribute('data-target');
const increment = target / speed;
const updateCount = () => {
const count = +counter.innerText;
if (count < target) {
counter.innerText = Math.ceil(count + increment);
setTimeout(updateCount, 1);
} else {
counter.innerText = target + '+';
}
};
updateCount();
observer.unobserve(counter);
}
});
}, observerOptions);
counters.forEach(counter => observer.observe(counter));
}
// Initialize contact form
function initContactForm() {
const form = document.getElementById('contactForm');
form.addEventListener('submit', function(e) {
e.preventDefault();
// Create success message
const successMsg = document.createElement('div');
successMsg.className = 'fixed top-20 right-6 bg-green-500 text-white px-6 py-3 rounded-lg shadow-lg z-50 fade-in';
successMsg.innerHTML = `
Message sent successfully!
`;
document.body.appendChild(successMsg);
feather.replace();
// Reset form
form.reset();
// Remove message after 3 seconds
setTimeout(() => {
successMsg.remove();
}, 3000);
// Create particle effect
createParticleEffect(e);
});
}
// Initialize scroll effects
function initScrollEffects() {
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('fade-in');
}
});
}, observerOptions);
document.querySelectorAll('section').forEach(section => {
observer.observe(section);
});
}
// Initialize parallax effect
function initParallax() {
window.addEventListener('scroll', () => {
const scrolled = window.pageYOffset;
const parallaxBg = document.getElementById('parallaxBg');
parallaxBg.style.transform = `translateY(${scrolled * 0.5}px)`;
});
}
// Create particle effect on click
function createParticleEffect(event) {
const colors = ['#9333ea', '#ec4899', '#3b82f6', '#10b981', '#f59e0b'];
const particleCount = 20;
for (let i = 0; i < particleCount; i++) {
const particle = document.createElement('div');
particle.className = 'particle';
const size = Math.random() * 8 + 4;
const color = colors[Math.floor(Math.random() * colors.length)];
const angle = (Math.PI * 2 * i) / particleCount;
const velocity = Math.random() * 100 + 50;
particle.style.width = size + 'px';
particle.style.height = size + 'px';
particle.style.backgroundColor = color;
particle.style.borderRadius = '50%';
particle.style.left = event.clientX + 'px';
particle.style.top = event.clientY + 'px';
particle.style.setProperty('--tx', Math.cos(angle) * velocity + 'px');
particle.style.setProperty('--ty', Math.sin(angle) * velocity + 'px');
document.body.appendChild(particle);
setTimeout(() => particle.remove(), 3000);
}
}
// Add cursor trail effect
document.addEventListener('mousemove', (e) => {
if (Math.random() > 0.98) {
const trail = document.createElement('div');
trail.className = 'fixed w-2 h-2 bg-purple-500 rounded-full pointer-events-none z-40';
trail.style.left = e.clientX + 'px';
trail.style.top = e.clientY + 'px';
trail.style.animation = 'fadeOut 1s ease-out forwards';
document.body.appendChild(trail);
setTimeout(() => trail.remove(), 1000);
}
});
// Earth interaction
function initEarthInteraction() {
const earthContainer = document.querySelector('.earth-container');
if (!earthContainer) return;
let mouseX = 0;
let mouseY = 0;
let currentX = 0;
let currentY = 0;
document.addEventListener('mousemove', (e) => {
const rect = earthContainer.getBoundingClientRect();
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
mouseX = (e.clientX - centerX) / 20;
mouseY = (e.clientY - centerY) / 20;
});
function animateEarth() {
currentX += (mouseX - currentX) * 0.1;
currentY += (mouseY - currentY) * 0.1;
const earthSphere = earthContainer.querySelector('.earth-sphere');
if (earthSphere) {
earthSphere.style.transform = `rotateY(${currentX}deg) rotateX(${-currentY}deg) rotateZ(-23.5deg)`;
}
requestAnimationFrame(animateEarth);
}
animateEarth();
// Add click event for earthquake effect
earthContainer.addEventListener('click', function(e) {
const earthSphere = this.querySelector('.earth-sphere');
earthSphere.style.animation = 'none';
setTimeout(() => {
earthSphere.style.animation = 'earthRotation 30s linear infinite, earthquake 0.5s ease-in-out';
}, 10);
setTimeout(() => {
earthSphere.style.animation = 'earthRotation 30s linear infinite';
}, 500);
createEarthParticles(e);
});
}
// Create Earth particles on click
function createEarthParticles(event) {
const colors = ['#4a90e2', '#228b22', '#87ceeb', '#ffffff'];
const particleCount = 15;
for (let i = 0; i < particleCount; i++) {
const particle = document.createElement('div');
particle.className = 'earth-particle';
const size = Math.random() * 6 + 2;
const color = colors[Math.floor(Math.random() * colors.length)];
const angle = (Math.PI * 2 * i) / particleCount;
const velocity = Math.random() * 80 + 40;
particle.style.width = size + 'px';
particle.style.height = size + 'px';
particle.style.backgroundColor = color;
particle.style.borderRadius = '50%';
particle.style.position = 'fixed';
particle.style.pointerEvents = 'none';
particle.style.zIndex = '1000';
particle.style.left = event.clientX + 'px';
particle.style.top = event.clientY + 'px';
particle.style.boxShadow = `0 0 10px ${color}`;
particle.style.setProperty('--tx', Math.cos(angle) * velocity + 'px');
particle.style.setProperty('--ty', Math.sin(angle) * velocity + 'px');
document.body.appendChild(particle);
setTimeout(() => particle.remove(), 2000);
}
}
// Add earthquake animation
const earthquakeStyle = document.createElement('style');
earthquakeStyle.textContent = `
@keyframes earthquake {
0%, 100% { transform: rotateY(0deg) rotateX(0deg) translateX(0); }
25% { transform: rotateY(2deg) rotateX(-1deg) translateX(-2px); }
50% { transform: rotateY(-1deg) rotateX(2deg) translateX(2px); }
75% { transform: rotateY(1deg) rotateX(-2deg) translateX(-1px); }
}
.earth-particle {
opacity: 1;
animation: earthParticleAnimation 2s ease-out forwards;
}
@keyframes earthParticleAnimation {
0% {
opacity: 1;
transform: translate(0, 0) scale(0);
}
50% {
opacity: 1;
transform: translate(var(--tx), var(--ty)) scale(1);
}
100% {
opacity: 0;
transform: translate(calc(var(--tx) * 1.5), calc(var(--ty) * 1.5)) scale(0.5);
}
}
`;
document.head.appendChild(earthquakeStyle);
// Initialize Earth interaction on DOM load
document.addEventListener('DOMContentLoaded', function() {
initEarthInteraction();
});
// Add keyboard navigation
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
window.scrollTo({ top: 0, behavior: 'smooth' });
}
});
// Performance optimization - Debounce scroll events
let scrollTimeout;
window.addEventListener('scroll', () => {
if (scrollTimeout) {
window.cancelAnimationFrame(scrollTimeout);
}
scrollTimeout = window.requestAnimationFrame(() => {
// Add any scroll-based animations here
});
});