196 lines
5.3 KiB
JavaScript
196 lines
5.3 KiB
JavaScript
const defaultOptions = {
|
|
active: true,
|
|
breakpoints: {},
|
|
delay: 4000,
|
|
jump: false,
|
|
playOnInit: true,
|
|
stopOnFocusIn: true,
|
|
stopOnInteraction: true,
|
|
stopOnMouseEnter: false,
|
|
stopOnLastSnap: false,
|
|
rootNode: null
|
|
};
|
|
|
|
function normalizeDelay(emblaApi, delay) {
|
|
const scrollSnaps = emblaApi.scrollSnapList();
|
|
if (typeof delay === 'number') {
|
|
return scrollSnaps.map(() => delay);
|
|
}
|
|
return delay(scrollSnaps, emblaApi);
|
|
}
|
|
function getAutoplayRootNode(emblaApi, rootNode) {
|
|
const emblaRootNode = emblaApi.rootNode();
|
|
return rootNode && rootNode(emblaRootNode) || emblaRootNode;
|
|
}
|
|
|
|
function Autoplay(userOptions = {}) {
|
|
let options;
|
|
let emblaApi;
|
|
let destroyed;
|
|
let delay;
|
|
let timerStartTime = null;
|
|
let timerId = 0;
|
|
let autoplayActive = false;
|
|
let mouseIsOver = false;
|
|
let playOnDocumentVisible = false;
|
|
let jump = false;
|
|
function init(emblaApiInstance, optionsHandler) {
|
|
emblaApi = emblaApiInstance;
|
|
const {
|
|
mergeOptions,
|
|
optionsAtMedia
|
|
} = optionsHandler;
|
|
const optionsBase = mergeOptions(defaultOptions, Autoplay.globalOptions);
|
|
const allOptions = mergeOptions(optionsBase, userOptions);
|
|
options = optionsAtMedia(allOptions);
|
|
if (emblaApi.scrollSnapList().length <= 1) return;
|
|
jump = options.jump;
|
|
destroyed = false;
|
|
delay = normalizeDelay(emblaApi, options.delay);
|
|
const {
|
|
eventStore,
|
|
ownerDocument
|
|
} = emblaApi.internalEngine();
|
|
const isDraggable = !!emblaApi.internalEngine().options.watchDrag;
|
|
const root = getAutoplayRootNode(emblaApi, options.rootNode);
|
|
eventStore.add(ownerDocument, 'visibilitychange', visibilityChange);
|
|
if (isDraggable) {
|
|
emblaApi.on('pointerDown', pointerDown);
|
|
}
|
|
if (isDraggable && !options.stopOnInteraction) {
|
|
emblaApi.on('pointerUp', pointerUp);
|
|
}
|
|
if (options.stopOnMouseEnter) {
|
|
eventStore.add(root, 'mouseenter', mouseEnter);
|
|
}
|
|
if (options.stopOnMouseEnter && !options.stopOnInteraction) {
|
|
eventStore.add(root, 'mouseleave', mouseLeave);
|
|
}
|
|
if (options.stopOnFocusIn) {
|
|
emblaApi.on('slideFocusStart', stopAutoplay);
|
|
}
|
|
if (options.stopOnFocusIn && !options.stopOnInteraction) {
|
|
eventStore.add(emblaApi.containerNode(), 'focusout', startAutoplay);
|
|
}
|
|
if (options.playOnInit) startAutoplay();
|
|
}
|
|
function destroy() {
|
|
emblaApi.off('pointerDown', pointerDown).off('pointerUp', pointerUp).off('slideFocusStart', stopAutoplay);
|
|
stopAutoplay();
|
|
destroyed = true;
|
|
autoplayActive = false;
|
|
}
|
|
function setTimer() {
|
|
const {
|
|
ownerWindow
|
|
} = emblaApi.internalEngine();
|
|
ownerWindow.clearTimeout(timerId);
|
|
timerId = ownerWindow.setTimeout(next, delay[emblaApi.selectedScrollSnap()]);
|
|
timerStartTime = new Date().getTime();
|
|
emblaApi.emit('autoplay:timerset');
|
|
}
|
|
function clearTimer() {
|
|
const {
|
|
ownerWindow
|
|
} = emblaApi.internalEngine();
|
|
ownerWindow.clearTimeout(timerId);
|
|
timerId = 0;
|
|
timerStartTime = null;
|
|
emblaApi.emit('autoplay:timerstopped');
|
|
}
|
|
function startAutoplay() {
|
|
if (destroyed) return;
|
|
if (documentIsHidden()) {
|
|
playOnDocumentVisible = true;
|
|
return;
|
|
}
|
|
if (!autoplayActive) emblaApi.emit('autoplay:play');
|
|
setTimer();
|
|
autoplayActive = true;
|
|
}
|
|
function stopAutoplay() {
|
|
if (destroyed) return;
|
|
if (autoplayActive) emblaApi.emit('autoplay:stop');
|
|
clearTimer();
|
|
autoplayActive = false;
|
|
}
|
|
function visibilityChange() {
|
|
if (documentIsHidden()) {
|
|
playOnDocumentVisible = autoplayActive;
|
|
return stopAutoplay();
|
|
}
|
|
if (playOnDocumentVisible) startAutoplay();
|
|
}
|
|
function documentIsHidden() {
|
|
const {
|
|
ownerDocument
|
|
} = emblaApi.internalEngine();
|
|
return ownerDocument.visibilityState === 'hidden';
|
|
}
|
|
function pointerDown() {
|
|
if (!mouseIsOver) stopAutoplay();
|
|
}
|
|
function pointerUp() {
|
|
if (!mouseIsOver) startAutoplay();
|
|
}
|
|
function mouseEnter() {
|
|
mouseIsOver = true;
|
|
stopAutoplay();
|
|
}
|
|
function mouseLeave() {
|
|
mouseIsOver = false;
|
|
startAutoplay();
|
|
}
|
|
function play(jumpOverride) {
|
|
if (typeof jumpOverride !== 'undefined') jump = jumpOverride;
|
|
startAutoplay();
|
|
}
|
|
function stop() {
|
|
if (autoplayActive) stopAutoplay();
|
|
}
|
|
function reset() {
|
|
if (autoplayActive) startAutoplay();
|
|
}
|
|
function isPlaying() {
|
|
return autoplayActive;
|
|
}
|
|
function next() {
|
|
const {
|
|
index
|
|
} = emblaApi.internalEngine();
|
|
const nextIndex = index.clone().add(1).get();
|
|
const lastIndex = emblaApi.scrollSnapList().length - 1;
|
|
const kill = options.stopOnLastSnap && nextIndex === lastIndex;
|
|
if (emblaApi.canScrollNext()) {
|
|
emblaApi.scrollNext(jump);
|
|
} else {
|
|
emblaApi.scrollTo(0, jump);
|
|
}
|
|
emblaApi.emit('autoplay:select');
|
|
if (kill) return stopAutoplay();
|
|
startAutoplay();
|
|
}
|
|
function timeUntilNext() {
|
|
if (!timerStartTime) return null;
|
|
const currentDelay = delay[emblaApi.selectedScrollSnap()];
|
|
const timePastSinceStart = new Date().getTime() - timerStartTime;
|
|
return currentDelay - timePastSinceStart;
|
|
}
|
|
const self = {
|
|
name: 'autoplay',
|
|
options: userOptions,
|
|
init,
|
|
destroy,
|
|
play,
|
|
stop,
|
|
reset,
|
|
isPlaying,
|
|
timeUntilNext
|
|
};
|
|
return self;
|
|
}
|
|
Autoplay.globalOptions = undefined;
|
|
|
|
export { Autoplay as default };
|
|
//# sourceMappingURL=embla-carousel-autoplay.esm.js.map
|