/**
* Modern Courses Page JavaScript
* This file contains JavaScript functionality for the courses page
*/
document.addEventListener('DOMContentLoaded', function() {
// Initialize 3D background if it exists
initializeBackground();
// Animate course cards with intersection observer
animateCourseCards();
// Make navbar transparent/solid on scroll
handleNavbarScroll();
// Initialize category filters
initializeCategoryFilters();
// Search functionality
initializeSearch();
});
/**
* Initialize the 3D animated background
*/
function initializeBackground() {
// Create background container if it doesn't exist
if (!document.querySelector('.bg-animation')) {
const bgAnimation = document.createElement('div');
bgAnimation.className = 'bg-animation';
const bgGradient = document.createElement('div');
bgGradient.className = 'bg-gradient';
const bgShapes = document.createElement('div');
bgShapes.className = 'bg-shapes';
// Create animated shapes
for (let i = 1; i <= 4; i++) {
const shape = document.createElement('div');
shape.className = `shape shape-${i}`;
bgShapes.appendChild(shape);
}
bgAnimation.appendChild(bgGradient);
bgAnimation.appendChild(bgShapes);
document.body.insertBefore(bgAnimation, document.body.firstChild);
}
// Add parallax effect to shapes
const shapes = document.querySelectorAll('.shape');
document.addEventListener('mousemove', function(e) {
const x = e.clientX / window.innerWidth;
const y = e.clientY / window.innerHeight;
shapes.forEach((shape, index) => {
const speed = (index + 1) * 10;
const offsetX = (0.5 - x) * speed;
const offsetY = (0.5 - y) * speed;
shape.style.transform = `translate(${offsetX}px, ${offsetY}px)`;
});
});
}
/**
* Animate course cards when they come into view
*/
function animateCourseCards() {
const courseCards = document.querySelectorAll('.course-card-container');
// If IntersectionObserver is supported
if ('IntersectionObserver' in window) {
const cardObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// Add animation with delay based on index
setTimeout(() => {
entry.target.style.opacity = '1';
entry.target.style.transform = 'translateY(0)';
}, 100 * Array.from(courseCards).indexOf(entry.target) % 10);
// Stop observing after animation
cardObserver.unobserve(entry.target);
}
});
}, {
threshold: 0.1
});
// Observe each card
courseCards.forEach(card => {
cardObserver.observe(card);
});
} else {
// Fallback for browsers that don't support IntersectionObserver
courseCards.forEach((card, index) => {
setTimeout(() => {
card.style.opacity = '1';
card.style.transform = 'translateY(0)';
}, 100 * (index % 10));
});
}
}
/**
* Handle navbar transparency on scroll
*/
function handleNavbarScroll() {
const navbar = document.querySelector('.navbar');
if (navbar) {
window.addEventListener('scroll', () => {
if (window.scrollY > 50) {
navbar.classList.remove('navbar-transparent');
navbar.classList.add('navbar-solid');
} else {
navbar.classList.add('navbar-transparent');
navbar.classList.remove('navbar-solid');
}
});
// Initial check
if (window.scrollY > 50) {
navbar.classList.remove('navbar-transparent');
navbar.classList.add('navbar-solid');
} else {
navbar.classList.add('navbar-transparent');
navbar.classList.remove('navbar-solid');
}
}
}
/**
* Initialize category filters
*/
function initializeCategoryFilters() {
const filterButtons = document.querySelectorAll('.btn-filter');
const courseCards = document.querySelectorAll('.course-card-container');
filterButtons.forEach(button => {
button.addEventListener('click', function(e) {
// If not using links for filtering
if (!button.getAttribute('href')) {
e.preventDefault();
// Remove active class from all buttons
filterButtons.forEach(btn => btn.classList.remove('active'));
// Add active class to clicked button
this.classList.add('active');
const category = this.getAttribute('data-category');
// Show all courses if 'all' is selected, otherwise filter
courseCards.forEach(card => {
if (category === 'all' || card.getAttribute('data-category') === category) {
card.style.display = '';
// Re-animate the visible cards
setTimeout(() => {
card.style.opacity = '1';
card.style.transform = 'translateY(0)';
}, 100 * Math.random() * 10);
} else {
card.style.display = 'none';
}
});
}
});
});
}
/**
* Initialize search functionality
*/
function initializeSearch() {
const searchForm = document.getElementById('courseSearchForm');
const searchInput = document.getElementById('courseSearch');
if (searchForm && searchInput) {
// Add input event for real-time filtering
searchInput.addEventListener('input', function() {
const searchTerm = this.value.toLowerCase().trim();
// If not submitting to server, perform client-side filtering
if (searchForm.getAttribute('data-client-search') === 'true') {
const courseCards = document.querySelectorAll('.course-card-container');
const courseTitles = document.querySelectorAll('.course-title');
courseTitles.forEach((title, index) => {
const card = courseCards[index];
const titleText = title.textContent.toLowerCase();
if (searchTerm === '' || titleText.includes(searchTerm)) {
card.style.display = '';
// Re-animate the visible cards
setTimeout(() => {
card.style.opacity = '1';
card.style.transform = 'translateY(0)';
}, 100 * Math.random() * 10);
} else {
card.style.display = 'none';
}
});
}
});
}
}
/**
* Apply 3D tilt effect to cards
*/
function applyTiltEffect() {
const cards = document.querySelectorAll('.course-card');
cards.forEach(card => {
card.addEventListener('mousemove', function(e) {
const cardRect = this.getBoundingClientRect();
const cardCenterX = cardRect.left + cardRect.width / 2;
const cardCenterY = cardRect.top + cardRect.height / 2;
const mouseX = e.clientX - cardCenterX;
const mouseY = e.clientY - cardCenterY;
// Calculate rotation based on mouse position
const rotateY = (mouseX / (cardRect.width / 2)) * 5; // Max 5 degrees
const rotateX = -(mouseY / (cardRect.height / 2)) * 5; // Max 5 degrees
// Apply the rotation and slight scale
this.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(1.02)`;
// Add a highlight effect based on mouse position
const highlight = `radial-gradient(circle at ${e.clientX - cardRect.left}px ${e.clientY - cardRect.top}px, rgba(255,255,255,0.1) 0%, transparent 80%)`;
this.style.backgroundImage = highlight;
});
// Reset the transform when mouse leaves
card.addEventListener('mouseleave', function() {
this.style.transform = 'perspective(1000px) rotateX(0) rotateY(0) scale(1)';
this.style.backgroundImage = 'none';
});
});
}
// Initialize tilt effect for desktop devices
if (window.innerWidth > 992) {
// Load tilt effect after a short delay to ensure DOM is fully loaded
setTimeout(applyTiltEffect, 500);
}