project demo
html code
Card Infinite Carousel Animation
css code
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f4f4f9;
}
.viewport {
width: 700px;
height: 330px;
overflow: hidden;
background: #fff;
border-radius: 12px;
padding: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.ribbon {
display: flex;
gap: 20px;
transition: transform 0.5s ease-in-out;
}
.card {
width: 220px;
height: 330px;
flex-shrink: 0;
border-radius: 10px;
}
.card-1 {
background: url(images/background-1.jpg) center/cover;
}
.card-2 {
background: url(images/background-2.jpg) center/cover;
}
.card-3 {
background: url(images/background-3.jpg) center/cover;
}
.card-4 {
background: url(images/background-4.jpg) center/cover;
}
.card-5 {
background: url(images/background-5.jpg) center/cover;
}
javascript code
const ribbon = document.getElementById("ribbon");
const originalCards = document.querySelectorAll(".card");
const cardWidth = 220;
const gapWidth = 20;
const totalStep = cardWidth + gapWidth; // 240px
let currentIndex = 0;
for (i = 0; i < 3; i++) {
const clone = originalCards[i].cloneNode(true);
ribbon.appendChild(clone);
}
function nextMove() {
currentIndex++;
ribbon.style.transition = "transform 0.5s ease-in-out";
ribbon.style.transform = `translateX(${-currentIndex * totalStep}px)`;
if (currentIndex === originalCards.length) {
setTimeout(() => {
ribbon.style.transition = "none";
currentIndex = 0;
ribbon.style.transform = `translateX(0)`;
}, 1000); //1s
}
}
setInterval(nextMove, 2200);