Slide prototype 3
by Julien Etienne
HTML
<section>
<div class="navs" id="navs">
<nav id="list">
<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>
<div class="six">Six</div>
</nav>
</div>
</section>
<aside>
<button id="prev">Prev</button><button id="next">Next</button>
</aside>
<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>
<button id="5">6</button>
</div>
CSS
body {
display: grid;
justify-content: center;
--width: 200px
}
section {
width: 300px;
height: 100px;
border: 4px solid crimson;
position: relative;
overflow: hidden;
left: calc(var(--width) * -1);
}
.navs {
/* display: grid; */
grid-auto-flow: column;
position: absolute;
width: calc(200px * 6 * 3);
/* left: calc(200px * -6); */
margin-left: 50px;
height: 100px;
border: 1px solid lime;
display: inline;
}
nav {
display: grid block;
grid-auto-flow: column;
height: 100px;
transform-origin: 50% 50%;
transition: all 400ms ease;
/* position: absolute; */
float: left;
position: relative;
/* border: 1px solid blue; */
>.one {
background: lightblue;
}
>.two {
background: lightgreen;
}
>.three {
background: lightgray;
}
>.four {
background: lightyellow;
}
>.five {
background: lightpink;
}
>.six {
background: orange;
}
}
nav:nth-child(1) {}
/* nav:nth-child(2) {
display: none;
} */
div {
width: 200px;
height: 100px;
font-size: 3rem;
display: grid;
justify-content: center;
align-content: center;
}
#prev,
#next {
display: inline;
margin-top: 2rem;
}
JavaScript
const main = document.querySelector('#list')
const navs = document.querySelector('#navs')
const leftPad = main.cloneNode(true)
leftPad.removeAttribute('id')
const wrapper = [leftPad, main]
if (leftPad.children.length <= 5) wrapper.push(leftPad.cloneNode(true))
navs.append(...wrapper)
const lists = Array.from(navs.children)
const items = wrapper.map(nav => Array.from(nav.children))
const items1Length = items[1].length
const oItems = Array.from(items[1])
const prev = document.querySelector('#prev')
const next = document.querySelector('#next')
const width = 200
const height = 100
const displace = -2
let index = 0
const transitionStyle = 'all 200ms ease'
let transform = 0
const navWidth = navs.children[1].getBoundingClientRect().width
const transformAction = transformValue => el => el.style.transform = `translate3d(${transformValue}px,0,0)`
const transitionAction = value => el => el.style.transition = value
navs.style.left = -(navWidth + (width * -displace)) + 'px'
const rotate = (amount, transition = true) => {
const i = items[1].findIndex(item => item === oItems[amount])
amount = -(i + displace)
items.forEach((item, i) => items[i] = [...items[i].slice(-amount), ...items[i].slice(0, -amount)])
wrapper.forEach((navEl, i) => navEl.append(...items[i]))
if (!transition) return
transform -= width * amount
wrapper.forEach(transitionAction('none'))
wrapper.forEach(transformAction(transform))
window.requestAnimationFrame(() => {
wrapper.forEach(transitionAction(transitionStyle))
transform += width * amount
wrapper.forEach(transformAction(transform))
})
}
rotate(0, false)
document.addEventListener('mousedown', ({
target
}) => {
if (target === next) index++
if (target === prev) index--
index = index % items1Length
if (index < 0) index += items1Length
if (target.closest('#direct') && target.tagName === 'BUTTON') {
index = parseFloat(target.id)
rotate(index)
return
}
if (target === next || target ===...