Replace Swiper with simple image viewer with prev/next buttons
This commit is contained in:
parent
f47470c851
commit
ffe6bd4409
62
components/ImageViewer.vue
Normal file
62
components/ImageViewer.vue
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
<template>
|
||||||
|
<div class="flex flex-col items-center justify-center h-full">
|
||||||
|
<div class="relative w-full flex-1 flex items-center justify-center min-h-0 p-4">
|
||||||
|
<!-- Previous button -->
|
||||||
|
<button
|
||||||
|
v-if="gallery.length > 1"
|
||||||
|
@click="prev"
|
||||||
|
class="absolute left-2 z-10 p-2 bg-gray-600 rounded-full text-white hover:bg-gray-700"
|
||||||
|
>
|
||||||
|
<Icon name="mdi:chevron-left" class="w-6 h-6" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Image -->
|
||||||
|
<NuxtImg
|
||||||
|
v-if="gallery[currentIndex]"
|
||||||
|
:src="'/' + bucket + '/' + gallery[currentIndex].image"
|
||||||
|
class="max-w-full max-h-[60vh] object-contain"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Next button -->
|
||||||
|
<button
|
||||||
|
v-if="gallery.length > 1"
|
||||||
|
@click="next"
|
||||||
|
class="absolute right-2 z-10 p-2 bg-gray-600 rounded-full text-white hover:bg-gray-700"
|
||||||
|
>
|
||||||
|
<Icon name="mdi:chevron-right" class="w-6 h-6" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Dots indicator -->
|
||||||
|
<div v-if="gallery.length > 1" class="flex gap-2 py-2">
|
||||||
|
<button
|
||||||
|
v-for="(img, index) in gallery"
|
||||||
|
:key="index"
|
||||||
|
@click="currentIndex = index"
|
||||||
|
class="w-2 h-2 rounded-full transition-colors"
|
||||||
|
:class="index === currentIndex ? 'bg-gray-600' : 'bg-gray-300'"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
bucket: String,
|
||||||
|
gallery: Array,
|
||||||
|
initialIndex: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const currentIndex = ref(props.initialIndex)
|
||||||
|
|
||||||
|
const next = () => {
|
||||||
|
currentIndex.value = (currentIndex.value + 1) % props.gallery.length
|
||||||
|
}
|
||||||
|
|
||||||
|
const prev = () => {
|
||||||
|
currentIndex.value = (currentIndex.value - 1 + props.gallery.length) % props.gallery.length
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -69,7 +69,9 @@
|
||||||
|
|
||||||
<Modal v-model="modalStore.isOpen" :maxHeight="modalStore.type === 'image' && modalStore.soundcloudUrl ? 'calc(85vh + 60px)' : '85vh'">
|
<Modal v-model="modalStore.isOpen" :maxHeight="modalStore.type === 'image' && modalStore.soundcloudUrl ? 'calc(85vh + 60px)' : '85vh'">
|
||||||
<div class="flex flex-col h-full overflow-hidden">
|
<div class="flex flex-col h-full overflow-hidden">
|
||||||
<ImageSlider v-if="modalStore.type === 'image'" :bucket="modalStore.bucket" :gallery="modalStore.gallery" :initialIndex="modalStore.initialIndex"></ImageSlider>
|
<div v-if="modalStore.type === 'image'" class="flex-1 flex items-center justify-center min-h-0">
|
||||||
|
<ImageViewer :bucket="modalStore.bucket" :gallery="modalStore.gallery" :initialIndex="modalStore.initialIndex"></ImageViewer>
|
||||||
|
</div>
|
||||||
<div v-if="modalStore.type === 'image' && modalStore.soundcloudUrl" class="flex justify-center mt-2">
|
<div v-if="modalStore.type === 'image' && modalStore.soundcloudUrl" class="flex justify-center mt-2">
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<iframe :src="modalStore.soundcloudUrl" class="w-64" height="20px" scrolling="no" frameborder="no" allow="autoplay"></iframe>
|
<iframe :src="modalStore.soundcloudUrl" class="w-64" height="20px" scrolling="no" frameborder="no" allow="autoplay"></iframe>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue