JSFiddle - React, Tailwind, and code Playground

by ninty9notout

HTML

<div class="slides">
    <div class="slide">
        <img src="https://loremflickr.com/640/480/wolf?random=1">
    </div>
    
    <div class="slide">
        <img src="https://loremflickr.com/640/480/wolf?random=2">
    </div>
    
    <div class="slide">
        <img src="https://loremflickr.com/640/480/wolf?random=3">
    </div>
    
    <div class="slide">
        <img src="https://loremflickr.com/640/480/wolf?random=4">
    </div>
    
    <div class="slide">
        <img src="https://loremflickr.com/640/480/wolf?random=5">
    </div>
</div>

CSS

body {
    --circle-center-center-out: circle(0%);
    --circle-center-center-in: circle(125%);
    --circle-hesitate: circle(40%);
    --circle-top-left-out: circle(0% at top left);
    --circle-top-right-out: circle(0% at top right);
    --circle-bottom-right-out: circle(0% at bottom right);
    --circle-bottom-left-out: circle(0% at bottom left);
    --circle-top-left-in: circle(150% at top left);
    --circle-top-right-in: circle(150% at top right);
    --circle-bottom-right-in: circle(150% at bottom right);
    --circle-bottom-left-in: circle(150% at bottom left);

    margin: 0;
    padding: 0;
}

.slides {
    position: relative;
    width: 640px;
    height: 480px;
}

.slide {
    position: absolute;
    width: 100%;
    height: 100%;
    clip-path: var(--circle-center-center-out);
    animation-delay: 0;
    animation-duration: 5s;
    animation-timing-function: cubic-bezier(0.25, 1, 0.3, 1);
    animation-fill-mode: both;
    will-change: clip-path;
}

@keyframes circle-in-bottom-left {
    from {
        clip-path: var(--circle-center-center-out);
    }
    to {
        clip-path: var(--circle-bottom-left-in);
    }
}

@keyframes circle-in-bottom-right {
    from {
        clip-path: var(--circle-center-center-out);
    }
    to {
        clip-path: var(--circle-bottom-right-in);
    }
}

@keyframes circle-in-center {
    from {
        clip-path: var(--circle-center-center-out);
    }
    to {
        clip-path: var(--circle-center-center-in);
    }
}

@keyframes circle-in-hesitate {
    0% {
        clip-path: var(--circle-center-center-out);
    }
    40% {
        clip-path: var(--circle-hesitate);
    }
    100% {
        clip-path: var(--circle-center-center-in);
    }
}

@keyframes circle-in-top-left {
    from {
        clip-path: var(--circle-center-center-out);
    }
    to {
        clip-path: var(--circle-top-left-in);
    }
}

@keyframes circle-in-top-right {
    from {
        clip-path: var(--circle-center-center-out);
    }
    to {
   ...

JavaScript

const transitionDuration = 10000;
const slideDuration = 1000;

let counter = 1;

const transitions = [
    'circle-in-bottom-left',
    'circle-in-bottom-right',
    // 'circle-in-center',
    // 'circle-in-hesitate',
    'circle-in-top-left',
    'circle-in-top-right',
]

const slides = document.querySelectorAll('.slide');

function animate(index) {
	const random = Math.random();
    const transitionIndex = Math.floor(random * transitions.length);
    const transition = transitions[transitionIndex];

	const slide = slides[index % slides.length];

	slide.style.zIndex = counter++;
    slide.style.animationName = transition;
    slide.style.animationDuration = `${transitionDuration}ms`;

    setTimeout(() => {
        animate(index + 1);
    }, transitionDuration + slideDuration);

    setTimeout(() => {
    	slide.style.animationName = 'none';
	}, transitionDuration + slideDuration + transitionDuration);
}

animate(0);