// Main JavaScript for RoseRadiance Design Showcase class RoseRadianceApp { constructor() { this.init(); } init() { console.log('RoseRadiance Design Showcase initialized'); this.setupEventListeners(); this.enhanceUI(); this.loadDynamicContent(); this.initializeComponents(); } setupEventListeners() { // Smooth scroll for all anchor links document.addEventListener('click', (e) => { const link = e.target.closest('a'); if (link && link.hash && link.pathname === window.location.pathname) { e.preventDefault(); const target = document.querySelector(link.hash); if (target) { target.scrollIntoView({ behavior: 'smooth' }); } } }); // Back to top button window.addEventListener('scroll', this.debounce(() => { this.toggleBackToTopButton(); }, 100)); // Responsive image loading window.addEventListener('load', () => { this.lazyLoadImages(); }); // Theme support (future dark mode) window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { console.log('Theme preference changed to:', e.matches ? 'dark' : 'light'); }); } enhanceUI() { // Add hover effects to cards document.querySelectorAll('.hover-card').forEach(card => { card.addEventListener('mouseenter', () => { card.classList.add('shadow-xl', 'border-rose-200'); }); card.addEventListener('mouseleave', () => { card.classList.remove('shadow-xl', 'border-rose-200'); }); }); // Add click ripple effect to buttons document.querySelectorAll('button, a[role="button"]').forEach(button => { button.addEventListener('click', (e) => { this.createRippleEffect(e, button); }); }); } createRippleEffect(event, element) { const ripple = document.createElement('span'); const rect = element.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); const x = event.clientX - rect.left - size / 2; const y = event.clientY - rect.top - size / 2; ripple.style.cssText = ` position: absolute; border-radius: 50%; background: rgba(244, 63, 94, 0.3); transform: scale(0); animation: ripple-animation 600ms linear; width: ${size}px; height: ${size}px; top: ${y}px; left: ${x}px; pointer-events: none; `; // Add CSS animation if not exists if (!document.querySelector('#ripple-styles')) { const style = document.createElement('style'); style.id = 'ripple-styles'; style.textContent = ` @keyframes ripple-animation { to { transform: scale(4); opacity: 0; } } `; document.head.appendChild(style); } element.style.position = 'relative'; element.style.overflow = 'hidden'; element.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 600); } loadDynamicContent() { // This could be expanded to load content from APIs console.log('Loading dynamic content...'); // Example: Load featured designs this.loadFeaturedDesigns(); } loadFeaturedDesigns() { // Simulating API call setTimeout(() => { const designs = [ { id: 1, title: "Minimal Dashboard", category: "UI Design", likes: 42 }, { id: 2, title: "E-commerce Redesign", category: "Web Design", likes: 87 }, { id: 3, title: "Mobile App Icons", category: "App Design", likes: 63 } ]; console.log('Featured designs loaded:', designs); }, 1000); } lazyLoadImages() { const images = document.querySelectorAll('img[data-src]'); const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; img.removeAttribute('data-src'); observer.unobserve(img); } }); }); images.forEach(img => observer.observe(img)); } toggleBackToTopButton() { const scrollTop = window.pageYOffset || document.documentElement.scrollTop; const backToTop = document.querySelector('#back-to-top'); if (!backToTop) return; if (scrollTop > 300) { backToTop.classList.remove('opacity-0', 'invisible'); backToTop.classList.add('opacity-100', 'visible'); } else { backToTop.classList.remove('opacity-100', 'visible'); backToTop.classList.add('opacity-0', 'invisible'); } } initializeComponents() { // Initialize any custom components here this.initImageLightbox(); this.initSmoothTransitions(); } initImageLightbox() { // This would be expanded for a proper lightbox implementation console.log('Image lightbox ready'); } initSmoothTransitions() { // Add smooth transitions to elements document.querySelectorAll('.transition-element').forEach(element => { element.style.transition = 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)'; }); } debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } // Utility function for toast notifications showToast(message, type = 'success') { const toast = document.createElement('div'); toast.className = `fixed bottom-4 right-4 px-6 py-3 rounded-lg shadow-xl transform transition-all duration-300 translate-x-full ${this.getToastClass(type)}`; toast.textContent = message; document.body.appendChild(toast); setTimeout(() => { toast.classList.remove('translate-x-full'); }, 10); setTimeout(() => { toast.classList.add('translate-x-full'); setTimeout(() => toast.remove(), 300); }, 3000); } getToastClass(type) { const classes = { success: 'bg-gradient-to-r from-rose-100 to-pink-100 border border-rose-200 text-rose-700', error: 'bg-red-50 border border-red-200 text-red-700', info: 'bg-blue-50 border border-blue-200 text-blue-700', warning: 'bg-yellow-50 border border-yellow-200 text-yellow-700' }; return classes[type] || classes.info; } // Analytics tracking trackEvent(event, data = {}) { console.log(`Event tracked: ${event}`, data); // Here you would integrate with Google Analytics or similar } } // Initialize the app when DOM is ready document.addEventListener('DOMContentLoaded', () => { const app = new RoseRadianceApp(); // Make app available globally for debugging window.roseRadianceApp = app; }); // Service Worker Registration (optional) if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/sw.js').then(registration => { console.log('SW registered:', registration); }).catch(registrationError => { console.log('SW registration failed:', registrationError); }); }); } // Image Gallery Helper Function function loadGalleryImages(category = 'all') { return fetch(`https://api.example.com/gallery/${category}`) .then(response => response.json()) .catch(error => { console.error('Error loading gallery images:', error); return []; }); } // Form Validation Helper function validateForm(form) { let isValid = true; const inputs = form.querySelectorAll('input[required], textarea[required]'); inputs.forEach(input => { if (!input.value.trim()) { isValid = false; input.classList.add('border-red-500'); input.classList.remove('border-rose-200'); } else { input.classList.remove('border-red-500'); input.classList.add('border-rose-200'); } }); return isValid; }