Für meine unendliche Karusssel brauche ich karousel. (carousel.scrollleft () Da dies eine ganze Reihe anderer Probleme aufwirft.
Code: Select all
const carousel = $('.carousel');
const carouselCards = carousel.children('.card');
let cardAmount = 3; // The amount of cards visible within the carousel
carouselCards.slice(-cardAmount).get().reverse().forEach((e) => {
let card = $(e);
carousel.prepend(card.prop('outerHTML')); // Puts the last three cards in front of the first card in reverse order
})
carouselCards.slice(0, cardAmount).get().forEach((e) => {
let card = $(e);
carousel.append(card.prop('outerHTML')); // Puts the first three cards after the last card
})
let scrollTriggerStart = Math.round(carouselCards.outerWidth() + carouselCards.outerWidth() / 2 - carousel.outerWidth() / 2); // The exact scrollLeft value where the second card is in the center of the carousel
let scrollTriggerEnd = Math.round(carousel[0].scrollWidth - carouselCards.outerWidth() - carouselCards.outerWidth() / 2 - carousel.outerWidth() / 2); // The exact scrollLeft value where the second to last card is in the center of the carousel
let seamlessPosStart = carouselCards.length * carouselCards.outerWidth() - carouselCards.outerWidth() / 2 - carousel.outerWidth() / 2; // The exact scrollLeft value of the corresponding card of the second to last card
let seamlessPosEnd = carousel[0].scrollWidth - carouselCards.length * carouselCards.outerWidth() + carouselCards.outerWidth() / 2 - carousel.outerWidth() / 2; // The exact scrollLeft value of the corresponding card of the second card
infiniteScroll = () => {
if (carousel.scrollLeft() = scrollTriggerEnd) {
carousel.addClass('no-transition');
carousel.scrollLeft(seamlessPosStart);
carousel.removeClass('no-transition');
}
}
carousel.on('scroll', infiniteScroll);< /code>
*,
::before,
::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
* {
font: inherit;
}
html,
body {
min-height: 100vh;
}
ul:has([class]) {
list-style: none;
}
body {
font-family: sans-serif;
display: flex;
align-items: center;
justify-content: center;
}
.wrapper {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
gap: 5em;
width: 100%;
padding-inline: 10em;
}
.carousel {
display: grid;
grid-auto-flow: column;
grid-auto-columns: calc(100% / 2);
overflow-x: auto;
scroll-snap-type: x mandatory;
border-radius: .5em;
scroll-behavior: smooth;
scrollbar-width: none;
width: 100%;
}
.carousel::-webkit-scrollbar {
display: none;
}
.carousel .card {
aspect-ratio: 1;
scroll-snap-align: center;
background: rgba(255, 0, 0, 0.25);
border-radius: .5rem;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
scale: 0.95;
border: 2px solid transparent;
transition: 250ms ease;
}
.card.selected {
border: 2px solid red;
scale: 1;
}
.no-transition {
scroll-behavior: auto;
}
.no-transition .card {
scroll-snap-align: unset;
}
/* .slider-interactive {
display: flex;
gap: 4em;
}
.slider-interactive > * {
background: rgba(255,0,0,0.25);
aspect-ratio: 1;
border-radius: 50%;
cursor: pointer;
transition: 250ms ease;
width: 1.5rem;
}
.slider-interactive > *.selected {
background: red;
} */< /code>
[*]
Infinite carousel
[list]
Card 1
[*]
Card 2
[*]
Card 3
[*]
Card 4
[*]
Card 5
[/list]