/* ================================
EFE PERFORE - MAIN JAVASCRIPT
Modern Web Sitesi İçin JS
================================ */
(function($) {
'use strict';
// DOM Ready
$(document).ready(function() {
// Initialize all modern functions
initScrollProgress();
initMobileMenu();
initModernGallery();
initNavigation();
initAnimations();
initCounters();
initForms();
initLightbox();
initSliders();
initBackToTop();
initWhatsApp();
initLazyLoading();
initSmoothScroll();
initTooltips();
initProductFilters();
initParallaxEffects();
});
// Navigation Functions
function initNavigation() {
// Navbar scroll effect
$(window).scroll(function() {
if ($(this).scrollTop() > 50) {
$('.navbar').addClass('scrolled');
} else {
$('.navbar').removeClass('scrolled');
}
});
// Mobile menu toggle
$('.navbar-toggler').click(function() {
$(this).toggleClass('active');
});
// Dropdown hover effect (desktop only)
if ($(window).width() > 991) {
$('.dropdown').hover(
function() {
$(this).addClass('show');
$(this).find('.dropdown-menu').addClass('show');
},
function() {
$(this).removeClass('show');
$(this).find('.dropdown-menu').removeClass('show');
}
);
}
// Close mobile menu when clicking outside
$(document).click(function(e) {
if (!$(e.target).closest('.navbar').length) {
$('.navbar-collapse').collapse('hide');
}
});
}
// Animations
function initAnimations() {
// Intersection Observer for scroll animations
if ('IntersectionObserver' in window) {
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
entry.target.classList.add('animate-in');
observer.unobserve(entry.target);
}
});
}, observerOptions);
// Observe elements
document.querySelectorAll('.service-card, .product-card, .testimonial-card, .feature-card').forEach(function(el) {
observer.observe(el);
});
}
// Hover effects for cards
$('.service-card, .product-card, .testimonial-card').hover(
function() {
$(this).addClass('hover-effect');
},
function() {
$(this).removeClass('hover-effect');
}
);
}
// Counter Animation
function initCounters() {
function animateCounter($element) {
const target = parseInt($element.data('target') || $element.text().replace(/[^\d]/g, ''));
const duration = 2000;
const step = target / (duration / 16);
let current = 0;
const timer = setInterval(function() {
current += step;
if (current >= target) {
current = target;
clearInterval(timer);
}
$element.text(Math.floor(current));
}, 16);
}
// Trigger counters when in viewport
const counterObserver = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
const $counter = $(entry.target);
if (!$counter.hasClass('counted')) {
$counter.addClass('counted');
animateCounter($counter);
}
}
});
}, { threshold: 0.5 });
document.querySelectorAll('.counter, .stat-number').forEach(function(el) {
counterObserver.observe(el);
});
}
// Form Handling
function initForms() {
// Contact form submission
$('#contactForm').on('submit', function(e) {
e.preventDefault();
const formData = new FormData(this);
const submitBtn = $(this).find('button[type="submit"]');
const originalText = submitBtn.html();
// Show loading state
submitBtn.html('Gönderiliyor...').prop('disabled', true);
// Simulate form submission (replace with actual endpoint)
setTimeout(function() {
// Success message
showNotification('Mesajınız başarıyla gönderildi! En kısa sürede size dönüş yapacağız.', 'success');
// Reset form
$('#contactForm')[0].reset();
// Reset button
submitBtn.html(originalText).prop('disabled', false);
}, 2000);
});
// Newsletter form
$('#newsletterForm').on('submit', function(e) {
e.preventDefault();
const email = $(this).find('input[type="email"]').val();
if (validateEmail(email)) {
showNotification('Email adresiniz başarıyla kaydedildi!', 'success');
$(this)[0].reset();
} else {
showNotification('Lütfen geçerli bir email adresi girin.', 'error');
}
});
// Quote form
$('#quoteForm').on('submit', function(e) {
e.preventDefault();
const formData = {
name: $('#quoteName').val(),
email: $('#quoteEmail').val(),
phone: $('#quotePhone').val(),
product: $('#quoteProduct').val(),
quantity: $('#quoteQuantity').val(),
message: $('#quoteMessage').val()
};
// Show success message
showNotification('Teklif talebiniz alındı! 24 saat içinde size dönüş yapacağız.', 'success');
$(this)[0].reset();
});
// Real-time form validation
$('input, textarea, select').on('blur', function() {
validateField($(this));
});
}
// Form validation functions
function validateField($field) {
const value = $field.val();
const type = $field.attr('type');
let isValid = true;
let message = '';
// Remove previous validation classes
$field.removeClass('is-valid is-invalid');
$field.siblings('.invalid-feedback').remove();
// Required field validation
if ($field.prop('required') && !value.trim()) {
isValid = false;
message = 'Bu alan zorunludur.';
}
// Email validation
else if (type === 'email' && value && !validateEmail(value)) {
isValid = false;
message = 'Geçerli bir email adresi girin.';
}
// Phone validation
else if (type === 'tel' && value && !validatePhone(value)) {
isValid = false;
message = 'Geçerli bir telefon numarası girin.';
}
// Min length validation
else if ($field.attr('minlength') && value.length < parseInt($field.attr('minlength'))) {
isValid = false;
message = `En az ${$field.attr('minlength')} karakter olmalıdır.`;
}
// Apply validation styles
if (value.trim()) {
$field.addClass(isValid ? 'is-valid' : 'is-invalid');
if (!isValid) {
$field.after(`
${message}
`);
}
}
return isValid;
}
function validateEmail(email) {
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return re.test(email);
}
function validatePhone(phone) {
const re = /^[\+]?[0-9\s\-\(\)]{10,}$/;
return re.test(phone);
}
// Notification system
function showNotification(message, type = 'info', duration = 5000) {
const notification = $(`
`);
$('body').append(notification);
setTimeout(() => notification.addClass('show'), 100);
// Auto hide
setTimeout(() => {
notification.removeClass('show');
setTimeout(() => notification.remove(), 300);
}, duration);
// Manual close
notification.find('.notification-close').click(function() {
notification.removeClass('show');
setTimeout(() => notification.remove(), 300);
});
}
function getNotificationIcon(type) {
const icons = {
success: 'check-circle',
error: 'exclamation-circle',
warning: 'exclamation-triangle',
info: 'info-circle'
};
return icons[type] || icons.info;
}
// Lightbox for images
function initLightbox() {
$('[data-lightbox]').click(function(e) {
e.preventDefault();
const src = $(this).attr('href') || $(this).find('img').attr('src');
const title = $(this).attr('title') || $(this).find('img').attr('alt');
showLightbox(src, title);
});
}
function showLightbox(src, title) {
const lightbox = $(`
`);
$('body').append(lightbox);
setTimeout(() => lightbox.addClass('show'), 50);
// Close events
lightbox.find('.lightbox-close').click(closeLightbox);
lightbox.click(function(e) {
if (e.target === this) closeLightbox();
});
$(document).keyup(function(e) {
if (e.keyCode === 27) closeLightbox(); // ESC key
});
function closeLightbox() {
lightbox.removeClass('show');
setTimeout(() => lightbox.remove(), 300);
$(document).off('keyup');
}
}
// Product Sliders
function initSliders() {
// Hero slider (if exists)
if ($('.hero-slider').length) {
initHeroSlider();
}
// Product gallery slider
if ($('.product-gallery').length) {
initProductGallery();
}
// Testimonial slider
if ($('.testimonial-slider').length) {
initTestimonialSlider();
}
}
function initHeroSlider() {
let currentSlide = 0;
const slides = $('.hero-slider .slide');
const totalSlides = slides.length;
function showSlide(index) {
slides.removeClass('active');
slides.eq(index).addClass('active');
// Update indicators
$('.slider-indicators .indicator').removeClass('active');
$('.slider-indicators .indicator').eq(index).addClass('active');
}
function nextSlide() {
currentSlide = (currentSlide + 1) % totalSlides;
showSlide(currentSlide);
}
function prevSlide() {
currentSlide = (currentSlide - 1 + totalSlides) % totalSlides;
showSlide(currentSlide);
}
// Auto slide
setInterval(nextSlide, 5000);
// Navigation buttons
$('.next-btn').click(nextSlide);
$('.prev-btn').click(prevSlide);
// Indicators
$('.indicator').click(function() {
currentSlide = $(this).data('slide');
showSlide(currentSlide);
});
}
// Back to Top Button
function initBackToTop() {
$(window).scroll(function() {
if ($(this).scrollTop() > 300) {
$('.back-to-top').fadeIn();
} else {
$('.back-to-top').fadeOut();
}
});
$('.back-to-top').click(function() {
$('html, body').animate({ scrollTop: 0 }, 600);
});
}
// WhatsApp Integration
function initWhatsApp() {
$('.whatsapp-btn').click(function(e) {
e.preventDefault();
const phoneNumber = '905551234567'; // Replace with actual number
const message = 'Merhaba, Efe Perfore hakkında bilgi almak istiyorum.';
const url = `https://wa.me/${phoneNumber}?text=${encodeURIComponent(message)}`;
window.open(url, '_blank');
});
// Animate WhatsApp button
setInterval(function() {
$('.whatsapp-btn').addClass('pulse');
setTimeout(() => $('.whatsapp-btn').removeClass('pulse'), 1000);
}, 10000);
}
// Lazy Loading
function initLazyLoading() {
if ('IntersectionObserver' in window) {
const imageObserver = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove('lazy');
img.classList.add('loaded');
imageObserver.unobserve(img);
}
});
});
document.querySelectorAll('img[data-src]').forEach(function(img) {
imageObserver.observe(img);
});
}
}
// Smooth Scrolling
function initSmoothScroll() {
$('a[href*="#"]:not([href="#"])').click(function() {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
let target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
$('html, body').animate({
scrollTop: target.offset().top - 80
}, 600);
return false;
}
}
});
}
// Tooltips
function initTooltips() {
$('[data-bs-toggle="tooltip"]').tooltip();
}
// Product Filters
function initProductFilters() {
$('.filter-btn').click(function() {
const filter = $(this).data('filter');
// Update active button
$('.filter-btn').removeClass('active');
$(this).addClass('active');
// Filter products
if (filter === 'all') {
$('.product-item').fadeIn();
} else {
$('.product-item').fadeOut();
$(`.product-item[data-category="${filter}"]`).fadeIn();
}
});
// Search functionality
$('#productSearch').on('input', function() {
const searchTerm = $(this).val().toLowerCase();
$('.product-item').each(function() {
const productName = $(this).find('.product-title').text().toLowerCase();
const productDesc = $(this).find('.product-description').text().toLowerCase();
if (productName.includes(searchTerm) || productDesc.includes(searchTerm)) {
$(this).fadeIn();
} else {
$(this).fadeOut();
}
});
});
}
// Utility Functions
function debounce(func, wait, immediate) {
let timeout;
return function executedFunction() {
const context = this;
const args = arguments;
const later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
// Performance optimization
const optimizedScroll = debounce(function() {
// Scroll-based functions
updateProgressBar();
updateActiveSection();
}, 10);
$(window).scroll(optimizedScroll);
function updateProgressBar() {
const scrollTop = $(window).scrollTop();
const docHeight = $(document).height() - $(window).height();
const scrollPercent = (scrollTop / docHeight) * 100;
$('.progress-bar').css('width', scrollPercent + '%');
}
function updateActiveSection() {
const scrollPos = $(window).scrollTop() + 100;
$('section[id]').each(function() {
const sectionTop = $(this).offset().top;
const sectionBottom = sectionTop + $(this).outerHeight();
const sectionId = $(this).attr('id');
if (scrollPos >= sectionTop && scrollPos < sectionBottom) {
$('.navbar-nav a').removeClass('active');
$(`.navbar-nav a[href="#${sectionId}"]`).addClass('active');
}
});
}
// Error handling
window.addEventListener('error', function(e) {
console.error('JavaScript Error:', e.error);
// You can send error reports to your analytics service here
});
// Page loading performance
$(window).on('load', function() {
// Hide loading spinner if exists
$('.page-loader').fadeOut();
// Initialize animations after page load
setTimeout(function() {
$('body').addClass('loaded');
}, 500);
});
})(jQuery);
// CSS for notifications and other dynamic elements
const dynamicStyles = `
`;
// Inject dynamic styles
if (!document.querySelector('#dynamic-styles')) {
const styleElement = document.createElement('div');
styleElement.id = 'dynamic-styles';
styleElement.innerHTML = dynamicStyles;
document.head.appendChild(styleElement);
}
// ================================
// EFE PERFORE - MODERN JAVASCRIPT
// Award Winning Interactions
// ================================
document.addEventListener('DOMContentLoaded', function() {
// Gallery Data - Perfore Products
const galleryData = [
{
id: 1,
title: "Metal Perfore Levha",
category: "metal-perfore",
image: "images/gallery/metal-perfore-01.jpg",
description: "Yüksek kaliteli çelik perfore levha - Endüstriyel uygulamalar için ideal"
},
{
id: 2,
title: "Hassas Metal Perfore",
category: "metal-perfore",
image: "images/gallery/metal-perfore-02.jpg",
description: "CNC teknolojisi ile üretilen hassas metal perfore"
},
{
id: 3,
title: "Genişletilmiş Metal",
category: "expanded-metal",
image: "images/gallery/expanded-metal-01.jpg",
description: "Hafif ve dayanıklı genişletilmiş metal çözümleri"
},
{
id: 4,
title: "Lazer Kesim Perfore",
category: "laser-cutting",
image: "images/gallery/laser-cutting-01.jpg",
description: "Hassas lazer teknolojisi ile özel desenler"
},
{
id: 5,
title: "Dekoratif Perfore",
category: "decorative",
image: "images/gallery/decorative-01.jpg",
description: "Mimari projelerde estetik dekoratif çözümler"
},
{
id: 6,
title: "Mimari Cephe Perfore",
category: "architectural",
image: "images/gallery/architectural-01.jpg",
description: "Modern binaların cephe sistemleri için özel tasarım"
},
{
id: 7,
title: "Endüstriyel Perfore",
category: "industrial",
image: "images/gallery/industrial-01.jpg",
description: "Endüstriyel filtrasyon ve güvenlik uygulamaları"
}
];
// Initialize Gallery
initializeGallery();
// Initialize Lightbox
initializeLightbox();
// Initialize Smooth Scrolling
initializeSmoothScrolling();
// Initialize Navigation Effects
initializeNavigation();
// Initialize Counter Animation
initializeCounters();
// Gallery Functions
function initializeGallery() {
const galleryContainer = document.querySelector('.gallery-grid');
if (!galleryContainer) return;
// Create filter buttons
createFilterButtons();
// Render gallery items
renderGalleryItems(galleryData);
// Add filter functionality
addFilterFunctionality();
}
function createFilterButtons() {
const gallerySection = document.querySelector('.product-gallery');
if (!gallerySection) return;
const filterContainer = document.createElement('div');
filterContainer.className = 'text-center mb-4';
filterContainer.innerHTML = `
`;
const titleContainer = gallerySection.querySelector('.text-center.mb-5');
titleContainer.appendChild(filterContainer);
}
function renderGalleryItems(items) {
const galleryContainer = document.querySelector('.gallery-grid');
if (!galleryContainer) return;
galleryContainer.innerHTML = items.map(item => `
${item.title}
${item.description}
`).join('');
// Add click events for lightbox
galleryContainer.querySelectorAll('.gallery-item img').forEach(img => {
img.addEventListener('click', function() {
openLightbox(this.src, this.alt);
});
});
}
function addFilterFunctionality() {
const filterButtons = document.querySelectorAll('.filter-btn');
const galleryItems = document.querySelectorAll('.gallery-item');
filterButtons.forEach(btn => {
btn.addEventListener('click', function() {
// Remove active class from all buttons
filterButtons.forEach(b => b.classList.remove('active'));
// Add active class to clicked button
this.classList.add('active');
const filterValue = this.getAttribute('data-filter');
galleryItems.forEach(item => {
if (filterValue === 'all') {
item.style.display = 'block';
// Trigger AOS animation
item.classList.add('aos-animate');
} else {
const category = item.getAttribute('data-category');
if (category === filterValue) {
item.style.display = 'block';
item.classList.add('aos-animate');
} else {
item.style.display = 'none';
}
}
});
});
});
}
// Lightbox Functions
function initializeLightbox() {
// Lightbox close functionality
const lightbox = document.getElementById('lightbox');
if (!lightbox) return;
lightbox.addEventListener('click', function(e) {
if (e.target === lightbox) {
closeLightbox();
}
});
// Escape key to close lightbox
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
closeLightbox();
}
});
}
// Navigation Effects
function initializeNavigation() {
const navbar = document.querySelector('.navbar-modern');
if (!navbar) return;
// Scroll effect for navigation
window.addEventListener('scroll', function() {
if (window.scrollY > 100) {
navbar.style.background = 'rgba(15, 23, 42, 0.95)';
navbar.style.boxShadow = '0 4px 20px rgba(0, 0, 0, 0.3)';
} else {
navbar.style.background = 'rgba(15, 23, 42, 0.9)';
navbar.style.boxShadow = 'none';
}
});
// Mobile menu toggle
const mobileMenuBtn = document.querySelector('.btn-modern.d-md-none');
const navLinks = document.querySelector('.nav-links');
if (mobileMenuBtn && navLinks) {
mobileMenuBtn.addEventListener('click', function() {
navLinks.classList.toggle('mobile-menu-open');
});
}
}
// Counter Animation
function initializeCounters() {
const counters = document.querySelectorAll('.hero-stat');
const animateCounter = (counter) => {
const target = parseInt(counter.textContent.replace(/\D/g, ''));
const increment = target / 100;
let current = 0;
const timer = setInterval(() => {
current += increment;
if (current >= target) {
counter.textContent = counter.textContent.replace(/\d+/, target);
clearInterval(timer);
} else {
counter.textContent = counter.textContent.replace(/\d+/, Math.floor(current));
}
}, 20);
};
// Intersection Observer for counter animation
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
animateCounter(entry.target);
observer.unobserve(entry.target);
}
});
});
counters.forEach(counter => {
observer.observe(counter);
});
}
// Smooth Scrolling
function initializeSmoothScrolling() {
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
}
// Parallax Effect for Hero Section
function initializeParallax() {
const heroSection = document.querySelector('.hero-modern');
if (!heroSection) return;
window.addEventListener('scroll', function() {
const scrolled = window.pageYOffset;
const rate = scrolled * -0.5;
heroSection.style.transform = `translateY(${rate}px)`;
});
}
// Initialize parallax
initializeParallax();
// Form Validation
function initializeFormValidation() {
const forms = document.querySelectorAll('.form-modern');
forms.forEach(form => {
form.addEventListener('submit', function(e) {
e.preventDefault();
// Simple validation
const inputs = form.querySelectorAll('input[required], textarea[required]');
let isValid = true;
inputs.forEach(input => {
if (!input.value.trim()) {
input.classList.add('is-invalid');
isValid = false;
} else {
input.classList.remove('is-invalid');
input.classList.add('is-valid');
}
});
if (isValid) {
// Show success message
showNotification('Mesajınız başarıyla gönderildi!', 'success');
}
});
});
}
// Notification System
function showNotification(message, type = 'info') {
const notification = document.createElement('div');
notification.className = `notification notification-${type}`;
notification.innerHTML = `
${message}
`;
document.body.appendChild(notification);
// Auto remove after 5 seconds
setTimeout(() => {
if (notification.parentElement) {
notification.remove();
}
}, 5000);
}
// Initialize form validation
initializeFormValidation();
// Loading Animation
function showLoading() {
const loading = document.createElement('div');
loading.className = 'loading-overlay';
loading.innerHTML = `
`;
document.body.appendChild(loading);
}
function hideLoading() {
const loading = document.querySelector('.loading-overlay');
if (loading) {
loading.remove();
}
}
// Expose global functions
window.openLightbox = openLightbox;
window.closeLightbox = closeLightbox;
window.showNotification = showNotification;
window.showLoading = showLoading;
window.hideLoading = hideLoading;
});
// Global Lightbox Functions
function openLightbox(imageSrc, imageTitle) {
const lightbox = document.getElementById('lightbox');
const lightboxImg = document.getElementById('lightbox-img');
if (lightbox && lightboxImg) {
lightboxImg.src = imageSrc;
lightboxImg.alt = imageTitle;
lightbox.classList.add('active');
document.body.style.overflow = 'hidden';
}
}
function closeLightbox() {
const lightbox = document.getElementById('lightbox');
if (lightbox) {
lightbox.classList.remove('active');
document.body.style.overflow = 'auto';
}
}
// Advanced CSS Animations
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('animate-slide-up');
}
});
}, observerOptions);
// Observe all sections for animations
document.querySelectorAll('section').forEach(section => {
observer.observe(section);
});
// Mobile Menu Styles
const mobileMenuStyles = `
.nav-links.mobile-menu-open {
position: fixed;
top: 80px;
left: 0;
right: 0;
background: rgba(15, 23, 42, 0.98);
backdrop-filter: blur(20px);
flex-direction: column;
padding: 2rem;
gap: 1rem;
z-index: 999;
transform: translateY(0);
transition: all 0.3s ease;
}
.notification {
position: fixed;
top: 100px;
right: 20px;
z-index: 10001;
background: white;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
padding: 1rem;
min-width: 300px;
transform: translateX(400px);
animation: slideInNotification 0.3s ease-out forwards;
}
.notification-success {
border-left: 4px solid var(--success-color);
}
.notification-content {
display: flex;
align-items: center;
justify-content: space-between;
}
.notification-close {
background: none;
border: none;
color: #666;
cursor: pointer;
padding: 0.25rem;
}
.loading-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(15, 23, 42, 0.9);
display: flex;
align-items: center;
justify-content: center;
z-index: 10002;
}
@keyframes slideInNotification {
to {
transform: translateX(0);
}
}
@media (max-width: 768px) {
.nav-links {
display: none;
transform: translateY(-20px);
}
.nav-links.mobile-menu-open {
display: flex;
}
}
`;
// Add mobile menu styles
const styleSheet = document.createElement('style');
styleSheet.textContent = mobileMenuStyles;
document.head.appendChild(styleSheet);
// Modern Scroll Progress Indicator
function initScrollProgress() {
const progressBar = document.getElementById('scrollProgress');
if (progressBar) {
window.addEventListener('scroll', () => {
const windowHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight;
const scrolled = (window.scrollY / windowHeight) * 100;
progressBar.style.width = scrolled + '%';
});
}
}
// Modern Mobile Menu Toggle
function toggleMobileMenu() {
const navLinks = document.querySelector('.nav-links');
const mobileMenuToggle = document.getElementById('mobileMenuToggle');
if (navLinks) {
navLinks.classList.toggle('mobile-menu-open');
// Animate hamburger icon
if (mobileMenuToggle) {
const icon = mobileMenuToggle.querySelector('i');
if (icon) {
icon.classList.toggle('fa-bars');
icon.classList.toggle('fa-times');
}
}
}
}
// Filter Gallery Function
function filterGallery(category) {
const galleryItems = document.querySelectorAll('.gallery-item');
const filterButtons = document.querySelectorAll('.btn-outline-primary');
// Update active button
filterButtons.forEach(btn => {
btn.classList.remove('active');
if (btn.getAttribute('onclick') && btn.getAttribute('onclick').includes(category)) {
btn.classList.add('active');
}
});
// Filter items with animation
galleryItems.forEach((item, index) => {
if (category === 'all' || item.getAttribute('data-category') === category) {
setTimeout(() => {
item.style.display = 'block';
item.style.opacity = '0';
item.style.transform = 'translateY(20px)';
setTimeout(() => {
item.style.opacity = '1';
item.style.transform = 'translateY(0)';
}, 50);
}, index * 50);
} else {
item.style.opacity = '0';
item.style.transform = 'translateY(-20px)';
setTimeout(() => {
item.style.display = 'none';
}, 300);
}
});
}
// Initialize on page load
document.addEventListener('DOMContentLoaded', () => {
initScrollProgress();
// Initialize any remaining features
if (typeof AOS !== 'undefined') {
AOS.refresh();
}
});