document.addEventListener("DOMContentLoaded", function () { let intouchBtn = document.getElementById("get-in-touch"); let intouchPopup = document.getElementById("get-in-touch-page"); let closeBtns = document.getElementById("close-btn"); // Show login popup intouchBtn.addEventListener("click", function () { intouchPopup.classList.add("active"); // alert("clicked ") }); // Hide both popups when clicking any close button closeBtns.addEventListener("click", function () { intouchPopup.classList.remove("active"); }); // Hide popups when clicking outside them window.addEventListener("click", function (event) { if (event.target.classList.contains("get-in-touch-page")) { intouchPopup.classList.remove("active"); } }); }); // university image animation window.addEventListener('DOMContentLoaded', () => { const section = document.getElementById('animated-section'); const leftItems = document.querySelectorAll('.left-group .line-item'); const rightItems = document.querySelectorAll('.right-group .line-item'); const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { leftItems.forEach((item, i) => { setTimeout(() => item.classList.add('visible'), i * 300); }); rightItems.forEach((item, i) => { setTimeout(() => item.classList.add('visible'), i * 300); }); } else { leftItems.forEach(item => item.classList.remove('visible')); rightItems.forEach(item => item.classList.remove('visible')); } }); }, { threshold: 0.5 }); observer.observe(section); }); // tabs in free resources function showTab(id) { // Remove active class from all buttons document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active')); // Hide all tab contents document.querySelectorAll('.tab-content').forEach(tab => tab.classList.remove('active')); // Show the selected tab document.getElementById(id).classList.add('active'); } // NEW: Attach click event on all tab buttons document.querySelectorAll('.tab-btn').forEach(button => { button.addEventListener('click', function () { // Remove active from all document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active')); // Add active to clicked button this.classList.add('active'); }); }); // counter section document.addEventListener("DOMContentLoaded", function () { const counters = document.querySelectorAll(".counter"); const observer = new IntersectionObserver(entries => { entries.forEach(entry => { const counter = entry.target; if (entry.isIntersecting) { if (!counter.classList.contains('started')) { startCounting(counter); counter.classList.add('started'); } } else { resetCounter(counter); counter.classList.remove('started'); } }); }); counters.forEach(counter => { observer.observe(counter); }); function startCounting(counter) { let start = 0; const targetNumber = parseInt(counter.getAttribute("data-target")); const duration = 2000; // 2 seconds const increment = targetNumber / (duration / 16); const timer = setInterval(() => { start += increment; if (start >= targetNumber) { counter.textContent = targetNumber; clearInterval(timer); } else { counter.textContent = Math.floor(start); } }, 16); } function resetCounter(counter) { counter.textContent = 0; } }); // course finder ball bouncing window.addEventListener('DOMContentLoaded', () => { const canvas = document.getElementById('flagCanvas'); const ctx = canvas.getContext('2d'); const ballSection = document.getElementById('ball-section'); // Get responsive ball size function getBallSize() { const width = window.innerWidth; if (width < 480) return 20; if (width < 768) return 30; return 40; } let ballSize = getBallSize(); // Responsive canvas sizing function resizeCanvas() { canvas.width = ballSection.clientWidth; canvas.height = ballSection.clientHeight; ballSize = getBallSize(); } resizeCanvas(); window.addEventListener('resize', resizeCanvas); const gravity = 0.25; const friction = 0.8; const elasticity = 0.75; const flags = ['us', 'gb', 'np', 'dk', 'ca', 'au']; let balls = []; class Ball { constructor(x, y, radius, imageSrc) { this.x = x; this.y = y; this.radius = radius; this.dx = (Math.random() - 0.5) * 2; this.dy = 0; this.image = new Image(); this.image.src = imageSrc; this.dragging = false; this.offsetX = 0; this.offsetY = 0; this.elasticity = elasticity; this.hasSettled = false; } draw() { ctx.save(); ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2); ctx.closePath(); ctx.clip(); const img = this.image; const size = Math.min(img.width, img.height); const sx = (img.width - size) / 2; const sy = (img.height - size) / 2; ctx.drawImage( img, sx, sy, size, size, this.x - this.radius, this.y - this.radius, this.radius * 2, this.radius * 2 ); ctx.restore(); } update(others) { if (!this.dragging) { this.dy += gravity; this.x += this.dx; this.y += this.dy; // Floor if (this.y + this.radius > canvas.height) { this.y = canvas.height - this.radius; this.dy *= -this.elasticity; this.dx *= friction; if (Math.abs(this.dy) < 0.5) { this.dy = 0; this.hasSettled = true; } } // Walls if (this.x - this.radius < 0) { this.x = this.radius; this.dx *= -friction; } else if (this.x + this.radius > canvas.width) { this.x = canvas.width - this.radius; this.dx *= -friction; } } // Collisions if (this.dragging || !this.hasSettled) { for (let other of others) { if (other !== this) { this.resolveBallCollision(other); } } } this.draw(); } resolveBallCollision(other) { const dx = other.x - this.x; const dy = other.y - this.y; const dist = Math.sqrt(dx * dx + dy * dy); const minDist = this.radius + other.radius; if (dist < minDist) { const nx = dx / dist; const ny = dy / dist; const overlap = minDist - dist; const impulse = 0.5; this.x -= nx * overlap * impulse; this.y -= ny * overlap * impulse; other.x += nx * overlap * impulse; other.y += ny * overlap * impulse; const tx = -ny; const ty = nx; const dpTan1 = this.dx * tx + this.dy * ty; const dpTan2 = other.dx * tx + other.dy * ty; const dpNorm1 = this.dx * nx + this.dy * ny; const dpNorm2 = other.dx * nx + other.dy * ny; this.dx = tx * dpTan1 + nx * dpNorm2; this.dy = ty * dpTan1 + ny * dpNorm2; other.dx = tx * dpTan2 + nx * dpNorm1; other.dy = ty * dpTan2 + ny * dpNorm1; } } } function createBalls() { balls = []; for (let i = 0; i < 30; i++) { const flag = flags[i % flags.length]; const x = Math.random() * (canvas.width - ballSize * 2) + ballSize; const y = -Math.random() * 300; balls.push(new Ball(x, y, ballSize, `assets/images/logo/country/${flag}.png`)); } } createBalls(); let draggedBall = null; let lastMouse = { x: 0, y: 0 }; canvas.addEventListener('pointerdown', (e) => { const rect = canvas.getBoundingClientRect(); const scaleX = canvas.width / rect.width; const scaleY = canvas.height / rect.height; const mouseX = (e.clientX - rect.left) * scaleX; const mouseY = (e.clientY - rect.top) * scaleY; for (let ball of balls) { const dx = mouseX - ball.x; const dy = mouseY - ball.y; if (Math.sqrt(dx * dx + dy * dy) < ball.radius) { ball.dragging = true; draggedBall = ball; ball.offsetX = dx; ball.offsetY = dy; ball.hasSettled = false; lastMouse = { x: mouseX, y: mouseY }; break; } } }); canvas.addEventListener('pointermove', (e) => { if (draggedBall) { const rect = canvas.getBoundingClientRect(); const scaleX = canvas.width / rect.width; const scaleY = canvas.height / rect.height; const mouseX = (e.clientX - rect.left) * scaleX; const mouseY = (e.clientY - rect.top) * scaleY; draggedBall.x = mouseX - draggedBall.offsetX; draggedBall.y = mouseY - draggedBall.offsetY; draggedBall.dx = (mouseX - lastMouse.x) * 0.4; draggedBall.dy = (mouseY - lastMouse.y) * 0.4; lastMouse = { x: mouseX, y: mouseY }; } }); window.addEventListener('pointerup', () => { if (draggedBall) { draggedBall.dragging = false; draggedBall = null; } }); // Animation loop let animationId = null; let isAnimating = false; function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); balls.forEach(ball => ball.update(balls)); animationId = requestAnimationFrame(animate); } // Intersection Observer const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { if (!isAnimating) { createBalls(); isAnimating = true; animate(); } } else { if (isAnimating) { cancelAnimationFrame(animationId); isAnimating = false; } } }); }, { threshold: 0.1 }); observer.observe(ballSection); }); // scroll detect in slider // JS script // JS for updating label on scroll window.addEventListener('load', () => { console.log("Window loaded. Running scroll indicator script."); const scrollLabel = document.getElementById('scroll-indicator-label'); console.log("Scroll Label Element:", scrollLabel); const sections = document.querySelectorAll('.scroll-section'); console.log("Found Sections:", sections); if (!scrollLabel || sections.length === 0) { console.error("Could not find scroll label or sections to observe. Exiting."); return; } const observer = new IntersectionObserver( (entries) => { console.log("IntersectionObserver callback fired:", entries); entries.forEach(entry => { console.log("Observing entry:", entry.target, "Is intersecting:", entry.isIntersecting); if (entry.isIntersecting) { // --- CHANGE IS HERE --- const sectionId = entry.target.id; // Get the ID of the intersecting section // --- END OF CHANGE --- console.log("Intersecting section ID:", sectionId); if (sectionId) { // Check if ID exists // Optional: Format the ID if needed (example: replace hyphens, capitalize) // let displayText = sectionId.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase()); // scrollLabel.textContent = displayText; // Simple version: Use the ID directly scrollLabel.textContent = sectionId; console.log("Updated scroll label text to:", sectionId); } else { console.warn("Intersecting section is missing an ID attribute:", entry.target); } } }); }, { threshold: 0.5 // Trigger when 50% of the section is visible // Consider adjusting rootMargin if you have sticky headers/footers // rootMargin: "-50px 0px -50px 0px" // Example: ignore top/bottom 50px } ); sections.forEach(section => { if (!section.id) { console.warn("Section is missing an ID, it won't update the label:", section); } console.log("Observing section:", section); observer.observe(section); }); console.log("Intersection observer setup complete."); }); // Optional: Add a check outside the load event to see if the script file itself is loaded console.log("Scroll indicator script file loaded."); // aeroplane flying const plane = document.getElementById("plane"); let planeX = 100; let planeYBase = 200; // starting height let vx; if (window.innerWidth < 600) { // mobile vx = 1; } else if (window.innerWidth < 1200) { // tablet vx = 2; } else { // desktop vx = 3; } // horizontal speed let direction = 1; // 1 = right, -1 = left // const amplitude = 150; let amplitude; if (window.innerWidth < 768) { // mobile amplitude = 90; } else { // desktop amplitude = 150; } // const numWaves = 2; let numWaves; if (window.innerWidth < 768) { // mobile numWaves = 1; } else { // desktop numWaves = 3; } let dodgeOffset = 0; const dodgeDecay = 0.9; let downwardMovement = 0; // current Y offset let targetDownwardMovement = 0; // target Y offset let downwardStep = 200; // increase per edge hit let goingDown = true; function updatePosition() { const w = window.innerWidth; const h = document.body.scrollHeight; const maxPlaneY = h - 200; // bounce left/right if (planeX <= 0 || planeX >= w - plane.width) { vx *= -1; direction *= -1; plane.style.transform = `scaleX(${direction > 0 ? 1 : -1})`; if (goingDown) { targetDownwardMovement += downwardStep; if (planeYBase + targetDownwardMovement >= maxPlaneY) { targetDownwardMovement = maxPlaneY - planeYBase; goingDown = false; } } else { targetDownwardMovement -= downwardStep; if (targetDownwardMovement <= 0) { targetDownwardMovement = 0; goingDown = true; } } } planeX += vx; // 🟢 Smoothly move downwardMovement towards targetDownwardMovement downwardMovement += (targetDownwardMovement - downwardMovement) * 0.05; // progress across screen let progress = planeX / (w - plane.width); if (direction < 0) { progress = 1 - progress; } const angle = progress * numWaves * 2 * Math.PI; const waveY = Math.sin(angle) * amplitude; const finalY = planeYBase + downwardMovement + waveY + dodgeOffset; plane.style.left = planeX + 'px'; plane.style.top = finalY + 'px'; dodgeOffset *= dodgeDecay; requestAnimationFrame(updatePosition); } document.addEventListener("mousemove", function(e) { const viewportOffset = plane.getBoundingClientRect(); const planeCenterX = viewportOffset.left + plane.width / 2; const planeCenterY = viewportOffset.top + plane.height / 2; const dx = e.clientX - planeCenterX; const dy = e.clientY - planeCenterY; const dist = Math.sqrt(dx * dx + dy * dy); if (dist < 100) { dodgeOffset -= (dy / dist) * 10; } }); updatePosition(); // gallery image const images = Array.from(document.querySelectorAll('.gallery img')); const lightbox = document.getElementById('lightbox'); const lightboxImg = document.getElementById('lightbox-img'); let currentIndex = 0; images.forEach((img, index) => { img.addEventListener('click', () => { currentIndex = index; showImage(); }); }); function showImage() { lightboxImg.src = images[currentIndex].src; lightbox.classList.add('active'); } function closeLightbox() { lightbox.classList.remove('active'); } function changeSlide(step) { currentIndex = (currentIndex + step + images.length) % images.length; showImage(); } document.addEventListener('keydown', e => { if (!lightbox.classList.contains('active')) return; if (e.key === 'ArrowRight') changeSlide(1); if (e.key === 'ArrowLeft') changeSlide(-1); if (e.key === 'Escape') closeLightbox(); }); // cost calculator progress let currentStep = 1; const totalSteps = 5; const monkey = document.getElementById('monkey').querySelector('img'); const monkeyContainer = document.getElementById('monkey'); const nextBtn = document.querySelector('.next-btn button'); const bananalast = document.getElementById('b5'); const monkeyImages = [ "assets/images/icons/monkey1.png", "assets/images/icons/monkey2.png", "assets/images/icons/monkey3.png", "assets/images/icons/monkey4.png", "assets/images/icons/monkey5.png", "assets/images/icons/monkey6.png", "assets/images/icons/monkey7.png", ]; nextBtn.addEventListener('click', () => { if (currentStep < totalSteps) { currentStep++; // Move monkey if (window.innerWidth <= 540) { const percent = ((currentStep -1) / (totalSteps - 0.2)) * 100; monkeyContainer.style.left = percent + '%'; } else if (window.innerWidth <= 768) { const percent = ((currentStep -1) / (totalSteps - 0.3)) * 100; monkeyContainer.style.left = percent + '%'; } else if (window.innerWidth <= 992) { const percent = ((currentStep -1) / (totalSteps - 0.7)) * 100; monkeyContainer.style.left = percent + '%'; } else if (window.innerWidth <= 1180) { const percent = ((currentStep -1) / (totalSteps - 0.2)) * 100; monkeyContainer.style.left = percent + '%'; } else{ const percent = ((currentStep -1) / (totalSteps - 0.5)) * 100; monkeyContainer.style.left = percent + '%'; } // Change monkey image monkey.src = monkeyImages[currentStep - 1]; // Update step content const currentContent = document.getElementById('step' + (currentStep - 1)); const nextContent = document.getElementById('step' + currentStep); if (currentContent && nextContent) { currentContent.classList.remove('active'); nextContent.classList.add('active'); } // At final step (Step 5), hide Next and show Done if (currentStep === totalSteps) { nextBtn.style.display = 'none'; doneBtn.style.display = 'block'; } }w }); doneBtn.addEventListener('click', () => { bananalast.classList.add('active'); if (window.innerWidth <= 992) { // On mobile: show 7th image and move down monkey.src = monkeyImages[6]; // 7th image (index 6) monkeyContainer.style.top = '142%'; monkeyContainer.style.left = '40%'; // Optional: keep it centered or adjust as needed } else { // On desktop: show 6th image and move right monkey.src = monkeyImages[5]; // 6th image (index 5) monkeyContainer.style.left = '110%'; monkeyContainer.style.top = '-120%'; // Reset top if changed previously } }); // Final monkey image // document.addEventListener("DOMContentLoaded", function () { // const animatedSections = document.querySelectorAll('[data-custom-animations="true"]'); // const observer = new IntersectionObserver(entries => { // entries.forEach(entry => { // const el = entry.target; // if (entry.isIntersecting) { // el.classList.add("lqd-animations-done"); // Add class when in view // console.log('added') // } else { // el.classList.remove("lqd-animations-done"); // Remove class when out of view // console.log('removed') // } // }); // }, { // threshold: 0.1 // You can adjust this if needed // }); // animatedSections.forEach(section => observer.observe(section)); // });