91 lines
3.4 KiB
Plaintext
91 lines
3.4 KiB
Plaintext
doctype html
|
|
html.scroll-smooth(lang=head.lang)
|
|
include src/components/Head
|
|
|
|
body.m-0.p-0
|
|
main.flex.flex-col
|
|
article(itemscope, itemtype="http://schema.org/Person")
|
|
include src/components/Landingpage
|
|
include src/components/Brands
|
|
include src/components/Academia
|
|
include src/components/Portfolio
|
|
include src/components/Professional
|
|
include src/components/Footer
|
|
|
|
script.
|
|
const footerEl = document.querySelector("#footer");
|
|
const footerObserver = new IntersectionObserver((payload) => {
|
|
const hasScrolledTo = payload.pop().isIntersecting;
|
|
if (hasScrolledTo && window.hasOwnProperty("umami")) {
|
|
umami.track("scrolled to", {position: "footer", id: "footer", visitDuration: getVisitDuration()});
|
|
console.debug("scrolled to footer", {visitDuration: getVisitDuration()});
|
|
}
|
|
});
|
|
footerObserver.observe(footerEl);
|
|
|
|
const sections = document.querySelectorAll("section");
|
|
const sectionObserver = (id) =>
|
|
new IntersectionObserver((payload) => {
|
|
const hasScrolledTo = payload.pop().isIntersecting;
|
|
if (hasScrolledTo && window.hasOwnProperty("umami")) {
|
|
umami.track("scrolled to", {position: "section", id, visitDuration: getVisitDuration()});
|
|
console.debug("scrolled to section with id", {id, visitDuation: getVisitDuration()});
|
|
}
|
|
});
|
|
sections.forEach((section) => sectionObserver(section.id).observe(section));
|
|
|
|
// carousel.js - Just the essentials
|
|
function carouselPrev(carouselId) {
|
|
const track = document.querySelector(`#${carouselId} .carousel-track`);
|
|
const slideWidth = track.querySelector(".carousel-slide").offsetWidth;
|
|
track.scrollBy({left: -slideWidth, behavior: "smooth"});
|
|
updateCarouselDots(carouselId);
|
|
}
|
|
|
|
function carouselNext(carouselId) {
|
|
const track = document.querySelector(`#${carouselId} .carousel-track`);
|
|
const slideWidth = track.querySelector(".carousel-slide").offsetWidth;
|
|
track.scrollBy({left: slideWidth, behavior: "smooth"});
|
|
updateCarouselDots(carouselId);
|
|
}
|
|
|
|
function carouselGoTo(carouselId, index) {
|
|
const track = document.querySelector(`#${carouselId} .carousel-track`);
|
|
const slideWidth = track.querySelector(".carousel-slide").offsetWidth;
|
|
track.scrollTo({left: slideWidth * index, behavior: "smooth"});
|
|
updateCarouselDots(carouselId);
|
|
}
|
|
|
|
function updateCarouselDots(carouselId) {
|
|
// Debounced dot state update
|
|
clearTimeout(window.carouselDotTimeout);
|
|
window.carouselDotTimeout = setTimeout(() => {
|
|
const track = document.querySelector(`#${carouselId} .carousel-track`);
|
|
const dots = document.querySelectorAll(`#${carouselId} .carousel-dot`);
|
|
const slideWidth = track.querySelector(".carousel-slide").offsetWidth;
|
|
const currentIndex = Math.round(track.scrollLeft / slideWidth);
|
|
|
|
dots.forEach((dot, index) => {
|
|
if (index === currentIndex) {
|
|
dot.className = dot.className.replace(/bg-gray-\d+/, "bg-nls-orange");
|
|
} else {
|
|
dot.className = dot.className.replace(/bg-nls-\w+/, "bg-gray-300 dark:bg-gray-600");
|
|
}
|
|
});
|
|
}, 100);
|
|
}
|
|
|
|
// Auto-initialize all carousels
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
document.querySelectorAll(".carousel-track").forEach((track) => {
|
|
track.addEventListener(
|
|
"scroll",
|
|
() => {
|
|
const carouselId = track.closest(".carousel-container").id;
|
|
updateCarouselDots(carouselId);
|
|
},
|
|
{passive: true},
|
|
);
|
|
});
|
|
});
|