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...