penguinui is now in the root dir in penguinui-components/
This commit is contained in:
72
penguinui-components/carousel/carousel-with-touch.html
Normal file
72
penguinui-components/carousel/carousel-with-touch.html
Normal file
@@ -0,0 +1,72 @@
|
||||
<div x-data="{
|
||||
slides: [
|
||||
{
|
||||
imgSrc: 'https://penguinui.s3.amazonaws.com/component-assets/carousel/default-slide-1.webp',
|
||||
imgAlt: 'Vibrant abstract painting with swirling blue and light pink hues on a canvas.',
|
||||
},
|
||||
{
|
||||
imgSrc: 'https://penguinui.s3.amazonaws.com/component-assets/carousel/default-slide-2.webp',
|
||||
imgAlt: 'Vibrant abstract painting with swirling red, yellow, and pink hues on a canvas.',
|
||||
},
|
||||
{
|
||||
imgSrc: 'https://penguinui.s3.amazonaws.com/component-assets/carousel/default-slide-3.webp',
|
||||
imgAlt: 'Vibrant abstract painting with swirling blue and purple hues on a canvas.',
|
||||
},
|
||||
],
|
||||
currentSlideIndex: 1,
|
||||
touchStartX: null,
|
||||
touchEndX: null,
|
||||
swipeThreshold: 50,
|
||||
previous() {
|
||||
if (this.currentSlideIndex > 1) {
|
||||
this.currentSlideIndex = this.currentSlideIndex - 1
|
||||
} else {
|
||||
// If it's the first slide, go to the last slide
|
||||
this.currentSlideIndex = this.slides.length
|
||||
}
|
||||
},
|
||||
next() {
|
||||
if (this.currentSlideIndex < this.slides.length) {
|
||||
this.currentSlideIndex = this.currentSlideIndex + 1
|
||||
} else {
|
||||
// If it's the last slide, go to the first slide
|
||||
this.currentSlideIndex = 1
|
||||
}
|
||||
},
|
||||
handleTouchStart(event) {
|
||||
this.touchStartX = event.touches[0].clientX
|
||||
},
|
||||
handleTouchMove(event) {
|
||||
this.touchEndX = event.touches[0].clientX
|
||||
},
|
||||
handleTouchEnd() {
|
||||
if(this.touchEndX){
|
||||
if (this.touchStartX - this.touchEndX > this.swipeThreshold) {
|
||||
this.next()
|
||||
}
|
||||
if (this.touchStartX - this.touchEndX < -this.swipeThreshold) {
|
||||
this.previous()
|
||||
}
|
||||
this.touchStartX = null
|
||||
this.touchEndX = null
|
||||
}
|
||||
},
|
||||
}" class="relative w-full overflow-hidden">
|
||||
|
||||
<!-- slides -->
|
||||
<!-- Change min-h-[50svh] to your preferred height size -->
|
||||
<div class="relative min-h-[50svh] w-full" x-on:touchstart="handleTouchStart($event)" x-on:touchmove="handleTouchMove($event)" x-on:touchend="handleTouchEnd()">
|
||||
<template x-for="(slide, index) in slides">
|
||||
<div x-show="currentSlideIndex == index + 1" class="absolute inset-0" x-transition.opacity.duration.700ms>
|
||||
<img class="absolute w-full h-full inset-0 object-cover text-on-surface dark:text-on-surface-dark" x-bind:src="slide.imgSrc" x-bind:alt="slide.imgAlt" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- indicators -->
|
||||
<div class="absolute rounded-radius bottom-3 md:bottom-5 left-1/2 z-20 flex -translate-x-1/2 gap-4 md:gap-3 bg-surface/75 px-1.5 py-1 md:px-2 dark:bg-surface-dark/75" role="group" aria-label="slides" >
|
||||
<template x-for="(slide, index) in slides">
|
||||
<button class="size-2 rounded-full transition bg-on-surface dark:bg-on-surface-dark" x-on:click="currentSlideIndex = index + 1" x-bind:class="[currentSlideIndex === index + 1 ? 'bg-on-surface dark:bg-on-surface-dark' : 'bg-on-surface/50 dark:bg-on-surface-dark/50']" x-bind:aria-label="'slide ' + (index + 1)"></button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user