Move to methods, normalized particles to show/to scroll

This commit is contained in:
Vadim
2021-10-08 16:51:42 +03:00
parent a0b90283c0
commit 7652208ea9
3 changed files with 72 additions and 62 deletions

View File

@@ -26,37 +26,35 @@
import { import {
getValueInRange, getValueInRange,
} from '../../utils/math' } from '../../utils/math'
import { get } from '../../utils/object' import { get, switcher } from '../../utils/object'
import { ProgressManager } from '../../utils/ProgressManager' import { ProgressManager } from '../../utils/ProgressManager'
import { wait } from '../../utils/interval' import { wait } from '../../utils/interval'
import { carousel2 } from './carousel2' import { carousel2 } from './carousel2'
// TODO: apply normalize value before saving to reactive
// TODO:
let currentPageIndex let currentPageIndex
let focused = false let focused = false
let progressValue let progressValue
let offset = 0 let offset = 0
let _duration = 0 let _duration = 0
let pagesCount = 1
const [{ data, progressManager }, methods] = carousel2((key, value) => { const [{ data, progressManager }, methods] = carousel2((key, value) => {
const description = { switcher({
'currentPageIndex': () => currentPageIndex = value, 'currentPageIndex': () => currentPageIndex = value,
'progressValue': () => progressValue = value, 'progressValue': () => progressValue = value,
'focused': () => focused = value, 'focused': () => focused = value,
'offset': () => offset = value, 'offset': () => offset = value,
'_duration': () => _duration = value, '_duration': () => _duration = value,
} 'pagesCount': () => pagesCount = value,
description[key] && description[key]() })(key)
}) })
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const directionFnDescription = {
[NEXT]: methods.showNextPage,
[PREV]: methods.showPrevPage
}
/** /**
* CSS animation timing function * CSS animation timing function
* examples: 'linear', 'steps(5, end)', 'cubic-bezier(0.1, -0.6, 0.2, 0)' * examples: 'linear', 'steps(5, end)', 'cubic-bezier(0.1, -0.6, 0.2, 0)'
@@ -95,7 +93,6 @@
export let autoplay = false export let autoplay = false
$: { $: {
data.autoplay = autoplay data.autoplay = autoplay
methods.applyAutoplayIfNeeded(autoplay) // call in carousel2
} }
/** /**
@@ -142,7 +139,7 @@
*/ */
export let particlesToShow = 1 export let particlesToShow = 1
$: { $: {
data.particlesToShow = particlesToShow // verify, normalize, use from data data.particlesToShowInit = particlesToShow
} }
/** /**
@@ -150,7 +147,7 @@
*/ */
export let particlesToScroll = 1 export let particlesToScroll = 1
$: { $: {
data.particlesToScroll = particlesToScroll // verify, normalize, use from data data.particlesToScrollInit = particlesToScroll
} }
export async function goTo(pageIndex, options) { export async function goTo(pageIndex, options) {
@@ -158,15 +155,7 @@
if (typeof pageIndex !== 'number') { if (typeof pageIndex !== 'number') {
throw new Error('pageIndex should be a number') throw new Error('pageIndex should be a number')
} }
await methods.showParticle(getParticleIndexByPageIndex({ await methods.showPage(pageIndex, { animated })
infinite: data.infinite,
pageIndex,
clonesCountHead: data.clonesCountHead,
clonesCountTail: data.clonesCountTail,
particlesToScroll: data.particlesToScroll,
particlesCount: data.particlesCount,
particlesToShow: data.particlesToShow,
}), { animated })
} }
export async function goToPrev(options) { export async function goToPrev(options) {
@@ -181,8 +170,6 @@
let pageWindowWidth = 0 let pageWindowWidth = 0
let particleWidth = 0 let particleWidth = 0
let pageWindowElement let pageWindowElement
let particlesContainer let particlesContainer
@@ -197,13 +184,9 @@
particlesContainerChildren: particlesContainer.children, particlesContainerChildren: particlesContainer.children,
particleWidth: data.particleWidth, particleWidth: data.particleWidth,
}) })
methods.offsetPage({ methods.offsetPage({ animated: false })
animated: false,
})
}) })
// used for lazy loading images, preloaded only current, adjacent and cloanable images // used for lazy loading images, preloaded only current, adjacent and cloanable images
let loaded = [] let loaded = []
// $: loaded = getAdjacentIndexes({ // $: loaded = getAdjacentIndexes({
@@ -231,17 +214,11 @@
}) })
} }
let cleanupFns = []
onMount(() => { onMount(() => {
(async () => { (async () => {
await tick() await tick()
cleanupFns.push(() => progressManager.reset())
if (particlesContainer && pageWindowElement) { if (particlesContainer && pageWindowElement) {
data.particlesCountWithoutClones = particlesContainer.children.length data.particlesCountWithoutClones = particlesContainer.children.length
data.particlesToShow = particlesToShow
data.particlesToScroll = particlesToScroll
await tick() await tick()
data.infinite && addClones() data.infinite && addClones()
@@ -257,33 +234,28 @@
onDestroy(() => { onDestroy(() => {
pageWindowElementResizeObserver.disconnect() pageWindowElementResizeObserver.disconnect()
cleanupFns.filter(fn => fn && typeof fn === 'function').forEach(fn => fn()) progressManager.reset()
}) })
async function handlePageChange(pageIndex) { async function handlePageChange(pageIndex) {
await methods.showParticle(getParticleIndexByPageIndex({ await methods.showPage(pageIndex, { animated: true })
infinite: data.infinite,
pageIndex,
clonesCountHead: data.clonesCountHead,
clonesCountTail: data.clonesCountTail,
particlesToScroll: data.particlesToScroll,
particlesCount: data.particlesCount,
particlesToShow: data.particlesToShow,
}))
} }
// gestures // gestures
function handleSwipeStart() { function handleSwipeStart() {
if (!swiping) return if (!swiping) return
_duration = 0 data._duration = 0
} }
async function handleSwipeThresholdReached(event) { async function handleSwipeThresholdReached(event) {
if (!swiping) return if (!swiping) return
await directionFnDescription[event.detail.direction]() await switcher({
[NEXT]: methods.showNextPage,
[PREV]: methods.showPrevPage
})(event.detail.direction)
} }
function handleSwipeMove(event) { function handleSwipeMove(event) {
if (!swiping) return if (!swiping) return
offset += event.detail.dx data.offset += event.detail.dx
} }
function handleSwipeEnd() { function handleSwipeEnd() {
if (!swiping) return if (!swiping) return
@@ -309,7 +281,7 @@
<div class="sc-carousel__arrow-container"> <div class="sc-carousel__arrow-container">
<Arrow <Arrow
direction="prev" direction="prev"
disabled={!data.infinite && currentPageIndex === 0} disabled={!infinite && currentPageIndex === 0}
on:click={methods.showPrevPage} on:click={methods.showPrevPage}
/> />
</div> </div>
@@ -353,7 +325,7 @@
<div class="sc-carousel__arrow-container"> <div class="sc-carousel__arrow-container">
<Arrow <Arrow
direction="next" direction="next"
disabled={!data.infinite && currentPageIndex === data.pagesCount - 1} disabled={!infinite && currentPageIndex === pagesCount - 1}
on:click={methods.showNextPage} on:click={methods.showNextPage}
/> />
</div> </div>
@@ -364,11 +336,11 @@
<slot <slot
name="dots" name="dots"
currentPageIndex={currentPageIndex} currentPageIndex={currentPageIndex}
pagesCount={data.pagesCount} pagesCount={pagesCount}
showPage={handlePageChange} showPage={handlePageChange}
> >
<Dots <Dots
pagesCount={data.pagesCount} pagesCount={pagesCount}
currentPageIndex={currentPageIndex} currentPageIndex={currentPageIndex}
on:pageChange={event => handlePageChange(event.detail)} on:pageChange={event => handlePageChange(event.detail)}
></Dots> ></Dots>

View File

@@ -10,10 +10,10 @@ import {
import { getClones, applyClones, getClonesCount } from '../../utils/clones' import { getClones, applyClones, getClonesCount } from '../../utils/clones'
import { getAdjacentIndexes } from '../../utils/lazy' import { getAdjacentIndexes } from '../../utils/lazy'
import { getValueInRange } from '../../utils/math' import { getValueInRange } from '../../utils/math'
import { get } from '../../utils/object' import { get, switcher } from '../../utils/object'
import { ProgressManager } from '../../utils/ProgressManager' import { ProgressManager } from '../../utils/ProgressManager'
import { wait } from '../../utils/interval' import { wait } from '../../utils/interval'
import { reactive } from './reactive' import simplyReactive from 'simply-reactive'
// return only getters // return only getters
export const carousel2 = (onChange) => { export const carousel2 = (onChange) => {
@@ -23,11 +23,13 @@ export const carousel2 = (onChange) => {
}, },
}) })
const [data, methods] = reactive( const [data, methods] = simplyReactive(
{ {
particlesCountWithoutClones: 0, particlesCountWithoutClones: 0,
particlesToShow: 1, particlesToShow: 1, // normalized
particlesToScroll: 1, particlesToShowInit: 1, // initial value
particlesToScroll: 1, // normalized
particlesToScrollInit: 1, // initial value
initialPageIndex: 1, initialPageIndex: 1,
particlesCount: 1, particlesCount: 1,
currentParticleIndex: 1, currentParticleIndex: 1,
@@ -100,6 +102,23 @@ export const carousel2 = (onChange) => {
initDuration: (data) => { initDuration: (data) => {
data._duration = data.duration data._duration = data.duration
}, },
applyAutoplay: (data, { applyAutoplayIfNeeded }) => {
applyAutoplayIfNeeded(data.autoplay)
},
setParticlesToShow(data) {
data.particlesToShow = getValueInRange(
1,
data.particlesToShowInit,
data.particlesCountWithoutClones
)
},
setParticlesToScroll(data) {
data.particlesToScroll = getValueInRange(
1,
data.particlesToScrollInit,
data.particlesCountWithoutClones
)
},
}, },
{ {
_prev: (data) => { _prev: (data) => {
@@ -159,12 +178,13 @@ export const carousel2 = (onChange) => {
} }
if (autoplay) { if (autoplay) {
const autoplayDirectionFnDescription = { const onFinish = () =>
[NEXT]: async () => await progressManager.start(showNextPage), switcher({
[PREV]: async () => await progressManager.start(showPrevPage), [NEXT]: showNextPage,
} [PREV]: showPrevPage,
})(autoplayDirection)
await autoplayDirectionFnDescription[autoplayDirection]() await progressManager.start(onFinish)
} }
}, },
// makes delayed jump to 1st or last element // makes delayed jump to 1st or last element
@@ -232,6 +252,20 @@ export const carousel2 = (onChange) => {
) => { ) => {
await changePage(() => _moveToParticle(particleIndex), options) await changePage(() => _moveToParticle(particleIndex), options)
}, },
showPage: async (data, { showParticle }, pageIndex, options) => {
await showParticle(
getParticleIndexByPageIndex({
infinite: data.infinite,
pageIndex,
clonesCountHead: data.clonesCountHead,
clonesCountTail: data.clonesCountTail,
particlesToScroll: data.particlesToScroll,
particlesCount: data.particlesCount,
particlesToShow: data.particlesToShow,
}),
options
)
},
offsetPage: (data, _, options) => { offsetPage: (data, _, options) => {
const animated = get(options, 'animated', true) const animated = get(options, 'animated', true)
return new Promise((resolve) => { return new Promise((resolve) => {

View File

@@ -7,3 +7,7 @@ export const get = (object, fieldName, defaultValue) => {
} }
return defaultValue return defaultValue
} }
export const switcher = (description) => (key) => {
description[key] && description[key]()
}