JSFiddle - React, Tailwind, and code Playground
by Yunus Gaziev
HTML
<div class="twc-wrap">
<div class="twc">
<div class="twc-item" data-index="0">
<div class="twc-item__content">
<img class="twc-item__poster" src="https://picsum.photos/seed/picsuma/750/500" alt="">
</div>
</div>
<div class="twc-item" data-index="1">
<div class="twc-item__content">
<img class="twc-item__poster" src="https://picsum.photos/seed/picsumb/750/500" alt="">
</div>
</div>
<div class="twc-item" data-index="2">
<div class="twc-item__content">
<img class="twc-item__poster" src="https://picsum.photos/seed/picsumc/750/500" alt="">
</div>
</div>
<div class="twc-item" data-index="3">
<div class="twc-item__content">
<img class="twc-item__poster" src="https://picsum.photos/seed/picsumd/750/500" alt="">
</div>
</div>
<div class="twc-item" data-index="4">
<div class="twc-item__content">
<img class="twc-item__poster" src="https://picsum.photos/seed/picsumf/750/500" alt="">
</div>
</div>
<div class="twc-item" data-index="5">
<div class="twc-item__content">
<img class="twc-item__poster" src="https://picsum.photos/seed/picsumg/750/500" alt="">
</div>
</div>
<div class="twc-item" data-index="6">
<div class="twc-item__content">
<img class="twc-item__poster" src="https://picsum.photos/seed/picsumh/750/500" alt="">
</div>
</div>
</div>
</div>
<div class="twc-controls">
<button type="button" id="slide_prev">prev</button>
<button type="button" id="slide_next">next</button>
</div>
CSS
:root {
--slide-width: 750px;
--slide-height: 300px;
}
*,
*:before,
*:after {
box-sizing: border-box;
}
.twc-wrap {
width: 100%;
overflow: hidden;
padding-top: 1.4rem;
padding-bottom: 1.4rem;
}
.twc {
position: relative;
width: 100%;
height: var(--slide-height);
}
.twc-item {
position: absolute;
z-index: 5;
opacity: 0;
left: 50%;
width: var(--slide-width);
height: var(--slide-height);
transition: transform .4s linear, opacity .4s linear;
}
.twc-item__content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transition: transform .3s;
}
.twc-item__content:before {
content: '';
position: absolute;
z-index: 30;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .6);
pointer-events: none;
transition: opacity .5s;
}
.twc-item--center .twc-item__content:before {
opacity: 0;
}
.twc-item__poster {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
vertical-align: top;
object-fit: cover;
}
.twc-item--active {
opacity: 1;
}
.twc-item--center {
transform: translateX(-50%) scale(1);
z-index: 30;
}
.twc-item--lp {
transform: translateX(-75%) scale(.85);
z-index: 20;
}
.twc-item--ll {
transform: translateX(-100%) scale(.7);
z-index: 10;
}
.twc-item--lh {
transform: translateX(-120%) scale(.5);
opacity: 0;
z-index: 5;
}
.twc-item--rp {
transform: translateX(-25%) scale(.85);
z-index: 20;
}
.twc-item--rl {
transform: translateX(0) scale(.7);
z-index: 10;
}
.twc-item--rh {
transform: translateX(25%) scale(.5);
opacity: 0;
z-index: 5;
}
.twc-item:hover .twc-item__content {
transform: scale(1.02);
}
.twc-item:hover .twc-item__content:before {
opacity: 0;
}
.twc-controls {
text-align: center;
}
JavaScript
const slides = document.querySelectorAll('.twc-item');
const slide_prev = document.getElementById('slide_prev');
const slide_next = document.getElementById('slide_next');
let stack = ['#', '#', '#', '#', '#', '#', '#'];
let temp = [];
let loop = false;
let center = Math.round(stack.length / 2) -1;
let step = 1;
let direction = '';
let classes = [
'twc-item--lh',
'twc-item--ll',
'twc-item--lp',
'twc-item--center',
'twc-item--rp',
'twc-item--rl',
'twc-item--rh',
];
if (slides.length >= stack.length) {
for (let i = 0; i < center; i++) {
stack[i] = slides.length - center + i;
}
for (let i = center; i < stack.length; i++) {
stack[i] = i - center;
}
loop = true;
}
if (!loop) {
for (let i = center; i < stack.length; i++) {
stack[i] = typeof slides[i - center] !== 'undefined' ? i - center : '#';
}
}
function styleSlides() {
slides.forEach((slide) => {
slide.classList.remove('twc-item--active');
});
stack.forEach((item, index) => {
if (Number.isInteger(item)) {
slides[item].classList.remove(...classes);
slides[item].classList.add(classes[index]);
slides[item].classList.add('twc-item--active');
}
});
}
function slideNext() {
if (!loop && stack[center] === slides.length -1) {
return;
}
temp.unshift(stack[0]);
stack.shift();
let next = stack[stack.length - 1] + 1;
if (typeof slides[next] !== 'undefined') {
stack.push(next);
} else {
stack.push(temp.pop());
}
if (next === temp[temp.length - 1]) {
temp.pop();
}
styleSlides('next');
}
function slidePrev() {
if (!loop) {
if (stack[center] === 0) {
return;
}
stack.unshift(temp[0]);
temp.shift();
temp.push(stack.pop());
}
if (loop) {
let prev = stack[0] - 1;
prev = prev < 0 ? slides.length - 1 : prev;
if (typeof slides[prev] !== 'undefined') {
stack.unshift(prev);
temp.push(stack.pop());
} else {
stack.unshift(temp[0]);
}
if (prev...