document.addEventListener('DOMContentLoaded', function() {
// Luxury Cursor System
class PremiumCursor {
constructor() {
this.cursor = document.createElement('div');
this.cursorFollower = document.createElement('div');
this.cursorInner = document.createElement('div');
this.cursorText = document.createElement('div');
this.posX = 0;
this.posY = 0;
this.mouseX = 0;
this.mouseY = 0;
this.isHovering = false;
this.isClicking = false;
this.currentText = '';
this.initCursor();
this.initEvents();
this.animate();
this.addHoverTextEffects();
}
initCursor() {
// Outer circle (magnetic field)
this.cursor.style.position = 'fixed';
this.cursor.style.width = '48px';
this.cursor.style.height = '48px';
this.cursor.style.border = '1px solid rgba(14, 165, 233, 0.3)';
this.cursor.style.borderRadius = '50%';
this.cursor.style.pointerEvents = 'none';
this.cursor.style.zIndex = '9999';
this.cursor.style.transform = 'translate(-50%, -50%) scale(0)';
this.cursor.style.transition = 'transform 0.4s cubic-bezier(0.33, 1, 0.68, 1), border-color 0.4s ease, width 0.4s ease, height 0.4s ease';
this.cursor.style.mixBlendMode = 'exclusion';
// Follower
this.cursorFollower.style.position = 'fixed';
this.cursorFollower.style.width = '12px';
this.cursorFollower.style.height = '12px';
this.cursorFollower.style.backgroundColor = 'rgba(14, 165, 233, 0.8)';
this.cursorFollower.style.borderRadius = '50%';
this.cursorFollower.style.pointerEvents = 'none';
this.cursorFollower.style.zIndex = '10000';
this.cursorFollower.style.transform = 'translate(-50%, -50%)';
this.cursorFollower.style.transition = 'transform 0.1s ease, background-color 0.3s ease';
// Inner dot
this.cursorInner.style.position = 'fixed';
this.cursorInner.style.width = '4px';
this.cursorInner.style.height = '4px';
this.cursorInner.style.backgroundColor = 'rgba(255, 255, 255, 0.9)';
this.cursorInner.style.borderRadius = '50%';
this.cursorInner.style.pointerEvents = 'none';
this.cursorInner.style.zIndex = '10001';
this.cursorInner.style.transform = 'translate(-50%, -50%)';
document.body.appendChild(this.cursor);
document.body.appendChild(this.cursorFollower);
document.body.appendChild(this.cursorInner);
}
initEvents() {
document.addEventListener('mousemove', (e) => {
this.mouseX = e.clientX;
this.mouseY = e.clientY;
this.cursorInner.style.left = `${this.mouseX}px`;
this.cursorInner.style.top = `${this.mouseY}px`;
});
const interactiveElements = document.querySelectorAll('a, button, [data-interactive], .professional-btn, .professional-card');
interactiveElements.forEach(el => {
el.addEventListener('mouseenter', () => {
this.isHovering = true;
this.cursor.style.borderColor = 'rgba(124, 58, 237, 0.8)';
this.cursor.style.transform = 'translate(-50%, -50%) scale(1.2)';
this.cursorFollower.style.transform = 'translate(-50%, -50%) scale(0.5)';
this.cursorFollower.style.backgroundColor = 'rgba(124, 58, 237, 0.6)';
});
el.addEventListener('mouseleave', () => {
this.isHovering = false;
this.cursor.style.borderColor = 'rgba(14, 165, 233, 0.5)';
this.cursor.style.transform = 'translate(-50%, -50%) scale(1)';
this.cursorFollower.style.transform = 'translate(-50%, -50%) scale(1)';
this.cursorFollower.style.backgroundColor = 'rgba(14, 165, 233, 0.8)';
});
});
}
animate() {
this.posX += (this.mouseX - this.posX) / 6;
this.posY += (this.mouseY - this.posY) / 6;
this.cursor.style.left = `${this.posX}px`;
this.cursor.style.top = `${this.posY}px`;
this.cursorFollower.style.left = `${this.posX}px`;
this.cursorFollower.style.top = `${this.posY}px`;
requestAnimationFrame(() => this.animate());
}
}
// Initialize luxury cursor system
const luxuryCursor = new PremiumCursor();
// Add click animation
document.addEventListener('mousedown', () => {
luxuryCursor.startClick();
});
document.addEventListener('mouseup', () => {
luxuryCursor.endClick();
});
const cursorTrail = document.createElement('div');
cursorTrail.style.position = 'fixed';
cursorTrail.style.width = '24px';
cursorTrail.style.height = '24px';
cursorTrail.style.background = 'radial-gradient(circle, rgba(124,58,237,0.8) 0%, rgba(14,165,233,0.4) 70%, transparent 100%)';
cursorTrail.style.borderRadius = '50%';
cursorTrail.style.pointerEvents = 'none';
cursorTrail.style.zIndex = '9999';
cursorTrail.style.transform = 'translate(-50%, -50%) scale(0)';
cursorTrail.style.mixBlendMode = 'overlay';
cursorTrail.style.transition = 'transform 0.2s cubic-bezier(0.25, 0.1, 0.25, 1)';
cursorTrail.style.filter = 'blur(1px)';
document.body.appendChild(cursorTrail);
// Professional cursor dot
const cursorDot = document.createElement('div');
cursorDot.style.position = 'fixed';
cursorDot.style.width = '6px';
cursorDot.style.height = '6px';
cursorDot.style.backgroundColor = 'rgba(124,58,237,0.9)';
cursorDot.style.borderRadius = '50%';
cursorDot.style.pointerEvents = 'none';
cursorDot.style.zIndex = '10000';
cursorDot.style.transform = 'translate(-50%, -50%)';
document.body.appendChild(cursorDot);
let posX = 0, posY = 0;
let mouseX = 0, mouseY = 0;
let isHovering = false;
document.addEventListener('mousemove', (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
cursorDot.style.left = `${mouseX}px`;
cursorDot.style.top = `${mouseY}px`;
});
const updateCursor = () => {
posX += (mouseX - posX) / 6;
posY += (mouseY - posY) / 6;
cursorTrail.style.left = `${posX}px`;
cursorTrail.style.top = `${posY}px`;
cursorTrail.style.transform = `translate(-50%, -50%) scale(${isHovering ? 1.5 : 1})`;
requestAnimationFrame(updateCursor);
};
updateCursor();
// Professional hover effect for interactive elements
const interactiveElements = document.querySelectorAll('a, button, [data-interactive], .professional-btn, .professional-card');
interactiveElements.forEach(el => {
el.addEventListener('mouseenter', () => {
isHovering = true;
cursorTrail.style.background = 'radial-gradient(circle, rgba(255,255,255,0.9) 0%, rgba(124,58,237,0.7) 70%, transparent 100%)';
cursorTrail.style.filter = 'blur(1.5px)';
cursorDot.style.transform = 'translate(-50%, -50%) scale(1.5)';
cursorDot.style.backgroundColor = 'rgba(255,255,255,0.9)';
});
el.addEventListener('mouseleave', () => {
isHovering = false;
cursorTrail.style.background = 'radial-gradient(circle, rgba(124,58,237,0.8) 0%, rgba(14,165,233,0.4) 70%, transparent 100%)';
cursorTrail.style.filter = 'blur(1px)';
cursorDot.style.transform = 'translate(-50%, -50%) scale(1)';
cursorDot.style.backgroundColor = 'rgba(124,58,237,0.9)';
});
});
// Smooth scrolling for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const targetId = this.getAttribute('href');
if (targetId === '#') return;
const targetElement = document.querySelector(targetId);
if (targetElement) {
targetElement.scrollIntoView({
behavior: 'smooth'
});
}
});
});
// Artwork modal functionality
const artworkModal = document.createElement('artwork-modal');
document.body.appendChild(artworkModal);
const artworkButtons = document.querySelectorAll('.professional-card button');
artworkButtons.forEach((button, index) => {
button.addEventListener('click', () => {
const card = button.closest('.professional-card');
const img = card.querySelector('img');
const title = card.querySelector('h3').textContent;
const meta = card.querySelector('p').textContent;
artworkModal.open({
image: img.src,
title: title,
medium: meta.split('|')[0].trim(),
year: meta.split('|')[1].trim(),
description: 'This artwork represents a unique blend of digital techniques and creative vision. Each element was carefully crafted to evoke emotion and tell a visual story.'
});
});
});
// Form submission
const contactForm = document.querySelector('form');
if (contactForm) {
contactForm.addEventListener('submit', function(e) {
e.preventDefault();
// Show success state
const submitButton = this.querySelector('button[type="submit"]');
submitButton.innerHTML = ' Message Sent';
submitButton.disabled = true;
// Add micro-interaction
gsap.to(submitButton, {
scale: 0.95,
duration: 0.2,
yoyo: true,
repeat: 1,
ease: "power1.inOut",
onComplete: () => {
setTimeout(() => {
this.reset();
submitButton.innerHTML = 'Send Message ';
submitButton.disabled = false;
feather.replace();
}, 2000);
}
});
feather.replace();
});
}
// Enhanced Intersection Observer for animations
const animateOnScroll = () => {
const elements = document.querySelectorAll('[data-animate]');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const animationType = entry.target.getAttribute('data-animate');
const delay = entry.target.getAttribute('data-delay') || '0';
entry.target.style.setProperty('--delay', delay);
entry.target.classList.add(`animate-${animationType}`);
// Remove observer if not a repeating animation
if (!entry.target.hasAttribute('data-repeat')) {
observer.unobserve(entry.target);
}
} else if (entry.target.hasAttribute('data-repeat')) {
entry.target.classList.remove(`animate-${animationType}`);
}
});
}, {
threshold: 0.1,
rootMargin: '-50px'
});
elements.forEach(element => {
observer.observe(element);
});
};
// Parallax effect for hero background
const heroSection = document.querySelector('.hero-section');
if (heroSection) {
window.addEventListener('scroll', () => {
const scrollPosition = window.pageYOffset;
heroSection.style.backgroundPositionY = `${scrollPosition * 0.5}px`;
});
}
// Hover tilt effect for artwork cards
const artworkCards = document.querySelectorAll('.artwork-card');
artworkCards.forEach(card => {
card.addEventListener('mousemove', (e) => {
const xAxis = (window.innerWidth / 2 - e.pageX) / 25;
const yAxis = (window.innerHeight / 2 - e.pageY) / 25;
card.style.transform = `rotateY(${xAxis}deg) rotateX(${yAxis}deg)`;
});
card.addEventListener('mouseenter', () => {
card.style.transition = 'transform 0.1s ease';
});
card.addEventListener('mouseleave', () => {
card.style.transition = 'transform 0.5s ease';
card.style.transform = 'rotateY(0deg) rotateX(0deg)';
});
});
// Initialize animations
animateOnScroll();
// Animate elements when they become visible
const animatedElements = document.querySelectorAll('[data-animate-on-visible]');
const visibilityObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, { threshold: 0.1 });
animatedElements.forEach(element => {
visibilityObserver.observe(element);
});
// Premium text reveal animation
const textRevealElements = document.querySelectorAll('.text-reveal');
textRevealElements.forEach(element => {
const words = element.textContent.split(' ');
element.innerHTML = words.map(word =>
`${word.split('').map(letter =>
`${letter}`
).join('')}`
).join(' ');
const chars = element.querySelectorAll('.text-reveal-char');
const wordsContainers = element.querySelectorAll('.text-reveal-word');
// Character animation
gsap.from(chars, {
y: '120%',
opacity: 0,
duration: 0.8,
ease: 'back.out(1.7)',
stagger: {
each: 0.02,
from: 'random'
},
scrollTrigger: {
trigger: element,
start: 'top 85%',
toggleActions: 'play none none none'
}
});
// Word container animation
gsap.from(wordsContainers, {
y: '20px',
opacity: 0,
duration: 1.2,
ease: 'power3.out',
stagger: 0.08,
scrollTrigger: {
trigger: element,
start: 'top 85%',
toggleActions: 'play none none none'
}
});
});
// Add subtle parallax to hero section
const heroSection = document.querySelector('.hero-section');
if (heroSection) {
const bgElements = heroSection.querySelectorAll('div[style*="background"]');
window.addEventListener('scroll', () => {
const scrollY = window.scrollY;
const speed = 0.3;
bgElements.forEach((el, index) => {
const yPos = -(scrollY * speed * (index + 1) * 0.5);
gsap.to(el, {
y: yPos,
ease: 'none'
});
});
});
}
});