94 lines
2.0 KiB
TypeScript
94 lines
2.0 KiB
TypeScript
type Props = {
|
|
duration?: number;
|
|
count: number;
|
|
};
|
|
|
|
const useSlider = ({ duration = 0, count }: Props) => {
|
|
// states
|
|
|
|
const sliderTimer = ref<NodeJS.Timeout | null>(null);
|
|
const progressTimer = ref<NodeJS.Timeout | null>(null);
|
|
|
|
const progress = ref(0);
|
|
const activeSlide = ref(0);
|
|
|
|
// methods
|
|
|
|
const slideTo = (index: number) => {
|
|
activeSlide.value = index;
|
|
restartSliderTimer();
|
|
};
|
|
|
|
const nextSlide = () => {
|
|
if (activeSlide.value > count - 2) {
|
|
activeSlide.value = 0;
|
|
} else {
|
|
activeSlide.value = activeSlide.value + 1;
|
|
}
|
|
};
|
|
|
|
const prevSlide = () => {
|
|
if (activeSlide.value < 1) {
|
|
activeSlide.value = count - 1;
|
|
} else {
|
|
activeSlide.value = activeSlide.value - 1;
|
|
}
|
|
};
|
|
|
|
const prevSlideHandler = () => {
|
|
restartSliderTimer();
|
|
runProgress();
|
|
prevSlide();
|
|
};
|
|
|
|
const nextSlideHandler = () => {
|
|
restartSliderTimer();
|
|
runProgress();
|
|
nextSlide();
|
|
};
|
|
|
|
const runProgress = () => {
|
|
const delay = duration / 100;
|
|
|
|
if (progressTimer.value) clearInterval(progressTimer.value);
|
|
progress.value = 0;
|
|
|
|
progressTimer.value = setInterval(() => {
|
|
if (progress.value < 100) {
|
|
progress.value = progress.value + 1;
|
|
}
|
|
}, delay);
|
|
};
|
|
|
|
const restartSliderTimer = () => {
|
|
if (sliderTimer.value) clearInterval(sliderTimer.value);
|
|
runProgress();
|
|
|
|
if (duration > 0) {
|
|
sliderTimer.value = setInterval(() => {
|
|
runProgress();
|
|
nextSlide();
|
|
}, duration);
|
|
}
|
|
};
|
|
|
|
onMounted(() => {
|
|
restartSliderTimer();
|
|
});
|
|
|
|
onUnmounted(() => {
|
|
restartSliderTimer();
|
|
});
|
|
|
|
return {
|
|
activeSlide,
|
|
progress,
|
|
slideTo,
|
|
nextSlide: nextSlideHandler,
|
|
prevSlide: prevSlideHandler,
|
|
restart: restartSliderTimer,
|
|
};
|
|
};
|
|
|
|
export default useSlider;
|