Files
SkyArtShop/Sky_Art_shop/wwwroot/assets/js/main.js

428 lines
13 KiB
JavaScript
Raw Normal View History

// 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! 🎨");