// Sky Art Shop - Main JavaScript File // ==================================== // Mobile Navigation Toggle // ==================================== document.addEventListener("DOMContentLoaded", function () { const navToggle = document.querySelector(".nav-toggle"); const navMenu = document.querySelector("#navDropdown"); if (navToggle && navMenu) { // Hover to open dropdown navToggle.addEventListener("mouseenter", function () { navMenu.classList.add("active"); this.setAttribute("aria-expanded", "true"); const spans = this.querySelectorAll("span"); spans[0].style.transform = "rotate(45deg) translate(7px, 7px)"; spans[1].style.opacity = "0"; spans[2].style.transform = "rotate(-45deg) translate(7px, -7px)"; }); // Keep dropdown open when hovering over it navMenu.addEventListener("mouseenter", function () { this.classList.add("active"); }); // Close when mouse leaves both hamburger and dropdown navToggle.addEventListener("mouseleave", function (e) { // Delay closing to allow moving to dropdown setTimeout(() => { if (!navMenu.matches(":hover") && !navToggle.matches(":hover")) { navMenu.classList.remove("active"); navToggle.setAttribute("aria-expanded", "false"); const spans = navToggle.querySelectorAll("span"); spans[0].style.transform = "none"; spans[1].style.opacity = "1"; spans[2].style.transform = "none"; } }, 200); }); navMenu.addEventListener("mouseleave", function () { setTimeout(() => { if (!navMenu.matches(":hover") && !navToggle.matches(":hover")) { navMenu.classList.remove("active"); navToggle.setAttribute("aria-expanded", "false"); const spans = navToggle.querySelectorAll("span"); spans[0].style.transform = "none"; spans[1].style.opacity = "1"; spans[2].style.transform = "none"; } }, 200); }); // Click to toggle (for mobile/touch) navToggle.addEventListener("click", function (e) { e.stopPropagation(); const isActive = navMenu.classList.toggle("active"); this.setAttribute("aria-expanded", isActive ? "true" : "false"); // Animate hamburger menu const spans = this.querySelectorAll("span"); if (isActive) { spans[0].style.transform = "rotate(45deg) translate(7px, 7px)"; spans[1].style.opacity = "0"; spans[2].style.transform = "rotate(-45deg) translate(7px, -7px)"; } else { spans[0].style.transform = "none"; spans[1].style.opacity = "1"; spans[2].style.transform = "none"; } }); // Close dropdown when clicking on a link const dropdownLinks = navMenu.querySelectorAll("a"); dropdownLinks.forEach((link) => { link.addEventListener("click", function () { navMenu.classList.remove("active"); navToggle.setAttribute("aria-expanded", "false"); const spans = navToggle.querySelectorAll("span"); spans[0].style.transform = "none"; spans[1].style.opacity = "1"; spans[2].style.transform = "none"; }); }); // Close dropdown when clicking outside document.addEventListener("click", function (event) { // Don't close if clicking on cart/wishlist dropdowns if ( event.target.closest(".dropdown-container") || event.target.closest(".icon-dropdown") ) { return; } const isClickInside = navToggle.contains(event.target) || navMenu.contains(event.target); if (!isClickInside && navMenu.classList.contains("active")) { navMenu.classList.remove("active"); navToggle.setAttribute("aria-expanded", "false"); const spans = navToggle.querySelectorAll("span"); spans[0].style.transform = "none"; spans[1].style.opacity = "1"; spans[2].style.transform = "none"; } }); } }); // ==================================== // Smooth Scrolling for Anchor Links // ==================================== document.querySelectorAll('a[href^="#"]').forEach((anchor) => { anchor.addEventListener("click", function (e) { const href = this.getAttribute("href"); if (href !== "#" && href !== "#instagram" && href !== "#wishlist") { e.preventDefault(); const target = document.querySelector(href); if (target) { target.scrollIntoView({ behavior: "smooth", block: "start", }); } } }); }); // ==================================== // Shop Page Filtering // ==================================== const categoryFilter = document.getElementById("category-filter"); const sortFilter = document.getElementById("sort-filter"); if (categoryFilter) { categoryFilter.addEventListener("change", function () { const selectedCategory = this.value; const productCards = document.querySelectorAll(".product-card"); productCards.forEach((card) => { if (selectedCategory === "all") { card.style.display = "block"; } else { const cardCategory = card.getAttribute("data-category"); if (cardCategory === selectedCategory) { card.style.display = "block"; } else { card.style.display = "none"; } } }); }); } if (sortFilter) { sortFilter.addEventListener("change", function () { const sortValue = this.value; const productsGrid = document.querySelector(".products-grid"); const productCards = Array.from(document.querySelectorAll(".product-card")); if (sortValue === "price-low") { productCards.sort((a, b) => { const priceA = parseFloat( a.querySelector(".price").textContent.replace("$", "") ); const priceB = parseFloat( b.querySelector(".price").textContent.replace("$", "") ); return priceA - priceB; }); } else if (sortValue === "price-high") { productCards.sort((a, b) => { const priceA = parseFloat( a.querySelector(".price").textContent.replace("$", "") ); const priceB = parseFloat( b.querySelector(".price").textContent.replace("$", "") ); return priceB - priceA; }); } // Re-append sorted cards productCards.forEach((card) => { productsGrid.appendChild(card); }); }); } // ==================================== // Add to Cart Functionality (Basic) // ==================================== document.querySelectorAll(".product-card .btn").forEach((button) => { button.addEventListener("click", function (e) { e.preventDefault(); // Get product details const productCard = this.closest(".product-card"); const productName = productCard.querySelector("h3").textContent; const productPrice = productCard.querySelector(".price").textContent; // Show notification showNotification(`${productName} added to cart!`); // You can expand this to actually store cart items // For example, using localStorage or sending to a server }); }); // ==================================== // Contact Form Handling // ==================================== const contactForm = document.getElementById("contactForm"); if (contactForm) { contactForm.addEventListener("submit", function (e) { e.preventDefault(); // Get form values const name = document.getElementById("name").value; const email = document.getElementById("email").value; const phone = document.getElementById("phone").value; const subject = document.getElementById("subject").value; const message = document.getElementById("message").value; // Basic validation if (!name || !email || !subject || !message) { showNotification("Please fill in all required fields!", "error"); return; } // Email validation const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(email)) { showNotification("Please enter a valid email address!", "error"); return; } // Here you would typically send the form data to a server // For now, we'll just show a success message showNotification( "Thank you! Your message has been sent. We'll get back to you soon.", "success" ); // Reset form contactForm.reset(); }); } // ==================================== // Notification System // ==================================== function showNotification(message, type = "success") { // Create notification element const notification = document.createElement("div"); notification.className = `notification notification-${type}`; notification.textContent = message; // Style the notification notification.style.cssText = ` position: fixed; top: 100px; right: 20px; background-color: ${type === "success" ? "#4CAF50" : "#F44336"}; color: white; padding: 15px 25px; border-radius: 5px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); z-index: 10000; animation: slideIn 0.3s ease-out; `; // Add animation const style = document.createElement("style"); style.textContent = ` @keyframes slideIn { from { transform: translateX(400px); opacity: 0; } to { transform: translateX(0); opacity: 1; } } @keyframes slideOut { from { transform: translateX(0); opacity: 1; } to { transform: translateX(400px); opacity: 0; } } `; document.head.appendChild(style); // Add to page document.body.appendChild(notification); // Remove after 3 seconds setTimeout(() => { notification.style.animation = "slideOut 0.3s ease-out"; setTimeout(() => { notification.remove(); }, 300); }, 3000); } // ==================================== // Image Lazy Loading (Optional Enhancement) // ==================================== if ("IntersectionObserver" in window) { const imageObserver = new IntersectionObserver((entries, observer) => { entries.forEach((entry) => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src || img.src; img.classList.add("loaded"); observer.unobserve(img); } }); }); document.querySelectorAll("img").forEach((img) => { imageObserver.observe(img); }); } // ==================================== // Scroll to Top Button // ==================================== function createScrollToTopButton() { const button = document.createElement("button"); button.innerHTML = "↑"; button.className = "scroll-to-top"; button.style.cssText = ` position: fixed; bottom: 30px; right: 30px; width: 50px; height: 50px; background-color: #6B4E9B; color: white; border: none; border-radius: 50%; font-size: 24px; cursor: pointer; display: none; z-index: 1000; transition: all 0.3s ease; box-shadow: 0 4px 6px rgba(0,0,0,0.1); `; document.body.appendChild(button); // Show/hide button based on scroll position window.addEventListener("scroll", () => { if (window.pageYOffset > 300) { button.style.display = "block"; } else { button.style.display = "none"; } }); // Scroll to top when clicked button.addEventListener("click", () => { window.scrollTo({ top: 0, behavior: "smooth", }); }); // Hover effect button.addEventListener("mouseenter", () => { button.style.backgroundColor = "#5a3e82"; button.style.transform = "translateY(-3px)"; }); button.addEventListener("mouseleave", () => { button.style.backgroundColor = "#6B4E9B"; button.style.transform = "translateY(0)"; }); } // Initialize scroll to top button createScrollToTopButton(); // ==================================== // Portfolio Gallery Hover Effects // ==================================== document.querySelectorAll(".portfolio-category").forEach((category) => { category.addEventListener("mouseenter", function () { this.style.transition = "all 0.3s ease"; }); }); // ==================================== // Active Navigation Link Highlighting // ==================================== function highlightActiveNavLink() { const currentPage = window.location.pathname.split("/").pop() || "index.html"; const navLinks = document.querySelectorAll(".nav-menu a"); navLinks.forEach((link) => { const linkPage = link.getAttribute("href").split("/").pop().split("#")[0]; if (linkPage === currentPage) { link.classList.add("active"); } }); } highlightActiveNavLink(); // ==================================== // Print console message // ==================================== console.log( "%c Sky Art Shop Website ", "background: #6B4E9B; color: white; font-size: 20px; padding: 10px;" ); console.log("Welcome to Sky Art Shop! 🎨");