diff --git a/src/components/Carousel/Carousel.svelte b/src/components/Carousel/Carousel.svelte index 551bf49..766e913 100644 --- a/src/components/Carousel/Carousel.svelte +++ b/src/components/Carousel/Carousel.svelte @@ -18,10 +18,14 @@ applyClones, getPageSizes, applyPageSizes, + getCurrentPageIndexWithoutClones, + getPagesCountWithoutClones, + getOneSideClonesCount, } from '../../utils/page' import { get } from '../../utils/object' import { ProgressManager } from '../../utils/ProgressManager' import { wait } from '../../utils/interval' + import { getIsOdd } from '../../utils/math' const dispatch = createEventDispatcher() @@ -103,12 +107,12 @@ /** * Number of pages to show */ - export let pagesToShow = 2 // 2 // 1 // 3 + export let pagesToShow = 4 // 2 // 2 // 1 // 3 /** * Number of pages to scroll */ - export let pagesToScroll = 2 // 1 // 1 // 2 + export let pagesToScroll = 3 // 2 // 1 // 1 // 2 export async function goTo(pageIndex, options) { @@ -116,7 +120,7 @@ if (typeof pageIndex !== 'number') { throw new Error('pageIndex should be a number') } - await showPage(pageIndex + oneSideClonesCount, { animated }) + await showPage(pageIndex * pagesToScroll + oneSideClonesCount, { animated }) } export async function goToPrev(options) { @@ -130,31 +134,25 @@ } let store = createStore() + let oneSideClonesCount = getOneSideClonesCount({ pagesToScroll, pagesToShow }) + let currentPageIndex = 0 - $: originalCurrentPageIndex = getOriginalCurrentPageIndex(currentPageIndex, pagesCount, infinite) // index without cloenes + $: originalCurrentPageIndex = getCurrentPageIndexWithoutClones({ + currentPageIndex, + pagesCount, + oneSideClonesCount, + infinite, + pagesToScroll + }) $: dispatch('pageChange', originalCurrentPageIndex) - let oneSideClonesCount = Math.max(pagesToScroll, pagesToShow) // TODO: check - $: pagesItemsClonesCount = oneSideClonesCount * 2 let pagesCount = 0 - - $: originalPagesCount = Math.max( - Math.ceil( - ( - pagesCount - (infinite ? pagesItemsClonesCount : 0) - ) / pagesToScroll - ), - 1) // without clones - - function getOriginalCurrentPageIndex(currentPageIndex, pagesCount, infinite) { - if (infinite) { - console.log('currentPageIndex', currentPageIndex) - if (currentPageIndex === pagesCount - oneSideClonesCount) return 0 - if (currentPageIndex === 0) return (pagesCount - oneSideClonesCount) - return Math.floor((currentPageIndex-oneSideClonesCount)/pagesToScroll) - } - return currentPageIndex - } + $: originalPagesCount = getPagesCountWithoutClones({ + pagesCount, + infinite, + oneSideClonesCount, + pagesToScroll, + }) let pagesWindowWidth = 0 let pageWidth = 0 @@ -241,6 +239,7 @@ await tick() cleanupFns.push(store.subscribe(value => { currentPageIndex = value.currentPageIndex + console.log('currentPageIndex', currentPageIndex) })) cleanupFns.push(() => progressManager.reset()) if (pagesContainer && pageWindowElement) { @@ -264,7 +263,7 @@ }) async function handlePageChange(pageIndex) { - await showPage(pageIndex + oneSideClonesCount) + await showPage(pageIndex * pagesToScroll + oneSideClonesCount) } function offsetPage(options) { @@ -285,10 +284,10 @@ async function jumpIfNeeded() { let jumped = false if (infinite) { - if (currentPageIndex === oneSideClonesCount - 1) { - await showPage(pagesCount - oneSideClonesCount - 1, { animated: false }) + if (currentPageIndex === 0) { // oneSideClonesCount - 1) { + await showPage(pagesCount - 2 * oneSideClonesCount, { animated: false }) jumped = true - } else if (currentPageIndex === pagesCount - oneSideClonesCount) { + } else if (currentPageIndex === pagesCount - oneSideClonesCount ) { await showPage(oneSideClonesCount, { animated: false }) jumped = true } @@ -313,7 +312,10 @@ async function showPage(pageIndex, options) { await changePage( - () => store.moveToPage({ pageIndex, pagesCount }), + () => store.moveToPage({ + pageIndex, + pagesCount, + }), options ) } diff --git a/src/utils/math.js b/src/utils/math.js index 3ecae8f..23d195d 100644 --- a/src/utils/math.js +++ b/src/utils/math.js @@ -4,3 +4,64 @@ export const getDistance = (p1, p2) => { return Math.sqrt((xDist * xDist) + (yDist * yDist)); } + +// 3 => true +export function getIsOdd(num) { + return Boolean(num % 2) +} + + +// TODO: determine when partial offset is needed and apply partial offset +// TODO: determine how many clones should be from both sides + + +// TODO: refactor pagesToShow <= pagesToScroll +// TODO: think about case if pagesCount < pagesToShow and pagesCount < pagesToScroll +export function getPartialPageSize({ + pagesToScroll, + pagesToShow, + pagesCount +}) { + + if (pagesToShow <= pagesToScroll) { + const overlap = pagesToShow - pagesToScroll + + const d = (Math.max(pagesToShow-pagesToScroll), pagesToShow) + // console.log('overlap', overlap) + let _pages = d + // console.log('pages', _pages) + + while(true) { + // let fp = _pages - overlap + _pages = _pages - overlap + d + // console.log('pages', _pages) + const diff = pagesCount - _pages + if (diff < pagesToShow) { + // console.log('diff', diff) + // console.log('pagesToShow - diff', pagesToShow - Math.abs(diff) - overlap) + const res = diff + overlap + if (res < 0) { + return pagesToShow - overlap + res + } + console.log(res, diff) + return diff !== 0 ? Math.min(res, diff) : res + } + } + } else { + const overlap = pagesToShow - pagesToScroll + + // console.log('overlap', overlap) + let _pages = pagesToShow + console.log('pages', _pages) + + while(true) { + const diff = pagesCount - _pages + overlap + if (diff < pagesToShow) { + return diff + } + _pages += pagesToShow - overlap + console.log('pages', _pages) + } + } + +} diff --git a/src/utils/math.test.js b/src/utils/math.test.js index 1307b7c..c46d06f 100644 --- a/src/utils/math.test.js +++ b/src/utils/math.test.js @@ -1,5 +1,6 @@ import { getDistance, + getPartialPageSize } from './math.js' describe('getDistance', () => { @@ -17,3 +18,107 @@ describe('getDistance', () => { expect(getDistance(p1, p2)).toBe(5) }) }) + +describe('getPartialPageSize', () => { + + it('getPartialPageSize', () => { + // ==== pagesToShow <= pagesToScroll + // const r1 = getPartialPageSize({ + // pagesCount: 15, + // pagesToShow: 4, + // pagesToScroll: 5, + // }) + // expect(r1).toBe(0) + + // const r2 = getPartialPageSize({ + // pagesCount: 16, + // pagesToShow: 4, + // pagesToScroll: 5, + // }) + // expect(r2).toBe(1) + + // const r3 = getPartialPageSize({ + // pagesCount: 17, + // pagesToShow: 4, + // pagesToScroll: 5, + // }) + // expect(r3).toBe(2) + + // const r4 = getPartialPageSize({ + // pagesCount: 18, + // pagesToShow: 4, + // pagesToScroll: 5, + // }) + // expect(r4).toBe(3) + + // const r5 = getPartialPageSize({ + // pagesCount: 8, + // pagesToShow: 2, + // pagesToScroll: 2, + // }) + // expect(r5).toBe(0) + + // ====== pagesToScroll < pagesToShow + + // const r6 = getPartialPageSize({ + // pagesCount: 8, + // pagesToShow: 4, + // pagesToScroll: 2, + // }) + // expect(r6).toBe(2) + + // const r7 = getPartialPageSize({ + // pagesCount: 7, + // pagesToShow: 4, + // pagesToScroll: 3, + // }) + // expect(r7).toBe(1) + + // const r8 = getPartialPageSize({ + // pagesCount: 8, + // pagesToShow: 4, + // pagesToScroll: 3, + // }) + // expect(r8).toBe(2) + + // const r9 = getPartialPageSize({ + // pagesCount: 8, + // pagesToShow: 2, + // pagesToScroll: 2, + // }) + // expect(r9).toBe(0) + + // const r10 = getPartialPageSize({ + // pagesCount: 9, + // pagesToShow: 4, + // pagesToScroll: 3, + // }) + // expect(r10).toBe(3) + + // const r11 = getPartialPageSize({ + // pagesCount: 8, + // pagesToShow: 3, + // pagesToScroll: 2, + // }) + // expect(r11).toBe(2) + + + const r12 = getPartialPageSize({ + pagesCount: 6, + pagesToShow: 3, + pagesToScroll: 1, + }) + expect(r12).toBe(2) + + + const r13 = getPartialPageSize({ + pagesCount: 7, + pagesToShow: 3, + pagesToScroll: 1, + }) + expect(r13).toBe(2) + + + + }) +}) diff --git a/src/utils/page.js b/src/utils/page.js index 047b663..2584824 100644 --- a/src/utils/page.js +++ b/src/utils/page.js @@ -111,3 +111,40 @@ export function applyPageSizes({ pagesContainerChildren[pageIndex].style.maxWidth = `${pageWidth}px` } } + +export function getCurrentPageIndexWithoutClones({ + currentPageIndex, + pagesCount, + oneSideClonesCount, + infinite, + pagesToScroll, +}) { + if (infinite) { + if (currentPageIndex === pagesCount - oneSideClonesCount) return 0 + if (currentPageIndex === 0) return pagesCount - oneSideClonesCount + return Math.floor((currentPageIndex - oneSideClonesCount) / pagesToScroll) + } + return currentPageIndex +} + +export function getPagesCountWithoutClones({ + pagesCount, + infinite, + oneSideClonesCount, + pagesToScroll, +}) { + const bothSidesClonesCount = oneSideClonesCount * 2 + return Math.max( + Math.ceil( + (pagesCount - (infinite ? bothSidesClonesCount : 0)) / pagesToScroll + ), + 1) +} + +// TODO: check +export function getOneSideClonesCount({ + pagesToScroll, + pagesToShow, +}) { + return Math.max(pagesToScroll, pagesToShow) // max - show 4, scroll 3, pages 7 +}