Reputation: 141
I am trying to build an infinite carousel and everything works fine when I press the next button but when I press prev the last child is prepended after transition end and not look good.
I tried to also prepend it on transition start but the same thing is happening.How can I do it smoothly? You have the code below.Thank you!
const wrapper = document.querySelector('.wrapper');
const container = document.querySelector('.container');
const children = wrapper.querySelectorAll('.child');
const leftArr = document.querySelector('.left-arrow');
const rightArr = document.querySelector('.right-arrow');
let counter = 0;
let infiniteCounter = 0;
container.addEventListener('click', function(e) {
wrapper.style.transition = '.5s ease all';
if(e.target.classList.contains('left-arrow')) {
infiniteCounter = -1;
counter += 20;
wrapper.style.transform = `translateX(${counter}%)`;
}
if(e.target.classList.contains('right-arrow')) {
infiniteCounter = 1;
counter -= 20;
wrapper.style.transform = `translateX(${counter}%)`;
}
});
let infiniteCarousel = function() {
wrapper.style.transition = 'none';
counter = 0;
if(infiniteCounter === 1) {
wrapper.appendChild(wrapper.firstElementChild);
wrapper.style.transform = `translateX(0%)`;
}
if(infiniteCounter === -1) {
wrapper.style.transform = `translateX(0%)`;
wrapper.prepend(wrapper.lastElementChild);
}
}
wrapper.addEventListener('transitionend', infiniteCarousel);
body {
display: flex;
justify-content:center;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
position: relative;
background: black;
width: 80vw;
overflow: hidden;
}
.wrapper {
display: flex;
justify-content: flex-start;
width: 100%;
transition: .5s ease all;
}
.left-arrow, .right-arrow {
display: flex;
cursor: pointer;
justify-content: center;
align-items: center;
font-size: 2rem;
color: white;
width: 50px;
height: 50px;
background: #ED4956;
border-radius: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
.left-arrow {
left: 2%;
top: 50%;
}
.right-arrow {
left: 98%;
top: 50%;
}
.child {
display: inline-flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
height: 250px;
width: 20%;
font-weight: bold;
font-size: 4rem;
}
.child1 {
background: green;
}
.child2 {
background: blue;
}
.child3 {
background: yellow;
}
.child4 {
background: navy;
}
.child5 {
background: red;
}
.child6 {
background: pink;
}
.child7 {
background: grey;
}
.child8 {
background: brown;
}
.child9 {
background: #ff80ed;
}
<div class="container">
<div class="wrapper">
<div class="child child1">1</div>
<div class="child child2">2</div>
<div class="child child3">3</div>
<div class="child child4">4</div>
<div class="child child5">5</div>
<div class="child child6">6</div>
<div class="child child7">7</div>
<div class="child child8">8</div>
<div class="child child9">9</div>
</div>
<div class="left-arrow"> ← </div>
<div class="right-arrow"> → </div>
</div>
Upvotes: 1
Views: 1296
Reputation: 263
The issue you're having is that the previous element doesn't exist and it takes the browser time to put that element there. One way to fix it is to move the whole carousel to the left. This way the first element will be hidden. I added "left: -20%; position: relative" to the wrapper and seems much better
const wrapper = document.querySelector('.wrapper');
const container = document.querySelector('.container');
const children = wrapper.querySelectorAll('.child');
const leftArr = document.querySelector('.left-arrow');
const rightArr = document.querySelector('.right-arrow');
let counter = 0;
let infiniteCounter = 0;
container.addEventListener('click', function(e) {
wrapper.style.transition = '.5s ease all';
if(e.target.classList.contains('left-arrow')) {
infiniteCounter = -1;
counter += 20;
wrapper.style.transform = `translateX(${counter}%)`;
}
if(e.target.classList.contains('right-arrow')) {
infiniteCounter = 1;
counter -= 20;
wrapper.style.transform = `translateX(${counter}%)`;
}
});
let infiniteCarousel = function() {
wrapper.style.transition = 'none';
counter = 0;
if(infiniteCounter === 1) {
wrapper.appendChild(wrapper.firstElementChild);
wrapper.style.transform = `translateX(0%)`;
}
if(infiniteCounter === -1) {
wrapper.style.transform = `translateX(0%)`;
wrapper.prepend(wrapper.lastElementChild);
}
}
wrapper.addEventListener('transitionend', infiniteCarousel);
body {
display: flex;
justify-content:center;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
position: relative;
background: black;
width: 80vw;
overflow: hidden;
}
.wrapper {
display: flex;
justify-content: flex-start;
width: 100%;
transition: .5s ease all;
left: -20%;
position: relative;
}
.left-arrow, .right-arrow {
display: flex;
cursor: pointer;
justify-content: center;
align-items: center;
font-size: 2rem;
color: white;
width: 50px;
height: 50px;
background: #ED4956;
border-radius: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
.left-arrow {
left: 2%;
top: 50%;
}
.right-arrow {
left: 98%;
top: 50%;
}
.child {
display: inline-flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
height: 250px;
width: 20%;
font-weight: bold;
font-size: 4rem;
}
.child1 {
background: green;
}
.child2 {
background: blue;
}
.child3 {
background: yellow;
}
.child4 {
background: navy;
}
.child5 {
background: red;
}
.child6 {
background: pink;
}
.child7 {
background: grey;
}
.child8 {
background: brown;
}
.child9 {
background: #ff80ed;
}
<div class="container">
<div class="wrapper">
<div class="child child1">1</div>
<div class="child child2">2</div>
<div class="child child3">3</div>
<div class="child child4">4</div>
<div class="child child5">5</div>
<div class="child child6">6</div>
<div class="child child7">7</div>
<div class="child child8">8</div>
<div class="child child9">9</div>
</div>
<div class="left-arrow"> ← </div>
<div class="right-arrow"> → </div>
</div>
Upvotes: 3
Reputation: 435
const wrapper = document.querySelector('.wrapper');
const container = document.querySelector('.container');
const children = wrapper.querySelectorAll('.child');
const leftArr = document.querySelector('.left-arrow');
const rightArr = document.querySelector('.right-arrow');
let counter = 0;
let infiniteCounter = 0;
container.addEventListener('click', function(e) {
wrapper.style.transition = '.5s ease all';
if(e.target.classList.contains('left-arrow')) {
infiniteCounter = -1;
counter += 20;
wrapper.style.transform = `translateX(${counter}%)`;
wrapper.style.transform = `translateX(0%)`;
wrapper.prepend(wrapper.lastElementChild);
}
if(e.target.classList.contains('right-arrow')) {
infiniteCounter = 1;
counter -= 20;
wrapper.style.transform = `translateX(${counter}%)`;
wrapper.appendChild(wrapper.firstElementChild);
wrapper.style.transform = `translateX(0%)`;
}
});
let infiniteCarousel = function() {
wrapper.style.transition = 'none';
counter = 0;
}
wrapper.addEventListener('transitionend', infiniteCarousel);
body {
display: flex;
justify-content:center;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
position: relative;
background: black;
width: 80vw;
overflow: hidden;
}
.wrapper {
display: flex;
justify-content: flex-start;
width: 100%;
transition: .5s ease all;
}
.left-arrow, .right-arrow {
display: flex;
cursor: pointer;
justify-content: center;
align-items: center;
font-size: 2rem;
color: white;
width: 50px;
height: 50px;
background: #ED4956;
border-radius: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
.left-arrow {
left: 2%;
top: 50%;
}
.right-arrow {
left: 98%;
top: 50%;
}
.child {
display: inline-flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
height: 250px;
width: 20%;
font-weight: bold;
font-size: 4rem;
}
.child1 {
background: green;
}
.child2 {
background: blue;
}
.child3 {
background: yellow;
}
.child4 {
background: navy;
}
.child5 {
background: red;
}
.child6 {
background: pink;
}
.child7 {
background: grey;
}
.child8 {
background: brown;
}
.child9 {
background: #ff80ed;
}
<div class="container">
<div class="wrapper">
<div class="child child1">1</div>
<div class="child child2">2</div>
<div class="child child3">3</div>
<div class="child child4">4</div>
<div class="child child5">5</div>
<div class="child child6">6</div>
<div class="child child7">7</div>
<div class="child child8">8</div>
<div class="child child9">9</div>
</div>
<div class="left-arrow"> ← </div>
<div class="right-arrow"> → </div>
</div>
Upvotes: 0