document.addEventListener('DOMContentLoaded', function () {
const track = document.getElementById('carouselTrack');
const dotsWrap = document.getElementById('carouselDots');
if (!track) return;
const prevBtn = document.querySelector('.featured-carousel .carousel-btn.prev');
const nextBtn = document.querySelector('.featured-carousel .carousel-btn.next');
const cards = Array.from(track.children);
if (cards.length === 0) return;
/* Monta os dots dinamicamente, um por card visível na "página" */
function getCardsPerView() {
const w = window.innerWidth;
if (w <= 600) return 1;
if (w <= 992) return 3;
return 4;
}
function buildDots() {
dotsWrap.innerHTML = '';
const perView = getCardsPerView();
const pages = Math.max(1, Math.ceil(cards.length / perView));
for (let i = 0; i < pages; i++) {
const dot = document.createElement('button');
dot.type = 'button';
dot.setAttribute('aria-label', 'Ir para o grupo ' + (i + 1));
dot.addEventListener('click', () => scrollToPage(i));
dotsWrap.appendChild(dot);
}
updateDots();
}
function scrollToPage(pageIndex) {
const perView = getCardsPerView();
const cardIndex = pageIndex * perView;
const target = cards[cardIndex];
if (target) {
track.scrollTo({ left: target.offsetLeft - track.offsetLeft, behavior: 'smooth' });
}
}
function updateDots() {
const perView = getCardsPerView();
const page = Math.round(track.scrollLeft / (cards[0].offsetWidth + 20)) ;
const currentPage = Math.min(
Math.round(page / perView),
dotsWrap.children.length - 1
);
Array.from(dotsWrap.children).forEach((d, i) => {
d.classList.toggle('active', i === currentPage);
});
if (prevBtn) prevBtn.disabled = track.scrollLeft <= 4;
if (nextBtn) nextBtn.disabled = track.scrollLeft >= track.scrollWidth - track.clientWidth - 4;
}
function scrollByCards(direction) {
const perView = getCardsPerView();
const cardWidth = cards[0].offsetWidth + 20; /* gap */
track.scrollBy({ left: direction * cardWidth * perView, behavior: 'smooth' });
}
if (prevBtn) prevBtn.addEventListener('click', () => scrollByCards(-1));
if (nextBtn) nextBtn.addEventListener('click', () => scrollByCards(1));
track.addEventListener('scroll', () => window.requestAnimationFrame(updateDots));
window.addEventListener('resize', () => {
buildDots();
updateDots();
});
/* Drag para arrastar com o mouse (desktop) */
let isDown = false;
let startX;
let scrollLeftStart;
track.addEventListener('mousedown', (e) => {
isDown = true;
track.classList.add('dragging');
startX = e.pageX - track.offsetLeft;
scrollLeftStart = track.scrollLeft;
});
track.addEventListener('mouseleave', () => { isDown = false; });
track.addEventListener('mouseup', () => { isDown = false; });
track.addEventListener('mousemove', (e) => {
if (!isDown) return;
e.preventDefault();
const x = e.pageX - track.offsetLeft;
const walk = (x - startX) * 1.2;
track.scrollLeft = scrollLeftStart - walk;
});
buildDots();
updateDots();
});
Referências: teste