Merge pull request #23 from vadimkorr/feature/#22_Pause-autoplay-on-mouseenter

Feature/#22 Pause autoplay on mouseenter
This commit is contained in:
Vadim
2021-04-29 20:26:21 +03:00
committed by GitHub
9 changed files with 104 additions and 7 deletions

View File

@@ -42,6 +42,7 @@ Import component and styles in App component
| `autoplay` | `boolean` | `false` | Enables auto play of pages | | `autoplay` | `boolean` | `false` | Enables auto play of pages |
| `autoplayDuration` | `number` | `3000` | Auto play change interval (ms) | | `autoplayDuration` | `number` | `3000` | Auto play change interval (ms) |
| `autoplayDirection` | `string` | `'next'` | Auto play change direction (`next` or `prev`) | | `autoplayDirection` | `string` | `'next'` | Auto play change direction (`next` or `prev`) |
| `pauseOnFocus` | `boolean` | `false` | Pause autoplay on focus |
| `dots` | `boolean` | `true` | Current page indicator dots | | `dots` | `boolean` | `true` | Current page indicator dots |
| `timingFunction` | `string` | `'ease-in-out'` | CSS animation timing function | | `timingFunction` | `string` | `'ease-in-out'` | CSS animation timing function |

View File

@@ -0,0 +1,21 @@
// focusin event
export function addFocusinEventListener(source, cb) {
source.addEventListener('mouseenter', cb)
source.addEventListener('touchstart', cb)
}
export function removeFocusinEventListener(source, cb) {
source.removeEventListener('mouseenter', cb)
source.removeEventListener('touchstart', cb)
}
// focusout event
export function addFocusoutEventListener(source, cb) {
source.addEventListener('mouseleave', cb)
source.addEventListener('touchend', cb)
source.addEventListener('touchcancel', cb)
}
export function removeFocusoutEventListener(source, cb) {
source.removeEventListener('mouseleave', cb)
source.removeEventListener('touchend', cb)
source.removeEventListener('touchcancel', cb)
}

View File

@@ -0,0 +1,29 @@
import { createDispatcher } from '../../utils/event'
import {
addFocusinEventListener,
removeFocusinEventListener,
addFocusoutEventListener,
removeFocusoutEventListener,
} from './event'
export function focusable(node) {
const dispatch = createDispatcher(node)
function handleFocusin() {
dispatch('focused', { value: true })
}
function handleFocusout() {
dispatch('focused', { value: false })
}
addFocusinEventListener(node, handleFocusin)
addFocusoutEventListener(node, handleFocusout)
return {
destroy() {
removeFocusinEventListener(node, handleFocusin)
removeFocusoutEventListener(node, handleFocusout)
},
}
}

View File

@@ -0,0 +1 @@
export * from './focusable'

View File

@@ -5,6 +5,7 @@
import Arrow from '../Arrow/Arrow.svelte' import Arrow from '../Arrow/Arrow.svelte'
import { NEXT, PREV } from '../../direction' import { NEXT, PREV } from '../../direction'
import { swipeable } from '../../actions/swipeable' import { swipeable } from '../../actions/swipeable'
import { focusable } from '../../actions/focusable'
import { import {
addResizeEventListener, addResizeEventListener,
removeResizeEventListener removeResizeEventListener
@@ -60,6 +61,11 @@
*/ */
export let autoplayDirection = NEXT export let autoplayDirection = NEXT
/**
* Pause autoplay on focus
*/
export let pauseOnFocus = false
/** /**
* Current page indicator dots * Current page indicator dots
*/ */
@@ -76,6 +82,18 @@
let offset = 0 let offset = 0
let pageWindowElement let pageWindowElement
let pagesElement let pagesElement
let focused = false
let autoplayInterval = null
$: {
if (pauseOnFocus) {
if (focused) {
clearAutoplay()
} else {
applyAutoplay()
}
}
}
// used for lazy loading images, preloaded only current, adjacent and cloanable images // used for lazy loading images, preloaded only current, adjacent and cloanable images
$: loaded = getAdjacentIndexes(originalCurrentPageIndex, originalPagesCount, infinite) $: loaded = getAdjacentIndexes(originalCurrentPageIndex, originalPagesCount, infinite)
@@ -96,15 +114,16 @@
} }
function applyAutoplay() { function applyAutoplay() {
let interval if (autoplay && !autoplayInterval) {
if (autoplay) { autoplayInterval = setInterval(() => {
interval = setInterval(() => {
directionFnDescription[autoplayDirection]() directionFnDescription[autoplayDirection]()
}, autoplayDuration) }, autoplayDuration)
} }
return () => { }
interval && clearInterval(interval)
} function clearAutoplay() {
clearInterval(autoplayInterval)
autoplayInterval = null
} }
function addClones() { function addClones() {
@@ -128,12 +147,13 @@
infinite && addClones() infinite && addClones()
applyPageSizes() applyPageSizes()
} }
cleanupFns.push(applyAutoplay()) applyAutoplay()
addResizeEventListener(applyPageSizes) addResizeEventListener(applyPageSizes)
})() })()
}) })
onDestroy(() => { onDestroy(() => {
clearAutoplay()
removeResizeEventListener(applyPageSizes) removeResizeEventListener(applyPageSizes)
cleanupFns.filter(fn => fn && typeof fn === 'function').forEach(fn => fn()) cleanupFns.filter(fn => fn && typeof fn === 'function').forEach(fn => fn())
}) })
@@ -198,6 +218,9 @@
function handleSwipeEnd() { function handleSwipeEnd() {
showPage(currentPageIndex, { offsetDelay: 0, animated: true }) showPage(currentPageIndex, { offsetDelay: 0, animated: true })
} }
function handleFocused(event) {
focused = event.detail.value
}
</script> </script>
<div class="sc-carousel__carousel-container"> <div class="sc-carousel__carousel-container">
@@ -216,6 +239,8 @@
<div <div
class="sc-carousel__pages-window" class="sc-carousel__pages-window"
bind:this={pageWindowElement} bind:this={pageWindowElement}
use:focusable
on:focused={handleFocused}
> >
<div <div
class="sc-carousel__pages-container" class="sc-carousel__pages-container"

