diff --git a/src/components/Carousel/Carousel.svelte b/src/components/Carousel/Carousel.svelte index 52f1496..551bf49 100644 --- a/src/components/Carousel/Carousel.svelte +++ b/src/components/Carousel/Carousel.svelte @@ -12,13 +12,17 @@ addResizeEventListener, removeResizeEventListener } from '../../utils/event' - import { getAdjacentIndexes } from '../../utils/page' + import { + getAdjacentIndexes, + getClones, + applyClones, + getPageSizes, + applyPageSizes, + } from '../../utils/page' import { get } from '../../utils/object' import { ProgressManager } from '../../utils/ProgressManager' import { wait } from '../../utils/interval' - - const dispatch = createEventDispatcher() const autoplayDirectionFnDescription = { @@ -99,12 +103,12 @@ /** * Number of pages to show */ - export let pagesToShow = 3 + export let pagesToShow = 2 // 2 // 1 // 3 /** * Number of pages to scroll */ - export let pagesToScroll = 1 + export let pagesToScroll = 2 // 1 // 1 // 2 export async function goTo(pageIndex, options) { @@ -112,7 +116,7 @@ if (typeof pageIndex !== 'number') { throw new Error('pageIndex should be a number') } - await showPage(pageIndex + clonesCount, { animated }) + await showPage(pageIndex + oneSideClonesCount, { animated }) } export async function goToPrev(options) { @@ -130,8 +134,8 @@ $: originalCurrentPageIndex = getOriginalCurrentPageIndex(currentPageIndex, pagesCount, infinite) // index without cloenes $: dispatch('pageChange', originalCurrentPageIndex) - let clonesCount = Math.max(pagesToScroll, pagesToShow) // TODO: check - $: pagesItemsClonesCount = clonesCount * 2 + let oneSideClonesCount = Math.max(pagesToScroll, pagesToShow) // TODO: check + $: pagesItemsClonesCount = oneSideClonesCount * 2 let pagesCount = 0 $: originalPagesCount = Math.max( @@ -143,21 +147,20 @@ 1) // without clones function getOriginalCurrentPageIndex(currentPageIndex, pagesCount, infinite) { - console.log('getOriginalCurrentPageIndex', currentPageIndex, pagesCount, infinite) - console.log('pagesItemsClonesCount', pagesItemsClonesCount) if (infinite) { - if (currentPageIndex === pagesCount - clonesCount) return 0 - if (currentPageIndex === 0) return (pagesCount - clonesCount) - return currentPageIndex - clonesCount + console.log('currentPageIndex', currentPageIndex) + if (currentPageIndex === pagesCount - oneSideClonesCount) return 0 + if (currentPageIndex === 0) return (pagesCount - oneSideClonesCount) + return Math.floor((currentPageIndex-oneSideClonesCount)/pagesToScroll) } return currentPageIndex } let pagesWindowWidth = 0 - let pagesItemWidth = 0 + let pageWidth = 0 let offset = 0 let pageWindowElement - let pagesElement + let pagesContainer let focused = false let progressValue @@ -181,41 +184,37 @@ // used for lazy loading images, preloaded only current, adjacent and cloanable images $: loaded = getAdjacentIndexes(originalCurrentPageIndex, originalPagesCount, infinite) - function applyPageSizes() { - const children = pagesElement.children - pagesWindowWidth = pageWindowElement.clientWidth + function initPageSizes() { + const sizes = getPageSizes({ + pageWindowElement, + pagesContainerChildren: pagesContainer.children, + pagesToShow, + }) + applyPageSizes({ + pagesContainerChildren: pagesContainer.children, + pageWidth: sizes.pageWidth, + }) - pagesItemWidth = pagesWindowWidth / pagesToShow - - pagesCount = children.length + pagesWindowWidth = sizes.pagesWindowWidth + pageWidth = sizes.pageWidth + pagesCount = sizes.pagesCount - for (let pageIndex=0; pageIndexlen - 1 - clonesCount; i--) { - toPrepend.push(pagesElement.children[i].cloneNode(true)) - } - - for (let i=0; i { currentPageIndex = value.currentPageIndex - console.log('currentPageIndex', currentPageIndex) })) cleanupFns.push(() => progressManager.reset()) - if (pagesElement && pageWindowElement) { + if (pagesContainer && pageWindowElement) { // load first and last child to clone them // TODO: update - loaded = [0, pagesElement.children.length - 1] + loaded = [0, pagesContainer.children.length - 1] await tick() infinite && addClones() - store.init(initialPageIndex + clonesCount) - applyPageSizes() + store.init(initialPageIndex + oneSideClonesCount) + initPageSizes() } - addResizeEventListener(applyPageSizes) + addResizeEventListener(initPageSizes) })() }) onDestroy(() => { - removeResizeEventListener(applyPageSizes) + removeResizeEventListener(initPageSizes) cleanupFns.filter(fn => fn && typeof fn === 'function').forEach(fn => fn()) }) async function handlePageChange(pageIndex) { - await showPage(pageIndex + clonesCount) + await showPage(pageIndex + oneSideClonesCount) } function offsetPage(options) { const animated = get(options, 'animated', true) + // TODO: remove const pagesToScroll = get(options, 'pagesToScroll', 0) return new Promise((resolve) => { // _duration is an offset animation time _duration = animated ? duration : 0 - console.log(currentPageIndex, pagesItemWidth, pagesToScroll) - offset = -currentPageIndex * (pagesItemWidth * pagesToScroll) - console.log('offset', offset) + offset = -currentPageIndex * pageWidth setTimeout(() => { resolve() @@ -288,11 +285,11 @@ async function jumpIfNeeded() { let jumped = false if (infinite) { - if (currentPageIndex === 0) { - await showPage(pagesCount - clonesCount, { animated: false }) + if (currentPageIndex === oneSideClonesCount - 1) { + await showPage(pagesCount - oneSideClonesCount - 1, { animated: false }) jumped = true - } else if (currentPageIndex === pagesCount - clonesCount) { - await showPage(clonesCount, { animated: false }) + } else if (currentPageIndex === pagesCount - oneSideClonesCount) { + await showPage(oneSideClonesCount, { animated: false }) jumped = true } } @@ -322,13 +319,13 @@ } async function showPrevPage(options) { await changePage( - () => store.prev({ infinite, pagesCount }), + () => store.prev({ infinite, pagesCount, pagesToScroll }), options ) } async function showNextPage(options) { await changePage( - () => store.next({ infinite, pagesCount }), + () => store.next({ infinite, pagesCount, pagesToScroll }), options ) } @@ -399,7 +396,7 @@ transition-duration: {_duration}ms; transition-timing-function: {timingFunction}; " - bind:this={pagesElement} + bind:this={pagesContainer} > @@ -428,6 +425,7 @@ pagesCount={originalPagesCount} showPage={handlePageChange} > + {currentPageIndex}/{pagesCount}; {originalCurrentPageIndex}/{originalPagesCount} ({ - ...store, - currentPageIndex: index, - })) - } - function moveToPage({ pageIndex, pagesCount }) { update(store => { return { @@ -35,9 +28,9 @@ function createStore() { }) } - function next({ infinite, pagesCount }) { + function next({ infinite, pagesCount, pagesToScroll }) { update(store => { - const newCurrentPageIndex = getNextPageIndexFn(infinite)(store.currentPageIndex, pagesCount) + const newCurrentPageIndex = getNextPageIndexFn(infinite)(store.currentPageIndex, pagesCount, pagesToScroll) return { ...store, currentPageIndex: newCurrentPageIndex, @@ -45,9 +38,9 @@ function createStore() { }) } - function prev({ infinite, pagesCount }) { + function prev({ infinite, pagesCount, pagesToScroll }) { update(store => { - const newCurrentPageIndex = getPrevPageIndexFn(infinite)(store.currentPageIndex, pagesCount) + const newCurrentPageIndex = getPrevPageIndexFn(infinite)(store.currentPageIndex, pagesCount, pagesToScroll) return { ...store, currentPageIndex: newCurrentPageIndex, @@ -59,7 +52,6 @@ function createStore() { subscribe, next, prev, - setCurrentPageIndex, init, moveToPage, }; diff --git a/src/utils/page.js b/src/utils/page.js index 389faa4..047b663 100644 --- a/src/utils/page.js +++ b/src/utils/page.js @@ -1,11 +1,11 @@ -export function getNextPageIndexLimited(currentPageIndex, pagesCount) { +export function getNextPageIndexLimited(currentPageIndex, pagesCount, pagesToScroll) { if (pagesCount < 1) throw new Error('pagesCount must be at least 1') - return Math.min(Math.max(currentPageIndex + 1, 0), pagesCount - 1) + return Math.min(Math.max(currentPageIndex + pagesToScroll, 0), pagesCount - 1) } -export function getNextPageIndexInfinte(currentPageIndex, pagesCount) { +export function getNextPageIndexInfinte(currentPageIndex, pagesCount, pagesToScroll) { if (pagesCount < 1) throw new Error('pagesCount must be at least 1') - const newCurrentPageIndex = Math.max(currentPageIndex, 0) + 1 + const newCurrentPageIndex = Math.max(currentPageIndex, 0) + pagesToScroll return newCurrentPageIndex > pagesCount - 1 ? 0 : Math.max(newCurrentPageIndex, 0) } @@ -13,14 +13,14 @@ export function getNextPageIndexFn(infinite) { return infinite ? getNextPageIndexInfinte : getNextPageIndexLimited } -export function getPrevPageIndexLimited(currentPageIndex, pagesCount) { +export function getPrevPageIndexLimited(currentPageIndex, pagesCount, pagesToScroll) { if (pagesCount < 1) throw new Error('pagesCount must be at least 1') - return Math.max(Math.min(currentPageIndex - 1, pagesCount - 1), 0) + return Math.max(Math.min(currentPageIndex - pagesToScroll, pagesCount - 1), 0) } -export function getPrevPageIndexInfinte(currentPageIndex, pagesCount) { +export function getPrevPageIndexInfinte(currentPageIndex, pagesCount, pagesToScroll) { if (pagesCount < 1) throw new Error('pagesCount must be at least 1') - const newCurrentPageIndex = Math.min(currentPageIndex, pagesCount - 1) - 1 + const newCurrentPageIndex = Math.min(currentPageIndex, pagesCount - 1) - pagesToScroll return newCurrentPageIndex >= 0 ? Math.min(newCurrentPageIndex, pagesCount - 1) : pagesCount - 1 } @@ -50,3 +50,64 @@ export function getAdjacentIndexes(pageIndex, pagesCount, infinite) { : rangeEnd return [...new Set([rangeStart, rangeEnd, _pageIndex])].sort((a, b) => a - b) } + +export function getClones({ + oneSideClonesCount, + pagesContainerChildren +}) { + // TODO: add fns to remove clones + const clonesToAppend = [] + for (let i=0; ilen-1-oneSideClonesCount; i--) { + clonesToPrepend.push(pagesContainerChildren[i].cloneNode(true)) + } + + return { + clonesToAppend, + clonesToPrepend, + } +} + +export function applyClones({ + pagesContainer, + clonesToAppend, + clonesToPrepend, +}) { + for (let i=0; i