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

View File

@@ -10,10 +10,10 @@ import {
import { getClones, applyClones, getClonesCount } from '../../utils/clones'
import { getAdjacentIndexes } from '../../utils/lazy'
import { getValueInRange } from '../../utils/math'
import { get } from '../../utils/object'
import { get, switcher } from '../../utils/object'
import { ProgressManager } from '../../utils/ProgressManager'
import { wait } from '../../utils/interval'
import { reactive } from './reactive'
import simplyReactive from 'simply-reactive'
// return only getters
export const carousel2 = (onChange) => {
@@ -23,11 +23,13 @@ export const carousel2 = (onChange) => {
},
})
const [data, methods] = reactive(
const [data, methods] = simplyReactive(
{
particlesCountWithoutClones: 0,
particlesToShow: 1,
particlesToScroll: 1,
particlesToShow: 1, // normalized
particlesToShowInit: 1, // initial value
particlesToScroll: 1, // normalized
particlesToScrollInit: 1, // initial value
initialPageIndex: 1,
particlesCount: 1,
currentParticleIndex: 1,
@@ -100,6 +102,23 @@ export const carousel2 = (onChange) => {
initDuration: (data) => {
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) => {
@@ -159,12 +178,13 @@ export const carousel2 = (onChange) => {
}
if (autoplay) {
const autoplayDirectionFnDescription = {
[NEXT]: async () => await progressManager.start(showNextPage),
[PREV]: async () => await progressManager.start(showPrevPage),
}
const onFinish = () =>
switcher({
[NEXT]: showNextPage,
[PREV]: showPrevPage,
})(autoplayDirection)
await autoplayDirectionFnDescription[autoplayDirection]()
await progressManager.start(onFinish)
}
},
// makes delayed jump to 1st or last element
@@ -232,6 +252,20 @@ export const carousel2 = (onChange) => {
) => {
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) => {
const animated = get(options, 'animated', true)
return new Promise((resolve) => {

View File

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