use-snap-slider 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/snap-slider.cjs +31 -26
- package/dist/snap-slider.cjs.map +1 -1
- package/dist/snap-slider.es.js +31 -26
- package/dist/snap-slider.es.js.map +1 -1
- package/package.json +1 -1
package/dist/snap-slider.cjs
CHANGED
|
@@ -178,6 +178,31 @@ function createSnapSlider({
|
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
|
+
function onScrollEnd() {
|
|
182
|
+
if (element) {
|
|
183
|
+
const scrollLeft = element.scrollLeft;
|
|
184
|
+
const positionItem = itemPositions.reduce((prev, curr) => {
|
|
185
|
+
return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft) ? curr : prev;
|
|
186
|
+
});
|
|
187
|
+
const indexDelta2 = itemPositions.findIndex((x) => x === positionItem);
|
|
188
|
+
const pxLeftScrolling = Math.abs(scrollLeft - positionItem);
|
|
189
|
+
prevIndexDelta = indexDelta2;
|
|
190
|
+
debug && console.log("onScrollEnd", {
|
|
191
|
+
pxLeftScrolling,
|
|
192
|
+
indexDelta: indexDelta2,
|
|
193
|
+
scrollLeft,
|
|
194
|
+
positionItem,
|
|
195
|
+
itemPositions
|
|
196
|
+
});
|
|
197
|
+
update({
|
|
198
|
+
event: "scroll",
|
|
199
|
+
...fixIndex({
|
|
200
|
+
index: Math.floor(indexDelta2 / slidesPerPage),
|
|
201
|
+
indexDelta: indexDelta2
|
|
202
|
+
})
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
181
206
|
function onScroll() {
|
|
182
207
|
if (element) {
|
|
183
208
|
const scrollLeft = element.scrollLeft;
|
|
@@ -222,31 +247,7 @@ function createSnapSlider({
|
|
|
222
247
|
updateIndexDelta();
|
|
223
248
|
calculate();
|
|
224
249
|
if ("onscrollend" in window) {
|
|
225
|
-
element?.addEventListener("scrollend",
|
|
226
|
-
if (element) {
|
|
227
|
-
const scrollLeft = element.scrollLeft;
|
|
228
|
-
const positionItem = itemPositions.reduce((prev, curr) => {
|
|
229
|
-
return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft) ? curr : prev;
|
|
230
|
-
});
|
|
231
|
-
const indexDelta2 = itemPositions.findIndex((x) => x === positionItem);
|
|
232
|
-
const pxLeftScrolling = Math.abs(scrollLeft - positionItem);
|
|
233
|
-
prevIndexDelta = indexDelta2;
|
|
234
|
-
debug && console.log("onScrollEnd", {
|
|
235
|
-
pxLeftScrolling,
|
|
236
|
-
indexDelta: indexDelta2,
|
|
237
|
-
scrollLeft,
|
|
238
|
-
positionItem,
|
|
239
|
-
itemPositions
|
|
240
|
-
});
|
|
241
|
-
update({
|
|
242
|
-
event: "scroll",
|
|
243
|
-
...fixIndex({
|
|
244
|
-
index: Math.floor(indexDelta2 / slidesPerPage),
|
|
245
|
-
indexDelta: indexDelta2
|
|
246
|
-
})
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
+
element?.addEventListener("scrollend", onScrollEnd);
|
|
250
251
|
} else {
|
|
251
252
|
element?.addEventListener("scroll", onScrollFn);
|
|
252
253
|
}
|
|
@@ -274,7 +275,11 @@ function createSnapSlider({
|
|
|
274
275
|
}
|
|
275
276
|
};
|
|
276
277
|
const destroy = () => {
|
|
277
|
-
|
|
278
|
+
if ("onscrollend" in window) {
|
|
279
|
+
element?.removeEventListener("scrollend", onScrollEnd);
|
|
280
|
+
} else {
|
|
281
|
+
element?.removeEventListener("scroll", onScrollFn);
|
|
282
|
+
}
|
|
278
283
|
window.removeEventListener("resize", onResizeFn);
|
|
279
284
|
};
|
|
280
285
|
const goNext = () => {
|
package/dist/snap-slider.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snap-slider.cjs","sources":["../lib/throttle.ts","../lib/snap-slider.ts"],"sourcesContent":["export const throttle = (fn: Function, wait: number) => {\n let inThrottle: boolean\n let lastFn: ReturnType<typeof setTimeout>\n let lastTime: number\n return function (this: any) {\n const context = this\n const args = arguments\n if (!inThrottle) {\n fn.apply(context, args)\n lastTime = Date.now()\n inThrottle = true\n } else {\n clearTimeout(lastFn)\n lastFn = setTimeout(() => {\n if (Date.now() - lastTime >= wait) {\n fn.apply(context, args)\n lastTime = Date.now()\n }\n }, Math.max(wait - (Date.now() - lastTime), 0))\n }\n }\n}\n","import { throttle } from './throttle'\n\nexport type TSnapListnerEvent = 'scroll' | 'click' | 'inital' | 'goto'\n\nexport interface TSnapListnerStateIndex {\n index: number\n indexDelta: number\n}\n\nexport interface TSnapSliderState extends TSnapListnerStateIndex {\n count: number\n countDelta: number\n event: TSnapListnerEvent\n}\n\ninterface TSnapSliderStateUpdate {\n index?: number\n indexDelta?: number\n count?: number\n countDelta?: number\n event: TSnapListnerEvent\n}\n\nexport interface TSnapSliderStateFull extends TSnapSliderState {\n prevEnabled: boolean\n nextEnabled: boolean\n}\n\nexport type TSnapListner = (params: TSnapSliderStateFull) => void\n\nexport type TSnapSliderOptions = {\n circular?: boolean\n debug?: boolean\n scrollTimeThrottle?: number\n resizeTimeThrottle?: number\n scrollListenerThreshold?: number\n}\n\nexport type TSnapSliderParams = Omit<TSnapSliderStateUpdate, 'event'> &\n TSnapSliderOptions & {\n element: HTMLElement | null\n itemSelector?: string\n initalSubscriptionPublish?: boolean\n }\n\nexport type TSnapSliderJumpToFn = (\n index?: number,\n indexDelta?: number,\n event?: TSnapListnerEvent\n) => void\n\nexport interface TSnapSlider {\n destroy: () => void\n getState: () => TSnapSliderStateFull\n jumpTo: TSnapSliderJumpToFn\n goNext: () => void\n goPrev: () => void\n subscribe: (fn: TSnapListner) => () => void\n setElement: (el: HTMLElement) => void\n calculate: () => void\n}\n\nexport function createSnapSlider({\n element: _element,\n count = 1,\n countDelta,\n index = 0,\n circular,\n indexDelta,\n initalSubscriptionPublish = true,\n itemSelector = ':scope > *',\n debug,\n scrollTimeThrottle = 500,\n resizeTimeThrottle = 500,\n scrollListenerThreshold = 2,\n}: TSnapSliderParams): TSnapSlider {\n let initalIndex: number | undefined = index\n let state: TSnapSliderState = {\n index,\n indexDelta: indexDelta || index,\n event: 'inital',\n count,\n countDelta: countDelta || count,\n }\n let prevIndexDelta: number = index\n let slidesPerPage: number = 1\n let itemPositions: number[] = []\n let muteScrollListner: boolean = false\n let left: number = 0\n let element: HTMLElement | null\n function updateIndexDelta() {\n if (element) {\n const prev = element.scrollLeft\n const { indexDelta, event } = state\n left = indexDelta * (element.offsetWidth / slidesPerPage)\n if (prevIndexDelta !== indexDelta) {\n const distance = Math.abs(prev - left)\n const limitInstantScroll = element.offsetWidth * 2\n prevIndexDelta = indexDelta\n muteScrollListner = true\n const behavior: ScrollBehavior =\n distance > limitInstantScroll || event === 'click'\n ? 'instant'\n : 'smooth'\n element.scroll({\n left,\n top: 0,\n behavior,\n })\n } else {\n if (initalIndex) {\n muteScrollListner = true\n element.scroll({\n left,\n top: 0,\n behavior: 'instant',\n })\n initalIndex = undefined\n }\n }\n }\n }\n\n let publishDirty = false\n let listeners: TSnapListner[] = []\n const subscribe = (callback: TSnapListner) => {\n listeners.push(callback)\n if (element && (publishDirty || initalSubscriptionPublish)) {\n callback(getState())\n }\n return () => {\n listeners = listeners.filter((x) => x !== callback)\n if (listeners.length < 1) {\n destroy()\n }\n }\n }\n function notify() {\n listeners.forEach((callback) => {\n callback(getState())\n })\n }\n const getState = (): TSnapSliderStateFull => {\n const { indexDelta, countDelta } = state\n return {\n ...state,\n prevEnabled: circular || indexDelta > 0,\n nextEnabled: circular || countDelta - slidesPerPage > indexDelta,\n }\n }\n function update(params: TSnapSliderStateUpdate) {\n let dirty = false\n let indexDeltaDirty = false\n type TSnapSliderStateUpdateKey = keyof typeof params\n const keys: TSnapSliderStateUpdateKey[] = Object.keys(\n params\n ) as Array<TSnapSliderStateUpdateKey>\n state['event'] = params['event']\n keys.forEach((key) => {\n if (key !== 'event' && state[key] !== params[key]) {\n state[key] = Number(params[key])\n dirty = true\n if (key === 'indexDelta') {\n indexDeltaDirty = true\n }\n }\n })\n if (dirty) {\n publishDirty = listeners.length === 0\n notify()\n if (indexDeltaDirty) {\n updateIndexDelta()\n }\n }\n }\n function fixIndex(nextIndex: TSnapListnerStateIndex): TSnapListnerStateIndex {\n const { index, indexDelta } = nextIndex\n const { countDelta, count } = state\n const last = countDelta - slidesPerPage\n return {\n index: indexDelta < last ? index : count - 1,\n indexDelta,\n }\n }\n function calculate() {\n if (element) {\n let contentWidth = 0\n let itemWidth = 0\n itemPositions = []\n const slides = element.querySelectorAll<HTMLDivElement>(itemSelector)\n slides.forEach((slide) => {\n itemPositions.push(contentWidth)\n contentWidth += slide.clientWidth\n itemWidth = slide.clientWidth\n })\n slidesPerPage = Math.round(element.offsetWidth / itemWidth)\n const countDelta = itemPositions.length\n const count = Math.ceil(countDelta / slidesPerPage)\n const { index } = state\n const resetIndexMayby =\n index + 1 > count\n ? {\n index: 0,\n indexDelta: 0,\n }\n : {}\n\n if (!isNaN(count)) {\n // if element not mounted / hidden not update\n update({\n event: 'inital',\n count,\n countDelta,\n ...resetIndexMayby,\n })\n debug &&\n console.log('update count', {\n count,\n countDelta,\n itemPositions,\n slidesPerPage,\n clientWidth: element.clientWidth,\n offsetWidth: element.offsetWidth,\n itemSelector,\n slides,\n })\n }\n }\n }\n\n function onScroll() {\n if (element) {\n const scrollLeft = element.scrollLeft\n if (muteScrollListner) {\n const leftToScroll = Math.abs(left - scrollLeft)\n if (leftToScroll < 2) {\n muteScrollListner = false\n }\n } else {\n const positionItem = itemPositions.reduce((prev, curr) => {\n return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft)\n ? curr\n : prev\n })\n const indexDelta = itemPositions.findIndex((x) => x === positionItem)\n const pxLeftScrolling = Math.abs(scrollLeft - positionItem)\n prevIndexDelta = indexDelta\n debug &&\n console.log('onScroll', {\n pxLeftScrolling,\n indexDelta,\n scrollLeft,\n positionItem,\n itemPositions,\n })\n if (pxLeftScrolling < scrollListenerThreshold) {\n update({\n event: 'scroll',\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n }\n }\n }\n const onScrollFn = throttle(onScroll, scrollTimeThrottle)\n const onResizeFn = throttle(calculate, resizeTimeThrottle)\n function setElement(_el: HTMLElement) {\n if (element) {\n destroy()\n }\n element = _el\n updateIndexDelta()\n calculate()\n\n if ('onscrollend' in window) {\n element?.addEventListener('scrollend', (event) => {\n if (element) {\n const scrollLeft = element.scrollLeft\n const positionItem = itemPositions.reduce((prev, curr) => {\n return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft)\n ? curr\n : prev\n })\n const indexDelta = itemPositions.findIndex((x) => x === positionItem)\n const pxLeftScrolling = Math.abs(scrollLeft - positionItem)\n prevIndexDelta = indexDelta\n debug &&\n console.log('onScrollEnd', {\n pxLeftScrolling,\n indexDelta,\n scrollLeft,\n positionItem,\n itemPositions,\n })\n update({\n event: 'scroll',\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n })\n } else {\n element?.addEventListener('scroll', onScrollFn)\n }\n window.addEventListener('resize', onResizeFn)\n }\n _element && setElement(_element)\n const jumpTo: TSnapSliderJumpToFn = function (\n index,\n indexDelta,\n event = 'goto'\n ) {\n if (indexDelta !== undefined) {\n update({\n event,\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n if (index !== undefined) {\n update({\n event,\n ...fixIndex({\n index,\n indexDelta: index * slidesPerPage,\n }),\n })\n }\n }\n const destroy = () => {\n element?.removeEventListener('scroll', onScrollFn)\n window.removeEventListener('resize', onResizeFn)\n }\n const goNext = () => {\n const { countDelta, indexDelta } = state\n const last = countDelta - slidesPerPage\n const next =\n indexDelta + slidesPerPage <= last\n ? indexDelta + slidesPerPage\n : circular && indexDelta === last\n ? 0\n : last\n jumpTo(undefined, next)\n }\n const goPrev = () => {\n const { indexDelta, countDelta } = state\n const last = countDelta - slidesPerPage\n const next =\n indexDelta - slidesPerPage >= 0\n ? indexDelta - slidesPerPage\n : circular && indexDelta === 0\n ? last\n : 0\n jumpTo(undefined, next)\n }\n return {\n destroy,\n getState,\n subscribe,\n jumpTo,\n setElement,\n calculate,\n goNext,\n goPrev,\n }\n}\n"],"names":["indexDelta","countDelta","index","count"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"snap-slider.cjs","sources":["../lib/throttle.ts","../lib/snap-slider.ts"],"sourcesContent":["export const throttle = (fn: Function, wait: number) => {\n let inThrottle: boolean\n let lastFn: ReturnType<typeof setTimeout>\n let lastTime: number\n return function (this: any) {\n const context = this\n const args = arguments\n if (!inThrottle) {\n fn.apply(context, args)\n lastTime = Date.now()\n inThrottle = true\n } else {\n clearTimeout(lastFn)\n lastFn = setTimeout(() => {\n if (Date.now() - lastTime >= wait) {\n fn.apply(context, args)\n lastTime = Date.now()\n }\n }, Math.max(wait - (Date.now() - lastTime), 0))\n }\n }\n}\n","import { throttle } from './throttle'\n\nexport type TSnapListnerEvent = 'scroll' | 'click' | 'inital' | 'goto'\n\nexport interface TSnapListnerStateIndex {\n index: number\n indexDelta: number\n}\n\nexport interface TSnapSliderState extends TSnapListnerStateIndex {\n count: number\n countDelta: number\n event: TSnapListnerEvent\n}\n\ninterface TSnapSliderStateUpdate {\n index?: number\n indexDelta?: number\n count?: number\n countDelta?: number\n event: TSnapListnerEvent\n}\n\nexport interface TSnapSliderStateFull extends TSnapSliderState {\n prevEnabled: boolean\n nextEnabled: boolean\n}\n\nexport type TSnapListner = (params: TSnapSliderStateFull) => void\n\nexport type TSnapSliderOptions = {\n circular?: boolean\n debug?: boolean\n scrollTimeThrottle?: number\n resizeTimeThrottle?: number\n scrollListenerThreshold?: number\n}\n\nexport type TSnapSliderParams = Omit<TSnapSliderStateUpdate, 'event'> &\n TSnapSliderOptions & {\n element: HTMLElement | null\n itemSelector?: string\n initalSubscriptionPublish?: boolean\n }\n\nexport type TSnapSliderJumpToFn = (\n index?: number,\n indexDelta?: number,\n event?: TSnapListnerEvent\n) => void\n\nexport interface TSnapSlider {\n destroy: () => void\n getState: () => TSnapSliderStateFull\n jumpTo: TSnapSliderJumpToFn\n goNext: () => void\n goPrev: () => void\n subscribe: (fn: TSnapListner) => () => void\n setElement: (el: HTMLElement) => void\n calculate: () => void\n}\n\nexport function createSnapSlider({\n element: _element,\n count = 1,\n countDelta,\n index = 0,\n circular,\n indexDelta,\n initalSubscriptionPublish = true,\n itemSelector = ':scope > *',\n debug,\n scrollTimeThrottle = 500,\n resizeTimeThrottle = 500,\n scrollListenerThreshold = 2,\n}: TSnapSliderParams): TSnapSlider {\n let initalIndex: number | undefined = index\n let state: TSnapSliderState = {\n index,\n indexDelta: indexDelta || index,\n event: 'inital',\n count,\n countDelta: countDelta || count,\n }\n let prevIndexDelta: number = index\n let slidesPerPage: number = 1\n let itemPositions: number[] = []\n let muteScrollListner: boolean = false\n let left: number = 0\n let element: HTMLElement | null\n function updateIndexDelta() {\n if (element) {\n const prev = element.scrollLeft\n const { indexDelta, event } = state\n left = indexDelta * (element.offsetWidth / slidesPerPage)\n if (prevIndexDelta !== indexDelta) {\n const distance = Math.abs(prev - left)\n const limitInstantScroll = element.offsetWidth * 2\n prevIndexDelta = indexDelta\n muteScrollListner = true\n const behavior: ScrollBehavior =\n distance > limitInstantScroll || event === 'click'\n ? 'instant'\n : 'smooth'\n element.scroll({\n left,\n top: 0,\n behavior,\n })\n } else {\n if (initalIndex) {\n muteScrollListner = true\n element.scroll({\n left,\n top: 0,\n behavior: 'instant',\n })\n initalIndex = undefined\n }\n }\n }\n }\n\n let publishDirty = false\n let listeners: TSnapListner[] = []\n const subscribe = (callback: TSnapListner) => {\n listeners.push(callback)\n if (element && (publishDirty || initalSubscriptionPublish)) {\n callback(getState())\n }\n return () => {\n listeners = listeners.filter((x) => x !== callback)\n if (listeners.length < 1) {\n destroy()\n }\n }\n }\n function notify() {\n listeners.forEach((callback) => {\n callback(getState())\n })\n }\n const getState = (): TSnapSliderStateFull => {\n const { indexDelta, countDelta } = state\n return {\n ...state,\n prevEnabled: circular || indexDelta > 0,\n nextEnabled: circular || countDelta - slidesPerPage > indexDelta,\n }\n }\n function update(params: TSnapSliderStateUpdate) {\n let dirty = false\n let indexDeltaDirty = false\n type TSnapSliderStateUpdateKey = keyof typeof params\n const keys: TSnapSliderStateUpdateKey[] = Object.keys(\n params\n ) as Array<TSnapSliderStateUpdateKey>\n state['event'] = params['event']\n keys.forEach((key) => {\n if (key !== 'event' && state[key] !== params[key]) {\n state[key] = Number(params[key])\n dirty = true\n if (key === 'indexDelta') {\n indexDeltaDirty = true\n }\n }\n })\n if (dirty) {\n publishDirty = listeners.length === 0\n notify()\n if (indexDeltaDirty) {\n updateIndexDelta()\n }\n }\n }\n function fixIndex(nextIndex: TSnapListnerStateIndex): TSnapListnerStateIndex {\n const { index, indexDelta } = nextIndex\n const { countDelta, count } = state\n const last = countDelta - slidesPerPage\n return {\n index: indexDelta < last ? index : count - 1,\n indexDelta,\n }\n }\n function calculate() {\n if (element) {\n let contentWidth = 0\n let itemWidth = 0\n itemPositions = []\n const slides = element.querySelectorAll<HTMLDivElement>(itemSelector)\n slides.forEach((slide) => {\n itemPositions.push(contentWidth)\n contentWidth += slide.clientWidth\n itemWidth = slide.clientWidth\n })\n slidesPerPage = Math.round(element.offsetWidth / itemWidth)\n const countDelta = itemPositions.length\n const count = Math.ceil(countDelta / slidesPerPage)\n const { index } = state\n const resetIndexMayby =\n index + 1 > count\n ? {\n index: 0,\n indexDelta: 0,\n }\n : {}\n\n if (!isNaN(count)) {\n // if element not mounted / hidden not update\n update({\n event: 'inital',\n count,\n countDelta,\n ...resetIndexMayby,\n })\n debug &&\n console.log('update count', {\n count,\n countDelta,\n itemPositions,\n slidesPerPage,\n clientWidth: element.clientWidth,\n offsetWidth: element.offsetWidth,\n itemSelector,\n slides,\n })\n }\n }\n }\n function onScrollEnd() {\n if (element) {\n const scrollLeft = element.scrollLeft\n const positionItem = itemPositions.reduce((prev, curr) => {\n return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft)\n ? curr\n : prev\n })\n const indexDelta = itemPositions.findIndex((x) => x === positionItem)\n const pxLeftScrolling = Math.abs(scrollLeft - positionItem)\n prevIndexDelta = indexDelta\n debug &&\n console.log('onScrollEnd', {\n pxLeftScrolling,\n indexDelta,\n scrollLeft,\n positionItem,\n itemPositions,\n })\n update({\n event: 'scroll',\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n }\n function onScroll() {\n if (element) {\n const scrollLeft = element.scrollLeft\n if (muteScrollListner) {\n const leftToScroll = Math.abs(left - scrollLeft)\n if (leftToScroll < 2) {\n muteScrollListner = false\n }\n } else {\n const positionItem = itemPositions.reduce((prev, curr) => {\n return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft)\n ? curr\n : prev\n })\n const indexDelta = itemPositions.findIndex((x) => x === positionItem)\n const pxLeftScrolling = Math.abs(scrollLeft - positionItem)\n prevIndexDelta = indexDelta\n debug &&\n console.log('onScroll', {\n pxLeftScrolling,\n indexDelta,\n scrollLeft,\n positionItem,\n itemPositions,\n })\n if (pxLeftScrolling < scrollListenerThreshold) {\n update({\n event: 'scroll',\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n }\n }\n }\n const onScrollFn = throttle(onScroll, scrollTimeThrottle)\n const onResizeFn = throttle(calculate, resizeTimeThrottle)\n function setElement(_el: HTMLElement) {\n if (element) {\n destroy()\n }\n element = _el\n updateIndexDelta()\n calculate()\n if ('onscrollend' in window) {\n element?.addEventListener('scrollend', onScrollEnd)\n } else {\n element?.addEventListener('scroll', onScrollFn)\n }\n window.addEventListener('resize', onResizeFn)\n }\n _element && setElement(_element)\n const jumpTo: TSnapSliderJumpToFn = function (\n index,\n indexDelta,\n event = 'goto'\n ) {\n if (indexDelta !== undefined) {\n update({\n event,\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n if (index !== undefined) {\n update({\n event,\n ...fixIndex({\n index,\n indexDelta: index * slidesPerPage,\n }),\n })\n }\n }\n const destroy = () => {\n if ('onscrollend' in window) {\n element?.removeEventListener('scrollend', onScrollEnd)\n } else {\n element?.removeEventListener('scroll', onScrollFn)\n }\n window.removeEventListener('resize', onResizeFn)\n }\n const goNext = () => {\n const { countDelta, indexDelta } = state\n const last = countDelta - slidesPerPage\n const next =\n indexDelta + slidesPerPage <= last\n ? indexDelta + slidesPerPage\n : circular && indexDelta === last\n ? 0\n : last\n jumpTo(undefined, next)\n }\n const goPrev = () => {\n const { indexDelta, countDelta } = state\n const last = countDelta - slidesPerPage\n const next =\n indexDelta - slidesPerPage >= 0\n ? indexDelta - slidesPerPage\n : circular && indexDelta === 0\n ? last\n : 0\n jumpTo(undefined, next)\n }\n return {\n destroy,\n getState,\n subscribe,\n jumpTo,\n setElement,\n calculate,\n goNext,\n goPrev,\n }\n}\n"],"names":["indexDelta","countDelta","index","count"],"mappings":"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"}
|
package/dist/snap-slider.es.js
CHANGED
|
@@ -176,6 +176,31 @@ function createSnapSlider({
|
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
|
+
function onScrollEnd() {
|
|
180
|
+
if (element) {
|
|
181
|
+
const scrollLeft = element.scrollLeft;
|
|
182
|
+
const positionItem = itemPositions.reduce((prev, curr) => {
|
|
183
|
+
return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft) ? curr : prev;
|
|
184
|
+
});
|
|
185
|
+
const indexDelta2 = itemPositions.findIndex((x) => x === positionItem);
|
|
186
|
+
const pxLeftScrolling = Math.abs(scrollLeft - positionItem);
|
|
187
|
+
prevIndexDelta = indexDelta2;
|
|
188
|
+
debug && console.log("onScrollEnd", {
|
|
189
|
+
pxLeftScrolling,
|
|
190
|
+
indexDelta: indexDelta2,
|
|
191
|
+
scrollLeft,
|
|
192
|
+
positionItem,
|
|
193
|
+
itemPositions
|
|
194
|
+
});
|
|
195
|
+
update({
|
|
196
|
+
event: "scroll",
|
|
197
|
+
...fixIndex({
|
|
198
|
+
index: Math.floor(indexDelta2 / slidesPerPage),
|
|
199
|
+
indexDelta: indexDelta2
|
|
200
|
+
})
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
}
|
|
179
204
|
function onScroll() {
|
|
180
205
|
if (element) {
|
|
181
206
|
const scrollLeft = element.scrollLeft;
|
|
@@ -220,31 +245,7 @@ function createSnapSlider({
|
|
|
220
245
|
updateIndexDelta();
|
|
221
246
|
calculate();
|
|
222
247
|
if ("onscrollend" in window) {
|
|
223
|
-
element?.addEventListener("scrollend",
|
|
224
|
-
if (element) {
|
|
225
|
-
const scrollLeft = element.scrollLeft;
|
|
226
|
-
const positionItem = itemPositions.reduce((prev, curr) => {
|
|
227
|
-
return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft) ? curr : prev;
|
|
228
|
-
});
|
|
229
|
-
const indexDelta2 = itemPositions.findIndex((x) => x === positionItem);
|
|
230
|
-
const pxLeftScrolling = Math.abs(scrollLeft - positionItem);
|
|
231
|
-
prevIndexDelta = indexDelta2;
|
|
232
|
-
debug && console.log("onScrollEnd", {
|
|
233
|
-
pxLeftScrolling,
|
|
234
|
-
indexDelta: indexDelta2,
|
|
235
|
-
scrollLeft,
|
|
236
|
-
positionItem,
|
|
237
|
-
itemPositions
|
|
238
|
-
});
|
|
239
|
-
update({
|
|
240
|
-
event: "scroll",
|
|
241
|
-
...fixIndex({
|
|
242
|
-
index: Math.floor(indexDelta2 / slidesPerPage),
|
|
243
|
-
indexDelta: indexDelta2
|
|
244
|
-
})
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
+
element?.addEventListener("scrollend", onScrollEnd);
|
|
248
249
|
} else {
|
|
249
250
|
element?.addEventListener("scroll", onScrollFn);
|
|
250
251
|
}
|
|
@@ -272,7 +273,11 @@ function createSnapSlider({
|
|
|
272
273
|
}
|
|
273
274
|
};
|
|
274
275
|
const destroy = () => {
|
|
275
|
-
|
|
276
|
+
if ("onscrollend" in window) {
|
|
277
|
+
element?.removeEventListener("scrollend", onScrollEnd);
|
|
278
|
+
} else {
|
|
279
|
+
element?.removeEventListener("scroll", onScrollFn);
|
|
280
|
+
}
|
|
276
281
|
window.removeEventListener("resize", onResizeFn);
|
|
277
282
|
};
|
|
278
283
|
const goNext = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snap-slider.es.js","sources":["../lib/throttle.ts","../lib/snap-slider.ts"],"sourcesContent":["export const throttle = (fn: Function, wait: number) => {\n let inThrottle: boolean\n let lastFn: ReturnType<typeof setTimeout>\n let lastTime: number\n return function (this: any) {\n const context = this\n const args = arguments\n if (!inThrottle) {\n fn.apply(context, args)\n lastTime = Date.now()\n inThrottle = true\n } else {\n clearTimeout(lastFn)\n lastFn = setTimeout(() => {\n if (Date.now() - lastTime >= wait) {\n fn.apply(context, args)\n lastTime = Date.now()\n }\n }, Math.max(wait - (Date.now() - lastTime), 0))\n }\n }\n}\n","import { throttle } from './throttle'\n\nexport type TSnapListnerEvent = 'scroll' | 'click' | 'inital' | 'goto'\n\nexport interface TSnapListnerStateIndex {\n index: number\n indexDelta: number\n}\n\nexport interface TSnapSliderState extends TSnapListnerStateIndex {\n count: number\n countDelta: number\n event: TSnapListnerEvent\n}\n\ninterface TSnapSliderStateUpdate {\n index?: number\n indexDelta?: number\n count?: number\n countDelta?: number\n event: TSnapListnerEvent\n}\n\nexport interface TSnapSliderStateFull extends TSnapSliderState {\n prevEnabled: boolean\n nextEnabled: boolean\n}\n\nexport type TSnapListner = (params: TSnapSliderStateFull) => void\n\nexport type TSnapSliderOptions = {\n circular?: boolean\n debug?: boolean\n scrollTimeThrottle?: number\n resizeTimeThrottle?: number\n scrollListenerThreshold?: number\n}\n\nexport type TSnapSliderParams = Omit<TSnapSliderStateUpdate, 'event'> &\n TSnapSliderOptions & {\n element: HTMLElement | null\n itemSelector?: string\n initalSubscriptionPublish?: boolean\n }\n\nexport type TSnapSliderJumpToFn = (\n index?: number,\n indexDelta?: number,\n event?: TSnapListnerEvent\n) => void\n\nexport interface TSnapSlider {\n destroy: () => void\n getState: () => TSnapSliderStateFull\n jumpTo: TSnapSliderJumpToFn\n goNext: () => void\n goPrev: () => void\n subscribe: (fn: TSnapListner) => () => void\n setElement: (el: HTMLElement) => void\n calculate: () => void\n}\n\nexport function createSnapSlider({\n element: _element,\n count = 1,\n countDelta,\n index = 0,\n circular,\n indexDelta,\n initalSubscriptionPublish = true,\n itemSelector = ':scope > *',\n debug,\n scrollTimeThrottle = 500,\n resizeTimeThrottle = 500,\n scrollListenerThreshold = 2,\n}: TSnapSliderParams): TSnapSlider {\n let initalIndex: number | undefined = index\n let state: TSnapSliderState = {\n index,\n indexDelta: indexDelta || index,\n event: 'inital',\n count,\n countDelta: countDelta || count,\n }\n let prevIndexDelta: number = index\n let slidesPerPage: number = 1\n let itemPositions: number[] = []\n let muteScrollListner: boolean = false\n let left: number = 0\n let element: HTMLElement | null\n function updateIndexDelta() {\n if (element) {\n const prev = element.scrollLeft\n const { indexDelta, event } = state\n left = indexDelta * (element.offsetWidth / slidesPerPage)\n if (prevIndexDelta !== indexDelta) {\n const distance = Math.abs(prev - left)\n const limitInstantScroll = element.offsetWidth * 2\n prevIndexDelta = indexDelta\n muteScrollListner = true\n const behavior: ScrollBehavior =\n distance > limitInstantScroll || event === 'click'\n ? 'instant'\n : 'smooth'\n element.scroll({\n left,\n top: 0,\n behavior,\n })\n } else {\n if (initalIndex) {\n muteScrollListner = true\n element.scroll({\n left,\n top: 0,\n behavior: 'instant',\n })\n initalIndex = undefined\n }\n }\n }\n }\n\n let publishDirty = false\n let listeners: TSnapListner[] = []\n const subscribe = (callback: TSnapListner) => {\n listeners.push(callback)\n if (element && (publishDirty || initalSubscriptionPublish)) {\n callback(getState())\n }\n return () => {\n listeners = listeners.filter((x) => x !== callback)\n if (listeners.length < 1) {\n destroy()\n }\n }\n }\n function notify() {\n listeners.forEach((callback) => {\n callback(getState())\n })\n }\n const getState = (): TSnapSliderStateFull => {\n const { indexDelta, countDelta } = state\n return {\n ...state,\n prevEnabled: circular || indexDelta > 0,\n nextEnabled: circular || countDelta - slidesPerPage > indexDelta,\n }\n }\n function update(params: TSnapSliderStateUpdate) {\n let dirty = false\n let indexDeltaDirty = false\n type TSnapSliderStateUpdateKey = keyof typeof params\n const keys: TSnapSliderStateUpdateKey[] = Object.keys(\n params\n ) as Array<TSnapSliderStateUpdateKey>\n state['event'] = params['event']\n keys.forEach((key) => {\n if (key !== 'event' && state[key] !== params[key]) {\n state[key] = Number(params[key])\n dirty = true\n if (key === 'indexDelta') {\n indexDeltaDirty = true\n }\n }\n })\n if (dirty) {\n publishDirty = listeners.length === 0\n notify()\n if (indexDeltaDirty) {\n updateIndexDelta()\n }\n }\n }\n function fixIndex(nextIndex: TSnapListnerStateIndex): TSnapListnerStateIndex {\n const { index, indexDelta } = nextIndex\n const { countDelta, count } = state\n const last = countDelta - slidesPerPage\n return {\n index: indexDelta < last ? index : count - 1,\n indexDelta,\n }\n }\n function calculate() {\n if (element) {\n let contentWidth = 0\n let itemWidth = 0\n itemPositions = []\n const slides = element.querySelectorAll<HTMLDivElement>(itemSelector)\n slides.forEach((slide) => {\n itemPositions.push(contentWidth)\n contentWidth += slide.clientWidth\n itemWidth = slide.clientWidth\n })\n slidesPerPage = Math.round(element.offsetWidth / itemWidth)\n const countDelta = itemPositions.length\n const count = Math.ceil(countDelta / slidesPerPage)\n const { index } = state\n const resetIndexMayby =\n index + 1 > count\n ? {\n index: 0,\n indexDelta: 0,\n }\n : {}\n\n if (!isNaN(count)) {\n // if element not mounted / hidden not update\n update({\n event: 'inital',\n count,\n countDelta,\n ...resetIndexMayby,\n })\n debug &&\n console.log('update count', {\n count,\n countDelta,\n itemPositions,\n slidesPerPage,\n clientWidth: element.clientWidth,\n offsetWidth: element.offsetWidth,\n itemSelector,\n slides,\n })\n }\n }\n }\n\n function onScroll() {\n if (element) {\n const scrollLeft = element.scrollLeft\n if (muteScrollListner) {\n const leftToScroll = Math.abs(left - scrollLeft)\n if (leftToScroll < 2) {\n muteScrollListner = false\n }\n } else {\n const positionItem = itemPositions.reduce((prev, curr) => {\n return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft)\n ? curr\n : prev\n })\n const indexDelta = itemPositions.findIndex((x) => x === positionItem)\n const pxLeftScrolling = Math.abs(scrollLeft - positionItem)\n prevIndexDelta = indexDelta\n debug &&\n console.log('onScroll', {\n pxLeftScrolling,\n indexDelta,\n scrollLeft,\n positionItem,\n itemPositions,\n })\n if (pxLeftScrolling < scrollListenerThreshold) {\n update({\n event: 'scroll',\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n }\n }\n }\n const onScrollFn = throttle(onScroll, scrollTimeThrottle)\n const onResizeFn = throttle(calculate, resizeTimeThrottle)\n function setElement(_el: HTMLElement) {\n if (element) {\n destroy()\n }\n element = _el\n updateIndexDelta()\n calculate()\n\n if ('onscrollend' in window) {\n element?.addEventListener('scrollend', (event) => {\n if (element) {\n const scrollLeft = element.scrollLeft\n const positionItem = itemPositions.reduce((prev, curr) => {\n return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft)\n ? curr\n : prev\n })\n const indexDelta = itemPositions.findIndex((x) => x === positionItem)\n const pxLeftScrolling = Math.abs(scrollLeft - positionItem)\n prevIndexDelta = indexDelta\n debug &&\n console.log('onScrollEnd', {\n pxLeftScrolling,\n indexDelta,\n scrollLeft,\n positionItem,\n itemPositions,\n })\n update({\n event: 'scroll',\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n })\n } else {\n element?.addEventListener('scroll', onScrollFn)\n }\n window.addEventListener('resize', onResizeFn)\n }\n _element && setElement(_element)\n const jumpTo: TSnapSliderJumpToFn = function (\n index,\n indexDelta,\n event = 'goto'\n ) {\n if (indexDelta !== undefined) {\n update({\n event,\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n if (index !== undefined) {\n update({\n event,\n ...fixIndex({\n index,\n indexDelta: index * slidesPerPage,\n }),\n })\n }\n }\n const destroy = () => {\n element?.removeEventListener('scroll', onScrollFn)\n window.removeEventListener('resize', onResizeFn)\n }\n const goNext = () => {\n const { countDelta, indexDelta } = state\n const last = countDelta - slidesPerPage\n const next =\n indexDelta + slidesPerPage <= last\n ? indexDelta + slidesPerPage\n : circular && indexDelta === last\n ? 0\n : last\n jumpTo(undefined, next)\n }\n const goPrev = () => {\n const { indexDelta, countDelta } = state\n const last = countDelta - slidesPerPage\n const next =\n indexDelta - slidesPerPage >= 0\n ? indexDelta - slidesPerPage\n : circular && indexDelta === 0\n ? last\n : 0\n jumpTo(undefined, next)\n }\n return {\n destroy,\n getState,\n subscribe,\n jumpTo,\n setElement,\n calculate,\n goNext,\n goPrev,\n }\n}\n"],"names":["indexDelta","countDelta","index","count"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"snap-slider.es.js","sources":["../lib/throttle.ts","../lib/snap-slider.ts"],"sourcesContent":["export const throttle = (fn: Function, wait: number) => {\n let inThrottle: boolean\n let lastFn: ReturnType<typeof setTimeout>\n let lastTime: number\n return function (this: any) {\n const context = this\n const args = arguments\n if (!inThrottle) {\n fn.apply(context, args)\n lastTime = Date.now()\n inThrottle = true\n } else {\n clearTimeout(lastFn)\n lastFn = setTimeout(() => {\n if (Date.now() - lastTime >= wait) {\n fn.apply(context, args)\n lastTime = Date.now()\n }\n }, Math.max(wait - (Date.now() - lastTime), 0))\n }\n }\n}\n","import { throttle } from './throttle'\n\nexport type TSnapListnerEvent = 'scroll' | 'click' | 'inital' | 'goto'\n\nexport interface TSnapListnerStateIndex {\n index: number\n indexDelta: number\n}\n\nexport interface TSnapSliderState extends TSnapListnerStateIndex {\n count: number\n countDelta: number\n event: TSnapListnerEvent\n}\n\ninterface TSnapSliderStateUpdate {\n index?: number\n indexDelta?: number\n count?: number\n countDelta?: number\n event: TSnapListnerEvent\n}\n\nexport interface TSnapSliderStateFull extends TSnapSliderState {\n prevEnabled: boolean\n nextEnabled: boolean\n}\n\nexport type TSnapListner = (params: TSnapSliderStateFull) => void\n\nexport type TSnapSliderOptions = {\n circular?: boolean\n debug?: boolean\n scrollTimeThrottle?: number\n resizeTimeThrottle?: number\n scrollListenerThreshold?: number\n}\n\nexport type TSnapSliderParams = Omit<TSnapSliderStateUpdate, 'event'> &\n TSnapSliderOptions & {\n element: HTMLElement | null\n itemSelector?: string\n initalSubscriptionPublish?: boolean\n }\n\nexport type TSnapSliderJumpToFn = (\n index?: number,\n indexDelta?: number,\n event?: TSnapListnerEvent\n) => void\n\nexport interface TSnapSlider {\n destroy: () => void\n getState: () => TSnapSliderStateFull\n jumpTo: TSnapSliderJumpToFn\n goNext: () => void\n goPrev: () => void\n subscribe: (fn: TSnapListner) => () => void\n setElement: (el: HTMLElement) => void\n calculate: () => void\n}\n\nexport function createSnapSlider({\n element: _element,\n count = 1,\n countDelta,\n index = 0,\n circular,\n indexDelta,\n initalSubscriptionPublish = true,\n itemSelector = ':scope > *',\n debug,\n scrollTimeThrottle = 500,\n resizeTimeThrottle = 500,\n scrollListenerThreshold = 2,\n}: TSnapSliderParams): TSnapSlider {\n let initalIndex: number | undefined = index\n let state: TSnapSliderState = {\n index,\n indexDelta: indexDelta || index,\n event: 'inital',\n count,\n countDelta: countDelta || count,\n }\n let prevIndexDelta: number = index\n let slidesPerPage: number = 1\n let itemPositions: number[] = []\n let muteScrollListner: boolean = false\n let left: number = 0\n let element: HTMLElement | null\n function updateIndexDelta() {\n if (element) {\n const prev = element.scrollLeft\n const { indexDelta, event } = state\n left = indexDelta * (element.offsetWidth / slidesPerPage)\n if (prevIndexDelta !== indexDelta) {\n const distance = Math.abs(prev - left)\n const limitInstantScroll = element.offsetWidth * 2\n prevIndexDelta = indexDelta\n muteScrollListner = true\n const behavior: ScrollBehavior =\n distance > limitInstantScroll || event === 'click'\n ? 'instant'\n : 'smooth'\n element.scroll({\n left,\n top: 0,\n behavior,\n })\n } else {\n if (initalIndex) {\n muteScrollListner = true\n element.scroll({\n left,\n top: 0,\n behavior: 'instant',\n })\n initalIndex = undefined\n }\n }\n }\n }\n\n let publishDirty = false\n let listeners: TSnapListner[] = []\n const subscribe = (callback: TSnapListner) => {\n listeners.push(callback)\n if (element && (publishDirty || initalSubscriptionPublish)) {\n callback(getState())\n }\n return () => {\n listeners = listeners.filter((x) => x !== callback)\n if (listeners.length < 1) {\n destroy()\n }\n }\n }\n function notify() {\n listeners.forEach((callback) => {\n callback(getState())\n })\n }\n const getState = (): TSnapSliderStateFull => {\n const { indexDelta, countDelta } = state\n return {\n ...state,\n prevEnabled: circular || indexDelta > 0,\n nextEnabled: circular || countDelta - slidesPerPage > indexDelta,\n }\n }\n function update(params: TSnapSliderStateUpdate) {\n let dirty = false\n let indexDeltaDirty = false\n type TSnapSliderStateUpdateKey = keyof typeof params\n const keys: TSnapSliderStateUpdateKey[] = Object.keys(\n params\n ) as Array<TSnapSliderStateUpdateKey>\n state['event'] = params['event']\n keys.forEach((key) => {\n if (key !== 'event' && state[key] !== params[key]) {\n state[key] = Number(params[key])\n dirty = true\n if (key === 'indexDelta') {\n indexDeltaDirty = true\n }\n }\n })\n if (dirty) {\n publishDirty = listeners.length === 0\n notify()\n if (indexDeltaDirty) {\n updateIndexDelta()\n }\n }\n }\n function fixIndex(nextIndex: TSnapListnerStateIndex): TSnapListnerStateIndex {\n const { index, indexDelta } = nextIndex\n const { countDelta, count } = state\n const last = countDelta - slidesPerPage\n return {\n index: indexDelta < last ? index : count - 1,\n indexDelta,\n }\n }\n function calculate() {\n if (element) {\n let contentWidth = 0\n let itemWidth = 0\n itemPositions = []\n const slides = element.querySelectorAll<HTMLDivElement>(itemSelector)\n slides.forEach((slide) => {\n itemPositions.push(contentWidth)\n contentWidth += slide.clientWidth\n itemWidth = slide.clientWidth\n })\n slidesPerPage = Math.round(element.offsetWidth / itemWidth)\n const countDelta = itemPositions.length\n const count = Math.ceil(countDelta / slidesPerPage)\n const { index } = state\n const resetIndexMayby =\n index + 1 > count\n ? {\n index: 0,\n indexDelta: 0,\n }\n : {}\n\n if (!isNaN(count)) {\n // if element not mounted / hidden not update\n update({\n event: 'inital',\n count,\n countDelta,\n ...resetIndexMayby,\n })\n debug &&\n console.log('update count', {\n count,\n countDelta,\n itemPositions,\n slidesPerPage,\n clientWidth: element.clientWidth,\n offsetWidth: element.offsetWidth,\n itemSelector,\n slides,\n })\n }\n }\n }\n function onScrollEnd() {\n if (element) {\n const scrollLeft = element.scrollLeft\n const positionItem = itemPositions.reduce((prev, curr) => {\n return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft)\n ? curr\n : prev\n })\n const indexDelta = itemPositions.findIndex((x) => x === positionItem)\n const pxLeftScrolling = Math.abs(scrollLeft - positionItem)\n prevIndexDelta = indexDelta\n debug &&\n console.log('onScrollEnd', {\n pxLeftScrolling,\n indexDelta,\n scrollLeft,\n positionItem,\n itemPositions,\n })\n update({\n event: 'scroll',\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n }\n function onScroll() {\n if (element) {\n const scrollLeft = element.scrollLeft\n if (muteScrollListner) {\n const leftToScroll = Math.abs(left - scrollLeft)\n if (leftToScroll < 2) {\n muteScrollListner = false\n }\n } else {\n const positionItem = itemPositions.reduce((prev, curr) => {\n return Math.abs(curr - scrollLeft) < Math.abs(prev - scrollLeft)\n ? curr\n : prev\n })\n const indexDelta = itemPositions.findIndex((x) => x === positionItem)\n const pxLeftScrolling = Math.abs(scrollLeft - positionItem)\n prevIndexDelta = indexDelta\n debug &&\n console.log('onScroll', {\n pxLeftScrolling,\n indexDelta,\n scrollLeft,\n positionItem,\n itemPositions,\n })\n if (pxLeftScrolling < scrollListenerThreshold) {\n update({\n event: 'scroll',\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n }\n }\n }\n const onScrollFn = throttle(onScroll, scrollTimeThrottle)\n const onResizeFn = throttle(calculate, resizeTimeThrottle)\n function setElement(_el: HTMLElement) {\n if (element) {\n destroy()\n }\n element = _el\n updateIndexDelta()\n calculate()\n if ('onscrollend' in window) {\n element?.addEventListener('scrollend', onScrollEnd)\n } else {\n element?.addEventListener('scroll', onScrollFn)\n }\n window.addEventListener('resize', onResizeFn)\n }\n _element && setElement(_element)\n const jumpTo: TSnapSliderJumpToFn = function (\n index,\n indexDelta,\n event = 'goto'\n ) {\n if (indexDelta !== undefined) {\n update({\n event,\n ...fixIndex({\n index: Math.floor(indexDelta / slidesPerPage),\n indexDelta,\n }),\n })\n }\n if (index !== undefined) {\n update({\n event,\n ...fixIndex({\n index,\n indexDelta: index * slidesPerPage,\n }),\n })\n }\n }\n const destroy = () => {\n if ('onscrollend' in window) {\n element?.removeEventListener('scrollend', onScrollEnd)\n } else {\n element?.removeEventListener('scroll', onScrollFn)\n }\n window.removeEventListener('resize', onResizeFn)\n }\n const goNext = () => {\n const { countDelta, indexDelta } = state\n const last = countDelta - slidesPerPage\n const next =\n indexDelta + slidesPerPage <= last\n ? indexDelta + slidesPerPage\n : circular && indexDelta === last\n ? 0\n : last\n jumpTo(undefined, next)\n }\n const goPrev = () => {\n const { indexDelta, countDelta } = state\n const last = countDelta - slidesPerPage\n const next =\n indexDelta - slidesPerPage >= 0\n ? indexDelta - slidesPerPage\n : circular && indexDelta === 0\n ? last\n : 0\n jumpTo(undefined, next)\n }\n return {\n destroy,\n getState,\n subscribe,\n jumpTo,\n setElement,\n calculate,\n goNext,\n goPrev,\n }\n}\n"],"names":["indexDelta","countDelta","index","count"],"mappings":"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"}
|