Fix autoplay

This commit is contained in:
Vadim
2021-10-08 19:31:36 +03:00
parent 7652208ea9
commit 87a60678ba
2 changed files with 65 additions and 49 deletions

View File

@@ -30,26 +30,26 @@
import { ProgressManager } from '../../utils/ProgressManager'
import { wait } from '../../utils/interval'
import { carousel2 } from './carousel2'
// TODO: apply normalize value before saving to reactive
// TODO:
import createCarousel from './createCarousel'
// used for lazy loading images, preloaded only current, adjacent and cloanable images
let loaded = []
let currentPageIndex
let focused = false
let progressValue
let offset = 0
let _duration = 0
let durationMs = 0
let pagesCount = 1
const [{ data, progressManager }, methods] = carousel2((key, value) => {
const [{ data, progressManager }, methods, service] = createCarousel((key, value) => {
switcher({
'currentPageIndex': () => currentPageIndex = value,
'progressValue': () => progressValue = value,
'focused': () => focused = value,
'offset': () => offset = value,
'_duration': () => _duration = value,
'durationMs': () => durationMs = value,
'pagesCount': () => pagesCount = value,
'loaded': () => loaded = value,
})(key)
})
@@ -78,13 +78,16 @@
* Page to start on
*/
export let initialPageIndex = 0
$: {
data.initialPageIndexInit = initialPageIndex
}
/**
* Transition duration (ms)
*/
export let duration = 500
$: {
data.duration = duration
data.durationMsInit = duration
}
/**
@@ -160,7 +163,7 @@
export async function goToPrev(options) {
const animated = get(options, 'animated', true)
await methods.showPrevPage({ animated })
await methods.showPrevPage({ animated })
}
export async function goToNext(options) {
@@ -187,17 +190,6 @@
methods.offsetPage({ animated: false })
})
// used for lazy loading images, preloaded only current, adjacent and cloanable images
let loaded = []
// $: loaded = getAdjacentIndexes({
// infinite,
// pageIndex: currentPageIndex,
// pagesCount,
// particlesCount: particlesCountWithoutClones,
// particlesToShow: _particlesToShow,
// particlesToScroll,
// }).particleIndexes
function addClones() {
const {
clonesToAppend,
@@ -244,7 +236,7 @@
// gestures
function handleSwipeStart() {
if (!swiping) return
data._duration = 0
data.durationMs = 0
}
async function handleSwipeThresholdReached(event) {
if (!swiping) return
@@ -272,6 +264,11 @@
function handleTapped(event) {
methods.toggleFocused()
}
function showPrevPage() {
methods.showPrevPage()
console.log(service._getSubscribers())
}
</script>
<div class="sc-carousel__carousel-container">
@@ -282,7 +279,7 @@
<Arrow
direction="prev"
disabled={!infinite && currentPageIndex === 0}
on:click={methods.showPrevPage}
on:click={showPrevPage}
/>
</div>
</slot>
@@ -307,7 +304,7 @@
on:swipeThresholdReached={handleSwipeThresholdReached}
style="
transform: translateX({offset}px);
transition-duration: {_duration}ms;
transition-duration: {durationMs}ms;
transition-timing-function: {timingFunction};
"
bind:this={particlesContainer}

View File

@@ -1,36 +1,34 @@
import simplyReactive from 'simply-reactive'
import { NEXT, PREV } from '../../direction'
import {
applyParticleSizes,
getCurrentPageIndexByCurrentParticleIndex,
getPartialPageSize,
getPagesCountByParticlesCount,
getParticleIndexByPageIndex,
createResizeObserver,
} from '../../utils/page'
import { getClones, applyClones, getClonesCount } from '../../utils/clones'
import { getClonesCount } from '../../utils/clones'
import { getAdjacentIndexes } from '../../utils/lazy'
import { getValueInRange } from '../../utils/math'
import { get, switcher } from '../../utils/object'
import { ProgressManager } from '../../utils/ProgressManager'
import { wait } from '../../utils/interval'
import simplyReactive from 'simply-reactive'
// return only getters
export const carousel2 = (onChange) => {
function createCarousel(onChange) {
const progressManager = new ProgressManager({
onProgressValueChange: (value) => {
onChange('progressValue', 1 - value)
},
})
const [data, methods] = simplyReactive(
const [data, methods, service] = simplyReactive(
{
particlesCountWithoutClones: 0,
particlesToShow: 1, // normalized
particlesToShowInit: 1, // initial value
particlesToScroll: 1, // normalized
particlesToScrollInit: 1, // initial value
initialPageIndex: 1,
initialPageIndex: 1, // normalized
initialPageIndexInit: 1, // initial value
particlesCount: 1,
currentParticleIndex: 1,
infinite: false,
@@ -46,10 +44,11 @@ export const carousel2 = (onChange) => {
autoplay: false,
autoplayDirection: 'next',
disabled: false, // Disable page change while animation is in progress
duration: 1000,
_duration: 1000,
durationMsInit: 1000,
durationMs: 1000,
offset: 0,
particleWidth: 0,
loaded: [],
},
{
setCurrentPageIndex: (data) => {
@@ -100,10 +99,12 @@ export const carousel2 = (onChange) => {
}
},
initDuration: (data) => {
data._duration = data.duration
data.durationMs = data.durationMsInit
},
applyAutoplay: (data, { applyAutoplayIfNeeded }) => {
applyAutoplayIfNeeded(data.autoplay)
applyAutoplay: (data, { _applyAutoplayIfNeeded }) => {
// prevent _applyAutoplayIfNeeded to be called with watcher
// to prevent its data added to deps
data.autoplay && _applyAutoplayIfNeeded(data.autoplay)
},
setParticlesToShow(data) {
data.particlesToShow = getValueInRange(
@@ -119,6 +120,23 @@ export const carousel2 = (onChange) => {
data.particlesCountWithoutClones
)
},
setInitialPageIndex(data) {
data.initialPageIndex = getValueInRange(
1,
data.initialPageIndexInit,
data.pagesCount
)
},
setLoaded(data) {
data.loaded = getAdjacentIndexes({
infinite: data.infinite,
pageIndex: data.currentPageIndex,
pagesCount: data.pagesCount,
particlesCount: data.particlesCountWithoutClones,
particlesToShow: data.particlesToShow,
particlesToScroll: data.particlesToScroll,
}).particleIndexes
},
},
{
_prev: (data) => {
@@ -156,7 +174,7 @@ export const carousel2 = (onChange) => {
toggleFocused: (data) => {
data.focused = !data.focused
},
applyAutoplayIfNeeded: async (
async _applyAutoplayIfNeeded(
{
infinite,
autoplayDirection,
@@ -165,7 +183,7 @@ export const carousel2 = (onChange) => {
autoplay,
},
{ showNextPage, showPrevPage }
) => {
) {
// prevent progress change if not infinite for first and last page
if (
!infinite &&
@@ -180,8 +198,8 @@ export const carousel2 = (onChange) => {
if (autoplay) {
const onFinish = () =>
switcher({
[NEXT]: showNextPage,
[PREV]: showPrevPage,
[NEXT]: async () => showNextPage(),
[PREV]: async () => showPrevPage(),
})(autoplayDirection)
await progressManager.start(onFinish)
@@ -221,7 +239,7 @@ export const carousel2 = (onChange) => {
changePage: async (
data,
{ offsetPage, applyAutoplayIfNeeded, _jumpIfNeeded },
{ offsetPage, _applyAutoplayIfNeeded, _jumpIfNeeded },
updateStoreFn,
options
) => {
@@ -234,7 +252,7 @@ export const carousel2 = (onChange) => {
data.disabled = false
const jumped = await _jumpIfNeeded()
!jumped && applyAutoplayIfNeeded() // no need to wait it finishes
!jumped && _applyAutoplayIfNeeded() // no need to wait it finishes
},
showNextPage: async ({ disabled }, { changePage, _next }, options) => {
if (disabled) return
@@ -266,21 +284,22 @@ export const carousel2 = (onChange) => {
options
)
},
offsetPage: (data, _, options) => {
offsetPage(data, _, options) {
const animated = get(options, 'animated', true)
return new Promise((resolve) => {
// _duration is an offset animation time
data._duration = animated ? data.duration : 0
// durationMs is an offset animation time
data.durationMs = animated ? data.durationMsInit : 0
data.offset = -data.currentParticleIndex * data.particleWidth
setTimeout(() => {
resolve()
}, data._duration)
}, data.durationMs)
})
},
},
onChange
)
return [{ data, progressManager }, methods]
// return [{ ...data, progressManager }, methods]
return [{ data, progressManager }, methods, service]
}
export default createCarousel