basic version by Felix

This commit is contained in:
luptmoor
2026-02-27 10:59:57 +01:00
commit 5f17605884
36 changed files with 2353 additions and 0 deletions

263
js/script.js Normal file
View File

@@ -0,0 +1,263 @@
/* =====================================================
GLOBAL STATE
===================================================== */
let index = 0;
let track;
let dots = [];
/* =====================================================
DOM CONTENT LOADED
===================================================== */
document.addEventListener("DOMContentLoaded", () => {
initServices();
initNavigation();
initNewsSlider();
});
/* =====================================================
SERVICES EXPAND / COLLAPSE
===================================================== */
function initServices() {
const boxes = document.querySelectorAll(".service-box");
boxes.forEach(box => {
const arrow = box.querySelector(".service-arrow");
const text = box.querySelector(".service-text");
let closeTimeout;
arrow.addEventListener("click", () => {
boxes.forEach(b => {
if (b !== box) b.classList.remove("open");
if (b.closeTimeout) clearTimeout(b.closeTimeout);
});
box.classList.toggle("open");
});
/* AUTO CLOSE */
box.addEventListener("mouseleave", () => {
if (box.classList.contains("open")) {
box.classList.add("closing");
closeTimeout = setTimeout(() => {
box.classList.remove("open");
}, 600);
box.closeTimeout = closeTimeout;
}
});
/* CANCEL CLOSE */
box.addEventListener("mouseenter", () => {
if (closeTimeout) clearTimeout(closeTimeout);
box.classList.remove("closing");
});
/* CLEANUP CLASS */
text.addEventListener("transitionend", e => {
if (
e.propertyName === "max-height" &&
box.classList.contains("closing")
) {
box.classList.remove("closing");
}
});
});
}
/* =====================================================
SCROLL TO TOP
===================================================== */
function scrollToTop() {
window.scrollTo({
top: 0,
behavior: "smooth"
});
}
/* =====================================================
MOBILE BURGER MENU
===================================================== */
function toggleBurger() {
document.querySelector(".nav").classList.toggle("open");
}
/* =====================================================
ACTIVE NAVIGATION SCROLL
===================================================== */
function initNavigation() {
const sections = document.querySelectorAll("section");
const navLinks = document.querySelectorAll(".nav-links a");
window.addEventListener("scroll", () => {
let current = "";
sections.forEach(section => {
const top = section.offsetTop - 120;
if (window.scrollY >= top) {
current = section.getAttribute("id");
}
});
navLinks.forEach(link => {
link.classList.remove("active");
if (link.getAttribute("href") === "#" + current) {
link.classList.add("active");
}
});
});
}
/* =====================================================
NEWS SLIDER
===================================================== */
function initNewsSlider() {
track = document.querySelector(".news-track");
const slider = document.querySelector(".news-slider");
const dotsContainer = document.querySelector(".news-dots");
const slides = document.querySelectorAll(".news-slide");
if (!track || !dotsContainer || slides.length === 0) return;
let autoSlide;
const INTERVAL = 8000; // 8 sec
/* -------------------------
CREATE DOTS
------------------------- */
dotsContainer.innerHTML = "";
dots = [];
slides.forEach((slide, i) => {
const dot = document.createElement("div");
dot.classList.add("news-dot");
if (i === 0) dot.classList.add("active");
dot.addEventListener("click", () => {
index = i;
updateSlider();
restartAutoSlide();
});
dotsContainer.appendChild(dot);
dots.push(dot);
});
/* -------------------------
UPDATE SLIDER
------------------------- */
function updateSlider() {
track.style.transform = `translateX(-${index * 100}%)`;
dots.forEach((dot, i) =>
dot.classList.toggle("active", i === index)
);
}
/* -------------------------
AUTO LOOP
------------------------- */
function startAutoSlide() {
autoSlide = setInterval(() => {
index++;
if (index >= slides.length) {
index = 0; // LOOP BACK
}
updateSlider();
}, INTERVAL);
}
function stopAutoSlide() {
clearInterval(autoSlide);
}
function restartAutoSlide() {
stopAutoSlide();
startAutoSlide();
}
/* -------------------------
PAUSE ON HOVER
------------------------- */
const newsSection = document.querySelector("#news");
newsSection.addEventListener("mouseenter", () => {
stopAutoSlide();
});
newsSection.addEventListener("mouseleave", () => {
startAutoSlide();
});
/* -------------------------
TOUCH SUPPORT
------------------------- */
let startX = 0;
let isDragging = false;
track.addEventListener("touchstart", e => {
startX = e.touches[0].clientX;
isDragging = true;
stopAutoSlide();
});
track.addEventListener("touchmove", e => {
if (!isDragging) return;
const delta = e.touches[0].clientX - startX;
track.style.transition = "none";
track.style.transform =
`translateX(calc(-${index * 100}% + ${delta}px))`;
});
track.addEventListener("touchend", e => {
isDragging = false;
track.style.transition = "transform 0.6s ease";
const delta = e.changedTouches[0].clientX - startX;
if (delta > 50 && index > 0) index--;
else if (delta < -50 && index < slides.length - 1) index++;
updateSlider();
restartAutoSlide();
});
/* -------------------------
INIT
------------------------- */
updateSlider();
startAutoSlide();
}