View File

@@ -42,6 +42,11 @@
*/ */
export let autoplayDirection = NEXT export let autoplayDirection = NEXT
/**
* Pause autoplay on focus
*/
export let pauseOnFocus = false
/** /**
* Current page indicator dots * Current page indicator dots
*/ */
@@ -77,6 +82,7 @@
{autoplay} {autoplay}
{autoplayDuration} {autoplayDuration}
{autoplayDirection} {autoplayDirection}
{pauseOnFocus}
{dots} {dots}
on:pageChange={ on:pageChange={
event => console.log(`Current page index: ${event.detail}`) event => console.log(`Current page index: ${event.detail}`)
@@ -101,6 +107,7 @@
{autoplay} {autoplay}
{autoplayDuration} {autoplayDuration}
{autoplayDirection} {autoplayDirection}
{pauseOnFocus}
{dots} {dots}
> >
{#each colors2 as { color, text } (color)} {#each colors2 as { color, text } (color)}

View File

@@ -42,6 +42,11 @@
*/ */
export let autoplayDirection = NEXT export let autoplayDirection = NEXT
/**
* Pause autoplay on focus
*/
export let pauseOnFocus = false
/** /**
* Current page indicator dots * Current page indicator dots
*/ */
@@ -71,6 +76,7 @@
{autoplay} {autoplay}
{autoplayDuration} {autoplayDuration}
{autoplayDirection} {autoplayDirection}
{pauseOnFocus}
{dots} {dots}
let:showPrevPage let:showPrevPage
let:showNextPage let:showNextPage

View File

@@ -42,6 +42,11 @@
*/ */
export let autoplayDirection = NEXT export let autoplayDirection = NEXT
/**
* Pause autoplay on focus
*/
export let pauseOnFocus = false
/** /**
* Current page indicator dots * Current page indicator dots
*/ */
@@ -75,6 +80,7 @@
{autoplay} {autoplay}
{autoplayDuration} {autoplayDuration}
{autoplayDirection} {autoplayDirection}
{pauseOnFocus}
{dots} {dots}
let:currentPageIndex let:currentPageIndex
let:pagesCount let:pagesCount

View File

@@ -214,6 +214,7 @@ Import component and styles in App component
| `autoplayDuration` | `number` | `3000` | Auto play change interval (ms) | | `autoplayDuration` | `number` | `3000` | Auto play change interval (ms) |
| `autoplayDirection` | `string` | `'next'` | Auto play change direction (`next` or `prev`) | | `autoplayDirection` | `string` | `'next'` | Auto play change direction (`next` or `prev`) |
| `dots` | `boolean` | `true` | Current page indicator dots | | `dots` | `boolean` | `true` | Current page indicator dots |
| `pauseOnFocus` | `boolean` | `false` | Pause autoplay on focus |
| `timingFunction` | `string` | `'ease-in-out'` | CSS animation timing function | | `timingFunction` | `string` | `'ease-in-out'` | CSS animation timing function |
</div> </div>