Skip to content

Commit

Permalink
fix: carousel autoplay issues
Browse files Browse the repository at this point in the history
  • Loading branch information
eddieferrer committed Jan 10, 2025
1 parent cfdd1a3 commit ae1e7eb
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 12 deletions.
33 changes: 21 additions & 12 deletions @kiva/kv-components/utils/carousels.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,6 @@ export function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
goToSlide(index);
}

/** Stop autoplay on user interaction */
const autoplay = embla.value?.plugins()?.autoplay;
if (autoplay) {
autoplay.stop();
}

/**
* Fires when the user interacts with the carousel.
* Contains the interaction type (swipe-left, click-left-arrow, etc.)
Expand Down Expand Up @@ -134,7 +128,7 @@ export function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
};
const onCarouselContainerClick = (e) => {
// If we're dragging, block click handlers within slides
if (embla.value && !embla.value.clickAllowed()) {
if (embla.value) {
e.preventDefault();
e.stopPropagation();
}
Expand All @@ -153,22 +147,26 @@ export function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
return false;
};

onMounted(async () => {
const combinedPluginOptions = [];
const combinedPluginOptions = computed(() => {
const options = [];
if (Object.keys(autoplayOptions.value).length !== 0) {
combinedPluginOptions.push(Autoplay(autoplayOptions.value));
options.push(Autoplay(autoplayOptions.value));
}
if (fadeEnabled.value) {
combinedPluginOptions.push(Fade());
options.push(Fade());
}
return options;
});

onMounted(async () => {
embla.value = EmblaCarousel(rootEl.value, {
loop: true,
containScroll: 'trimSnaps',
inViewThreshold: 0.9,
align: 'start',
...extraEmblaOptions,
...emblaOptions.value,
}, combinedPluginOptions);
}, combinedPluginOptions.value);

if (slidesToScroll.value === 'visible') {
reInitVisible();
Expand All @@ -192,6 +190,17 @@ export function carouselUtil(props, { emit, slots }, extraEmblaOptions) {

embla?.value?.on('select', () => {
currentIndex.value = embla.value.selectedScrollSnap();

/** After the select event, it is possible that embla will itself trigger a reinit.
* For example, if the act of selecting a slide causes it to change dimensions and the carousel
* needs to recalculate.
* When this reinit happens, autoplay settings will reset to the initial plugin options.
* Set playOnInit equal to the current state of autoplay to prevent this.
*/
const autoplay = embla.value?.plugins()?.autoplay;
if (autoplay) {
embla.value.plugins().autoplay.options.playOnInit = autoplay.isPlaying();
}
/**
* The index of the slide that the carousel has changed to
* @event change
Expand Down
61 changes: 61 additions & 0 deletions @kiva/kv-components/vue/stories/KvVerticalCarousel.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,26 +189,87 @@ export const AutoPlayButton = () => ({
},
data: () => ({
isAutoplaying: false,
currentSlide: 0,
}),
mounted() {
watch(() => this.$refs?.sampleCarousel?.isAutoplaying, (newValue) => {
this.isAutoplaying = newValue;
});
},
methods: {
changeEvent(index) {
this.currentSlide = index;
},
},
template: `
<div>
<kv-vertical-carousel
ref="sampleCarousel"
style="max-width: 400px;"
:embla-options="{ loop: false }"
:autoplay-options="{ playOnInit: true, delay: 3000 }"
@change="changeEvent"
>
${defaultCarouselSlides}
</kv-vertical-carousel>
<a href="#" @click.native.prevent="$refs.sampleCarousel.toggleAutoPlay()" role="toggleAutoPlayButton">Toggle AutoPlay</a>
<br/>
<p>AutoPlay is: {{ isAutoplaying ? 'ON' : 'OFF' }}</p>
<a href="#" @click.native.prevent="$refs.sampleCarousel.goToSlide(0)">Go To Slide 0</a>
<p>Current Slide: {{ currentSlide }}</p>
</div>
`,
});

export const AutoPlayWithDynamicSlides = () => ({
components: {
KvVerticalCarousel,
},
data: () => ({
isAutoplaying: false,
currentSlide: 0,
}),
mounted() {
watch(() => this.$refs?.sampleCarousel?.isAutoplaying, (newValue) => {
this.isAutoplaying = newValue;
});
},
methods: {
changeEvent(index) {
this.currentSlide = index;
},
},
template: `
<div>
<kv-vertical-carousel
ref="sampleCarousel"
style="max-width: 400px;"
:embla-options="{ loop: false }"
:autoplay-options="{ playOnInit: true, delay: 3000 }"
@change="changeEvent"
>
<template #slide1 >
<img src="https://placehold.co/400x150/${randomHexColor(1)}/000000">
<p style="background-color: #${randomHexColor(1)};" v-if="currentSlide === 0" >Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
</template>
<template #slide2>
<img src="https://placehold.co/400x150/${randomHexColor(2)}/000000">
<p style="background-color: #${randomHexColor(2)};" v-if="currentSlide === 1">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
</template>
<template #slide3>
<img src="https://placehold.co/400x150/${randomHexColor(3)}/000000">
<p style="background-color: #${randomHexColor(3)};" v-if="currentSlide === 2">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
</template>
<template #slide4>
<img src="https://placehold.co/400x150/${randomHexColor(4)}/000000">
<p style="background-color: #${randomHexColor(4)};" v-if="currentSlide === 3">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
</template>
</kv-vertical-carousel>
<a href="#" @click.native.prevent="$refs.sampleCarousel.toggleAutoPlay()" role="toggleAutoPlayButton">Toggle AutoPlay</a>
<br/>
<p>AutoPlay is: {{ isAutoplaying ? 'ON' : 'OFF' }}</p>
<a href="#" @click.native.prevent="$refs.sampleCarousel.goToSlide(0)">Go To Slide 0</a>
<p>Current Slide: {{ currentSlide }}</p>
</div>
`,
});
Expand Down

0 comments on commit ae1e7eb

Please sign in to comment.