<section class="container max-md:pe-0 py-6 flex flex-col gap-3" x-data="initInstagramSlider" x-init="calcPageSize(); $nextTick(function() { calcActive() })" @resize.window.debounce="calcPageSize(); $nextTick(() => calcActive())" role="group" aria-roledescription="Carousel">
<h2 class="font-bold text-body-lg text-black/56">#Instapur</h2>
<div class="gutter-quarter flex md:grid grid-cols-6 overflow-auto js_slides snap" @scroll.debounce="calcActive">
<div id="slide-0" aria-labelledby="tab-0" role="tabpanel" class="w-[42%] aspect-[3/4] md:w-auto shrink-0 js_slide">
<img class="object-cover w-full h-full" src="/img/instagram/post-1.png" alt="">
</div>
<div id="slide-1" aria-labelledby="tab-1" role="tabpanel" class="w-[42%] aspect-[3/4] md:w-auto shrink-0 js_slide">
<img class="object-cover w-full h-full" src="/img/instagram/post-2.png" alt="">
</div>
<div id="slide-2" aria-labelledby="tab-2" role="tabpanel" class="w-[42%] aspect-[3/4] md:w-auto shrink-0 js_slide">
<img class="object-cover w-full h-full" src="/img/instagram/post-3.png" alt="">
</div>
<div id="slide-3" aria-labelledby="tab-3" role="tabpanel" class="w-[42%] aspect-[3/4] md:w-auto shrink-0 js_slide">
<img class="object-cover w-full h-full" src="/img/instagram/post-4.png" alt="">
</div>
<div id="slide-4" aria-labelledby="tab-4" role="tabpanel" class="w-[42%] aspect-[3/4] md:w-auto shrink-0 js_slide">
<img class="object-cover w-full h-full" src="/img/instagram/post-5.png" alt="">
</div>
<div id="slide-5" aria-labelledby="tab-5" role="tabpanel" class="w-[42%] aspect-[3/4] md:w-auto shrink-0 js_slide">
<img class="object-cover w-full h-full" src="/img/instagram/post-6.png" alt="">
</div>
</div>
<div class="flex items-center justify-center py-6 mt-3 md:hidden">
<div role="tablist" aria-label="Navigation du slider" class="flex flex-wrap justify-center gap-3">
<template x-for="(index, i) in Math.ceil(itemCount / pageSize)" :key="i">
<button class="shrink-0 block h-1 bg-black rounded-full shadow cursor-pointer transition-all duration-300 ease-in-out" role="tab" :id="'tab-' + (index-1)" :aria-controls="'slide-' + (index-1)" :aria-selected="Math.floor(active/pageSize) === index-1" :tabindex="Math.floor(active/pageSize) === index-1 ? 0 : -1" :class="{
'bg-opacity-100 w-22': Math.floor(active/pageSize) === index-1,
'bg-opacity-40 w-6': Math.floor(active/pageSize) !== index-1
}" @click="scrollTo((index-1)*pageSize);">
<span class="sr-only" x-text="'Aller au groupe de slides ' + index"></span>
</button>
</template>
</div>
</div>
</section>
<script>
'use strict';
function initInstagramSlider() {
return {
active: 0,
itemCount: 0,
getSlider() {
return this.$root.querySelector('.js_slides');
},
pageSize: 4,
pageFillers: 0,
calcPageSize() {
const slider = this.getSlider();
if (slider) {
this.itemCount = slider.querySelectorAll('.js_slide').length;
this.pageSize = Math.round(slider.clientWidth / slider.querySelector('.js_slide').clientWidth);
this.pageFillers = (
this.pageSize * Math.ceil(this.itemCount / this.pageSize)
) - this.itemCount;
}
},
calcActive() {
const slider = this.getSlider();
if (slider) {
const sliderItems = this.itemCount + this.pageFillers;
const calculatedActiveSlide = slider.scrollLeft / (slider.scrollWidth / sliderItems);
this.active = Math.round(calculatedActiveSlide / this.pageSize) * this.pageSize;
}
},
scrollPrevious() {
this.scrollTo(this.active - this.pageSize);
},
scrollNext() {
this.scrollTo(this.active + this.pageSize);
},
scrollTo(idx) {
const slider = this.getSlider();
if (slider) {
const slideWidth = slider.scrollWidth / (this.itemCount + this.pageFillers);
slider.scrollLeft = Math.floor(slideWidth) * idx;
this.active = idx;
}
},
}
}
</script>
<section class="container max-md:pe-0 py-6 flex flex-col gap-3"
x-data="initInstagramSlider"
x-init="calcPageSize(); $nextTick(function() { calcActive() })"
@resize.window.debounce="calcPageSize(); $nextTick(() => calcActive())"
role="group"
aria-roledescription="Carousel"
>
<h2 class="font-bold text-body-lg text-black/56">#Instapur</h2>
<div class="gutter-quarter flex md:grid grid-cols-6 overflow-auto js_slides snap" @scroll.debounce="calcActive">
{% for post in posts %}
<div
id="slide-{{ loop.index0 }}"
aria-labelledby="tab-{{ loop.index0 }}"
role="tabpanel"
class="w-[42%] aspect-[3/4] md:w-auto shrink-0 js_slide"
>
<img class="object-cover w-full h-full" src="{{ post.img.src }}" alt="{{ post.img.alt }}">
</div>
{% endfor %}
</div>
{% render '@slider-pagination' with {
class: 'justify-center py-6 mt-3 md:hidden'
} %}
</section>
<script>
'use strict';
function initInstagramSlider() {
return {
active: 0,
itemCount: 0,
getSlider() {
return this.$root.querySelector('.js_slides');
},
pageSize: 4,
pageFillers: 0,
calcPageSize() {
const slider = this.getSlider();
if (slider) {
this.itemCount = slider.querySelectorAll('.js_slide').length;
this.pageSize = Math.round(slider.clientWidth / slider.querySelector('.js_slide').clientWidth);
this.pageFillers = (
this.pageSize * Math.ceil(this.itemCount / this.pageSize)
) - this.itemCount;
}
},
calcActive() {
const slider = this.getSlider();
if (slider) {
const sliderItems = this.itemCount + this.pageFillers;
const calculatedActiveSlide = slider.scrollLeft / (slider.scrollWidth / sliderItems);
this.active = Math.round(calculatedActiveSlide / this.pageSize) * this.pageSize;
}
},
scrollPrevious() {
this.scrollTo(this.active - this.pageSize);
},
scrollNext() {
this.scrollTo(this.active + this.pageSize);
},
scrollTo(idx) {
const slider = this.getSlider();
if (slider) {
const slideWidth = slider.scrollWidth / (this.itemCount + this.pageFillers);
slider.scrollLeft = Math.floor(slideWidth) * idx;
this.active = idx;
}
},
}
}
</script>
{
"title": "#Instapur",
"posts": [
{
"img": {
"src": "/img/instagram/post-1.png"
}
},
{
"img": {
"src": "/img/instagram/post-2.png"
}
},
{
"img": {
"src": "/img/instagram/post-3.png"
}
},
{
"img": {
"src": "/img/instagram/post-4.png"
}
},
{
"img": {
"src": "/img/instagram/post-5.png"
}
},
{
"img": {
"src": "/img/instagram/post-6.png"
}
}
]
}
No notes defined.