JSFiddle - React, Tailwind, and code Playground
by mariomc
HTML
<body>
<div class="outer-container">
<div class="container">
<div class="slide prev">1</div>
<div class="slide active">2</div>
<div class="slide next">3</div>
<div class="slide">4</div>
<div class="slide">5</div>
<div class="slide">6</div>
<div class="slide">7</div>
<div class="slide">8</div>
<div class="slide">9</div>
</div>
</div>
<p>
<button class="prev-button">Prev</button>
<button class="next-button">Next</button>
</p>
</body>
CSS
.outer-container {
width: 400px;
margin: 0 auto;
}
.container {
width: 50%;
margin: 0 auto;
height: 200px;
position: relative;
}
.slide {
height: 100%;
font-size: 5rem;
position: absolute;
inset: 0;
background-color: white;
border: 1px solid red;
align-items: center;
justify-content: center;
display: flex;
}
.animating {
background: green;
}
.active {
z-index: 1;
opacity: 1;
transform: translate3d(0, 0, 0);
}
.prev {
z-index: 2;
opacity: 1;
transform: translate3d(-100%, 0, 0);
}
.next {
z-index: 2;
opacity: 1;
transform: translate3d(100%, 0, 0);
}
JavaScript
const prevButton = document.querySelector('.prev-button');
const nextButton = document.querySelector('.next-button');
const first = document.querySelector('.slide:first-child');
const last = document.querySelector('.slide:last-child');
let state = {
active: document.querySelector('.active'),
prev: document.querySelector('.prev'),
next: document.querySelector('.next'),
animation: null,
};
const setState = (newState) => {
state = {
...state,
...newState
};
}
const toActiveAnimation = [{
transform: "translate3d(0,0,0)"
}];
const ANIMATION_DURATION = 5000;
const removeAllStateClasses = ({
active,
prev,
next
}) => {
active.classList.remove('active');
prev.classList.remove('prev');
next.classList.remove('next');
}
const addAllStateClasses = ({
active,
prev,
next
}) => {
active.classList.add('active');
prev.classList.add('prev');
next.classList.add('next');
}
const animationStart = (oldState, newState, animation) => {
setState({
animation
});
newState.active.classList.add('animating');
}
const animationEnd = (oldState, newState) => {
newState.active.classList.remove('animating');
removeAllStateClasses(oldState);
addAllStateClasses(newState);
setState({
...newState,
animation: null
});
};
const NEXT = 'next';
const PREV = 'prev';
const selectNextUp = (state, slide, direction) => {
if (direction === NEXT) return slide.nextElementSibling || first;
return slide.previousElementSibling || last;
}
const move = (state, direction = NEXT) => {
// The "next"/"prev" will become the new active
const active = state[direction];
// Represents the next slide in the current direction
const nextUp = selectNextUp(state, active, direction);
const oppositeDirection = direction === NEXT ? PREV : NEXT;
return {
active,
[oppositeDirection]: state.active,
[direction]: nextUp
}
}
const transitionState = async (oldState, newState) => {
const animation =...