Continuous Slide - with loop
by Julien Etienne
HTML
<section>
<nav>
<div class="one">One</div>
<div class="two">Two</div>
<div class="three">Three</div>
<div class="four">Four</div>
<div class="five">Five</div>
</nav>
</section>
<button id="prev">Prev</button><button id="next">Next</button>
<div id="direct">
<button id="0">1</button>
<button id="1">2</button>
<button id="2">3</button>
<button id="3">4</button>
<button id="4">5</button>
</div>
CSS
section {
width: 400px;
height: 200px;
border: 1px solid lime;
position: relative;
overflow: hidden;
}
nav {
display: grid;
grid-auto-flow: column;
height: 200px;
transform-origin: 50% 50%;
transition: all 400ms ease;
left: 0;
position: absolute;
>.one {
background: lightblue;
}
>.two {
background: lightgreen;
}
>.three {
background: lightgray;
}
>.four {
background: lightyellow;
}
>.five {
background: lightpink;
}
}
div {
width: 400px;
height: 200px;
font-size: 6rem;
display: grid;
justify-content: center;
align-content: center;
}
JavaScript
const list = document.querySelector('nav')
const items = Array.from(list.children)
const prev = document.querySelector('#prev')
const next = document.querySelector('#next')
const width = 400
const height = 200
const {
abs
} = Math
const raf = window.requestAnimationFrame
// Get last item and place it next to first
// list.insertAdjacentElement('afterbegin', list.lastElementChild)
// Move one back
// let transform = -width
let transform = 0
list.style.transform = `translate3d(${transform}px, 0,0)`
let index = 0
let initial = 0
let lastIndex = 0
let initialLast = 0
let end = false
let endLeft = false
document.addEventListener('mousedown', ({
target
}) => {
let dir
if (target === next) {
if (index >= items.length - 1 || end) {
end = true
list.style.transition = 'none'
list.insertAdjacentElement('beforeend', list.firstElementChild)
list.style.transform = `translate3d(${transform}px, 0,0)`
raf(() => {
list.style.transition = 'all 400ms ease'
transform -= width
list.style.transform = `translate3d(${transform}px, 0,0)`
})
list.style.transition = 'none'
transform += width
list.style.transform = `translate3d(${transform}px, 0,0)`
}else{
index++
}
initial++
if (initial === items.length) initial = 0
dir = true
}
if (target === prev) {
if (index === 0 || endLeft) {
endLeft = true
list.style.transition = 'none'
list.insertAdjacentElement('afterbegin', list.lastElementChild)
list.style.transform = `translate3d(${transform}px, 0,0)`
raf(() => {
list.style.transition = 'all 400ms ease'
transform += width
list.style.transform = `translate3d(${transform}px, 0,0)`
})
list.style.transition = 'none'
transform -= width
list.style.transform = `translate3d(${transform}px, 0,0)`
} else {
index--
}
dir = false
}
if (target.closest('#direct'))...