Blossom Carousel Logo
Basic

Dots

Add interactive dot markers with IntersectionObserver.
1
2
3
4
5
6
7
8
9
10
const slides = document.querySelectorAll(".slide");
const dots = document.querySelectorAll(".dot");
let activeIndex = 0;
const intersectionRatioBySlide = new WeakMap<Element, number>();

const observer = new IntersectionObserver(
  (entries) => {
    for (const entry of entries) {
      intersectionRatioBySlide.set(
        entry.target,
        entry.isIntersecting ? entry.intersectionRatio : 0,
      );
    }

    const mostVisible = Array.from(slides).reduce(
      (current, slide, index) => {
        const ratio = intersectionRatioBySlide.get(slide) ?? 0;
        return ratio > current.ratio ? { index, ratio } : current;
      },
      { index: activeIndex, ratio: 0 },
    );

    if (mostVisible.ratio > 0) {
      activeIndex = mostVisible.index;
      dots.forEach((dot, i) => dot.classList.toggle("active", i === activeIndex));
    }
  },
  { threshold: [0, 0.5, 1] },
);

slides.forEach((slide) => observer.observe(slide));

dots.forEach((dot, index) => {
  dot.addEventListener("click", () => {
    slides[index]?.scrollIntoView({
      behavior: "smooth",
      block: "nearest",
      inline: "center",
    });
  });
});