Skip to content

Instantly share code, notes, and snippets.

@umutyerebakmaz
Created December 19, 2022 13:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save umutyerebakmaz/121b2f03312dbad32393e00b947b21fa to your computer and use it in GitHub Desktop.
Save umutyerebakmaz/121b2f03312dbad32393e00b947b21fa to your computer and use it in GitHub Desktop.
Carousel Slider with Progress Bar Indicator (JavaScript, AlpineJS, TailwindCSS, Laravel Blade Component)
<div id="slider" class="relative flex-col justify-center items-center pt-5" x-data="slider(6000)">
<div class="relative overflow-hidden rounded shadow">
<!-- progress bar -->
<div id="slider-progress-bar" class="block h-4 bg-indigo-400"></div>
<!-- item 1 -->
<div x-show="active === 1" data-slider-item>
<div class="text-white font-bold absolute text-4xl bottom-1 right-1">1 / 3</div>
<img src="https://images.unsplash.com/photo-1438761681033-6461ffad8d80?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1520&q=80"
loading="lazy" alt="">
<div class="text-white font-bold absolute text-4xl bottom-1 left-1">Caption Text 1</div>
</div>
<!-- item 2 -->
<div x-show="active === 2" data-slider-item>
<div class="text-white font-bold absolute text-4xl bottom-1 right-1">2 / 3</div>
<img src="https://images.unsplash.com/photo-1462804993656-fac4ff489837?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1520&q=80"
loading="lazy" alt="">
<div class="text-white font-bold absolute text-4xl bottom-1 left-1">Caption Text 2</div>
</div>
<!-- item 3 -->
<div x-show="active === 3" data-slider-item>
<div class="text-white font-bold absolute text-4xl bottom-1 right-1">3 / 3</div>
<img src="https://images.unsplash.com/photo-1480455624313-e29b44bbfde1?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1520&q=80"
loading="lazy" alt="">
<div class="text-white font-bold absolute text-4xl bottom-1 left-1">Caption Text 3</div>
</div>
</div>
<!-- prev / next buttons -->
<button class="absolute top-1/2 left-3 z-30 inline-flex items-center p-1 text-indigo-500 rounded-full
hover:bg-indigo-700 hover:text-white hover:border-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2
focus:ring-indigo-500 transition ease-in-out duration-700" x-on:click="prev(active)" data-slider-prev>
<svg aria-hidden="true" class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path></svg>
<span class="sr-only">Previous</span>
</button>
<button class="absolute top-1/2 right-3 z-30 inline-flex items-center p-1 text-indigo-500 rounded-full
hover:bg-indigo-700 hover:text-white hover:border-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2
focus:ring-indigo-500 transition ease-in-out duration-700" x-on:click="next(active)" data-slider-next>
<svg aria-hidden="true" class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
<span class="sr-only">Next</span>
</button>
<!-- navigation buttons -->
<div class="flex gap-2 p-4 items-center justify-center">
<x-buttons.circular-indigo-xs x-on:click="active = 1" ::class="{ 'bg-indigo-500': active === 1 }">
<span class="sr-only">Current</span>
<div class="w-5 h-5"></div>
</x-buttons.circular-indigo-xs>
<x-buttons.circular-indigo-xs x-on:click="active = 2" ::class="{ 'bg-indigo-500': active === 2 }">
<span class="sr-only">Current</span>
<div class="w-5 h-5"></div>
</x-buttons.circular-indigo-xs>
<x-buttons.circular-indigo-xs x-on:click="active = 3" ::class="{ 'bg-indigo-500': active === 3 }">
<span class="sr-only">Current</span>
<div class="w-5 h-5"></div>
</x-buttons.circular-indigo-xs>
</div>
</div>
function slider(duration) {
return {
active: 1,
first: 1,
last: 3,
duration,
progressBarElement: document.getElementById('slider-progress-bar').animate([
{ width: 0 },
{ width: '100%' }
], {
duration,
iterations: Infinity,
}),
init() {
this.slideInterval();
},
slideInterval() {
setInterval(() => {
this.sequence();
}, this.duration);
},
prev(active) {
if (active !== this.first) {
this.active--;
} else {
this.active = this.last;
}
this.handler();
},
next(active) {
if (active !== this.last) {
this.active++;
} else {
this.active = this.first;
}
this.handler();
},
sequence() {
if (this.active === this.last) {
this.active = this.first;
} else {
this.active++;
}
this.handler();
},
handler() {
this.progressBarElement.cancel();
this.progressBarElement.play();
clearInterval(this.slideInterval);
}
}
}
@umutyerebakmaz
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment