125 lines
3.5 KiB
Svelte
125 lines
3.5 KiB
Svelte
<style lang="scss">
|
|
@import "./PostersGrid";
|
|
</style>
|
|
|
|
<script lang="ts">
|
|
import { getContext } from 'svelte'
|
|
import EmblaCarousel, { type EmblaCarouselType } from 'embla-carousel'
|
|
// Components
|
|
import Poster from '$components/molecules/Poster/Poster.svelte'
|
|
import { debounce } from 'utils/actions'
|
|
|
|
let {
|
|
posters,
|
|
}: {
|
|
posters: any[]
|
|
} = $props()
|
|
|
|
let innerWidth = $state<number>()
|
|
let carouselEl = $state<HTMLElement>(undefined)
|
|
let carousel = $state<EmblaCarouselType>()
|
|
let currentSlide = $state(0)
|
|
let carouselDots = $state([])
|
|
|
|
const { shopProducts }: any = getContext('shop')
|
|
|
|
|
|
/** Navigate to specific slide */
|
|
const goToSlide = (index = 0) => {
|
|
carousel.scrollTo(index)
|
|
}
|
|
|
|
/** Init Carousel */
|
|
const initCarousel = () => {
|
|
if (innerWidth < 1200) {
|
|
if (!carousel) {
|
|
carousel = EmblaCarousel(carouselEl, {
|
|
slidesToScroll: innerWidth < 550 ? 1 : 2,
|
|
})
|
|
|
|
// On init
|
|
carousel.on('init', () => {
|
|
// Define amounts of dots
|
|
carouselDots = carousel.scrollSnapList()
|
|
})
|
|
// On slide change
|
|
carousel.on('select', () => {
|
|
// Define current slide
|
|
currentSlide = carousel.selectedScrollSnap()
|
|
})
|
|
// On resize
|
|
carousel.on('resize', () => {
|
|
// Redefine options
|
|
carousel.reInit({
|
|
slidesToScroll: innerWidth < 550 ? 1 : 2
|
|
})
|
|
// Define amounts of dots
|
|
carouselDots = carousel.scrollSnapList()
|
|
// Define current slide
|
|
currentSlide = carousel.selectedScrollSnap()
|
|
})
|
|
}
|
|
} else {
|
|
if (carousel) {
|
|
destroyCarousel()
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Destroy carousel */
|
|
const destroyCarousel = () => {
|
|
carousel.destroy()
|
|
carousel = undefined
|
|
}
|
|
|
|
/** Destroy carousel for larger screens */
|
|
const handleResize = debounce(initCarousel, 200)
|
|
|
|
|
|
$effect(() => {
|
|
if (innerWidth < 1200) {
|
|
initCarousel()
|
|
}
|
|
|
|
// Destroy
|
|
return () => {
|
|
if (carousel) {
|
|
carousel.destroy()
|
|
}
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<svelte:window
|
|
bind:innerWidth
|
|
onresize={handleResize}
|
|
/>
|
|
|
|
<section class="shop-page__posters grid">
|
|
<h3>View all of our available posters</h3>
|
|
|
|
{#if posters}
|
|
<div class="set" bind:this={carouselEl}>
|
|
<div class="set__content">
|
|
{#each posters as { location, photos_product }}
|
|
<Poster
|
|
location={location}
|
|
image={photos_product.length && photos_product[1].directus_files_id}
|
|
product={shopProducts.find(item => item.slug.includes(location.slug))}
|
|
/>
|
|
{/each}
|
|
</div>
|
|
|
|
{#if carousel}
|
|
<ul class="set__dots">
|
|
{#each carouselDots as _, index}
|
|
<li class:is-active={index === currentSlide}>
|
|
<button onclick={() => goToSlide(index)} aria-label="Go to slide #{index + 1}"></button>
|
|
</li>
|
|
{/each}
|
|
</ul>
|
|
{/if}
|
|
</div>
|
|
{/if}
|
|
</section>
|