@fountain-ui/lab 2.0.0-beta.12 → 2.0.0-beta.15
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/build/commonjs/Carousel/Carousel.js +39 -37
- package/build/commonjs/Carousel/Carousel.js.map +1 -1
- package/build/commonjs/Carousel/CarouselProps.js.map +1 -1
- package/build/commonjs/Carousel/animation/createDefaultScrollAnimation.js +2 -2
- package/build/commonjs/Carousel/animation/createDefaultScrollAnimation.js.map +1 -1
- package/build/commonjs/Carousel/animation/parallaxItemStyleFactory.js +15 -15
- package/build/commonjs/Carousel/animation/parallaxItemStyleFactory.js.map +1 -1
- package/build/commonjs/Carousel/components/InternalContext.js.map +1 -1
- package/build/commonjs/Carousel/components/ItemView.js +6 -4
- package/build/commonjs/Carousel/components/ItemView.js.map +1 -1
- package/build/commonjs/Carousel/components/RootView.js +21 -3
- package/build/commonjs/Carousel/components/RootView.js.map +1 -1
- package/build/commonjs/Carousel/components/ScrollViewGesture.js +18 -13
- package/build/commonjs/Carousel/components/ScrollViewGesture.js.map +1 -1
- package/build/commonjs/Carousel/{hooks → components}/useItemInterpolation.js +6 -4
- package/build/commonjs/Carousel/components/useItemInterpolation.js.map +1 -0
- package/build/commonjs/Carousel/hooks/index.js +0 -16
- package/build/commonjs/Carousel/hooks/index.js.map +1 -1
- package/build/commonjs/Carousel/hooks/useAutoplayController.js +4 -1
- package/build/commonjs/Carousel/hooks/useAutoplayController.js.map +1 -1
- package/build/commonjs/Carousel/hooks/useIndexController.js +15 -46
- package/build/commonjs/Carousel/hooks/useIndexController.js.map +1 -1
- package/build/commonjs/Carousel/hooks/useItemVisibilityStore.js +12 -12
- package/build/commonjs/Carousel/hooks/useItemVisibilityStore.js.map +1 -1
- package/build/commonjs/Carousel/hooks/usePagingAnimation.js +121 -69
- package/build/commonjs/Carousel/hooks/usePagingAnimation.js.map +1 -1
- package/build/commonjs/Carousel/tick.js +16 -0
- package/build/commonjs/Carousel/tick.js.map +1 -0
- package/build/commonjs/Carousel/types.js.map +1 -1
- package/build/commonjs/ViewPager/ChildrenMemoizedPage.js +53 -47
- package/build/commonjs/ViewPager/ChildrenMemoizedPage.js.map +1 -1
- package/build/commonjs/ViewPager/InternalContext.js +17 -0
- package/build/commonjs/ViewPager/InternalContext.js.map +1 -0
- package/build/commonjs/ViewPager/ViewPagerNative.js +74 -23
- package/build/commonjs/ViewPager/ViewPagerNative.js.map +1 -1
- package/build/commonjs/ViewPager/ViewPagerProps.js.map +1 -1
- package/build/commonjs/ViewPager/ViewPagerWeb.js +23 -12
- package/build/commonjs/ViewPager/ViewPagerWeb.js.map +1 -1
- package/build/commonjs/ViewPager/index.js.map +1 -1
- package/build/commonjs/ViewPager/types.js +6 -0
- package/build/commonjs/ViewPager/types.js.map +1 -0
- package/build/commonjs/ViewPager/usePageStore.js +35 -0
- package/build/commonjs/ViewPager/usePageStore.js.map +1 -0
- package/build/commonjs/ViewPager/utils.js.map +1 -1
- package/build/commonjs/ViewabilityTrackerView/measureViewability.js +6 -6
- package/build/commonjs/ViewabilityTrackerView/measureViewability.js.map +1 -1
- package/build/commonjs/hooks/useUnstableCollapsibleAppBar.js +1 -1
- package/build/commonjs/hooks/useUnstableCollapsibleAppBar.js.map +1 -1
- package/build/module/Carousel/Carousel.js +39 -39
- package/build/module/Carousel/Carousel.js.map +1 -1
- package/build/module/Carousel/CarouselProps.js.map +1 -1
- package/build/module/Carousel/animation/createDefaultScrollAnimation.js +2 -2
- package/build/module/Carousel/animation/createDefaultScrollAnimation.js.map +1 -1
- package/build/module/Carousel/animation/parallaxItemStyleFactory.js +15 -15
- package/build/module/Carousel/animation/parallaxItemStyleFactory.js.map +1 -1
- package/build/module/Carousel/components/InternalContext.js.map +1 -1
- package/build/module/Carousel/components/ItemView.js +5 -3
- package/build/module/Carousel/components/ItemView.js.map +1 -1
- package/build/module/Carousel/components/RootView.js +22 -4
- package/build/module/Carousel/components/RootView.js.map +1 -1
- package/build/module/Carousel/components/ScrollViewGesture.js +18 -13
- package/build/module/Carousel/components/ScrollViewGesture.js.map +1 -1
- package/build/module/Carousel/{hooks → components}/useItemInterpolation.js +3 -3
- package/build/module/Carousel/components/useItemInterpolation.js.map +1 -0
- package/build/module/Carousel/hooks/index.js +0 -2
- package/build/module/Carousel/hooks/index.js.map +1 -1
- package/build/module/Carousel/hooks/useAutoplayController.js +4 -1
- package/build/module/Carousel/hooks/useAutoplayController.js.map +1 -1
- package/build/module/Carousel/hooks/useIndexController.js +14 -39
- package/build/module/Carousel/hooks/useIndexController.js.map +1 -1
- package/build/module/Carousel/hooks/useItemVisibilityStore.js +10 -11
- package/build/module/Carousel/hooks/useItemVisibilityStore.js.map +1 -1
- package/build/module/Carousel/hooks/usePagingAnimation.js +122 -69
- package/build/module/Carousel/hooks/usePagingAnimation.js.map +1 -1
- package/build/module/Carousel/tick.js +6 -0
- package/build/module/Carousel/tick.js.map +1 -0
- package/build/module/Carousel/types.js.map +1 -1
- package/build/module/ViewPager/ChildrenMemoizedPage.js +53 -47
- package/build/module/ViewPager/ChildrenMemoizedPage.js.map +1 -1
- package/build/module/ViewPager/InternalContext.js +7 -0
- package/build/module/ViewPager/InternalContext.js.map +1 -0
- package/build/module/ViewPager/ViewPagerNative.js +72 -23
- package/build/module/ViewPager/ViewPagerNative.js.map +1 -1
- package/build/module/ViewPager/ViewPagerProps.js.map +1 -1
- package/build/module/ViewPager/ViewPagerWeb.js +21 -13
- package/build/module/ViewPager/ViewPagerWeb.js.map +1 -1
- package/build/module/ViewPager/index.js.map +1 -1
- package/build/module/ViewPager/types.js +2 -0
- package/build/module/ViewPager/types.js.map +1 -0
- package/build/module/ViewPager/usePageStore.js +25 -0
- package/build/module/ViewPager/usePageStore.js.map +1 -0
- package/build/module/ViewPager/utils.js.map +1 -1
- package/build/module/ViewabilityTrackerView/measureViewability.js +2 -2
- package/build/module/ViewabilityTrackerView/measureViewability.js.map +1 -1
- package/build/module/hooks/useUnstableCollapsibleAppBar.js +1 -1
- package/build/module/hooks/useUnstableCollapsibleAppBar.js.map +1 -1
- package/build/typescript/Carousel/CarouselProps.d.ts +4 -3
- package/build/typescript/Carousel/animation/parallaxItemStyleFactory.d.ts +5 -5
- package/build/typescript/Carousel/components/InternalContext.d.ts +2 -2
- package/build/typescript/Carousel/components/ItemView.d.ts +2 -0
- package/build/typescript/Carousel/components/RootView.d.ts +4 -4
- package/build/typescript/Carousel/components/ScrollViewGesture.d.ts +3 -3
- package/build/typescript/Carousel/{hooks → components}/useItemInterpolation.d.ts +0 -0
- package/build/typescript/Carousel/hooks/index.d.ts +0 -2
- package/build/typescript/Carousel/hooks/useIndexController.d.ts +0 -2
- package/build/typescript/Carousel/hooks/useItemVisibilityStore.d.ts +5 -2
- package/build/typescript/Carousel/hooks/usePagingAnimation.d.ts +8 -10
- package/build/typescript/Carousel/tick.d.ts +2 -0
- package/build/typescript/Carousel/types.d.ts +26 -5
- package/build/typescript/ViewPager/ChildrenMemoizedPage.d.ts +1 -1
- package/build/typescript/ViewPager/InternalContext.d.ts +7 -0
- package/build/typescript/ViewPager/ViewPagerNative.d.ts +2 -2
- package/build/typescript/ViewPager/ViewPagerProps.d.ts +4 -22
- package/build/typescript/ViewPager/ViewPagerWeb.d.ts +2 -2
- package/build/typescript/ViewPager/index.d.ts +2 -1
- package/build/typescript/ViewPager/types.d.ts +19 -0
- package/build/typescript/ViewPager/usePageStore.d.ts +2 -0
- package/build/typescript/ViewPager/utils.d.ts +1 -1
- package/package.json +3 -3
- package/src/Carousel/Carousel.tsx +32 -40
- package/src/Carousel/CarouselProps.ts +4 -3
- package/src/Carousel/animation/createDefaultScrollAnimation.ts +2 -2
- package/src/Carousel/animation/parallaxItemStyleFactory.ts +24 -24
- package/src/Carousel/components/InternalContext.ts +2 -2
- package/src/Carousel/components/ItemView.tsx +13 -3
- package/src/Carousel/components/RootView.tsx +19 -6
- package/src/Carousel/components/ScrollViewGesture.tsx +23 -15
- package/src/Carousel/{hooks → components}/useItemInterpolation.ts +3 -3
- package/src/Carousel/hooks/index.ts +0 -2
- package/src/Carousel/hooks/useAutoplayController.ts +4 -1
- package/src/Carousel/hooks/useIndexController.tsx +14 -44
- package/src/Carousel/hooks/useItemVisibilityStore.ts +17 -13
- package/src/Carousel/hooks/usePagingAnimation.ts +161 -83
- package/src/Carousel/tick.ts +6 -0
- package/src/Carousel/types.ts +34 -5
- package/src/ViewPager/ChildrenMemoizedPage.tsx +53 -50
- package/src/ViewPager/InternalContext.ts +13 -0
- package/src/ViewPager/ViewPagerNative.tsx +91 -44
- package/src/ViewPager/ViewPagerProps.ts +4 -27
- package/src/ViewPager/ViewPagerWeb.tsx +28 -23
- package/src/ViewPager/index.ts +2 -1
- package/src/ViewPager/types.ts +24 -0
- package/src/ViewPager/usePageStore.ts +30 -0
- package/src/ViewPager/utils.tsx +1 -1
- package/src/ViewabilityTrackerView/measureViewability.ts +1 -3
- package/src/hooks/useUnstableCollapsibleAppBar.ts +1 -1
- package/build/commonjs/Carousel/hooks/useDimensionChangeReaction.js +0 -23
- package/build/commonjs/Carousel/hooks/useDimensionChangeReaction.js.map +0 -1
- package/build/commonjs/Carousel/hooks/useItemInterpolation.js.map +0 -1
- package/build/module/Carousel/hooks/useDimensionChangeReaction.js +0 -14
- package/build/module/Carousel/hooks/useDimensionChangeReaction.js.map +0 -1
- package/build/module/Carousel/hooks/useItemInterpolation.js.map +0 -1
- package/build/typescript/Carousel/hooks/useDimensionChangeReaction.d.ts +0 -7
- package/src/Carousel/hooks/useDimensionChangeReaction.ts +0 -25
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
import React, { useCallback } from 'react';
|
|
2
2
|
import { Animated } from 'react-native';
|
|
3
3
|
import { PanGestureHandler, State as GestureHandlerState } from 'react-native-gesture-handler';
|
|
4
|
-
const SCROLL_TO_ADJACENT_TX_THRESHOLD =
|
|
5
|
-
const SCROLL_TO_ADJACENT_VX_THRESHOLD =
|
|
4
|
+
const SCROLL_TO_ADJACENT_TX_THRESHOLD = 80;
|
|
5
|
+
const SCROLL_TO_ADJACENT_VX_THRESHOLD = 1000;
|
|
6
6
|
const ACTIVE_OFFSET_ABS_X = 5;
|
|
7
7
|
const activeOffsetX = [-ACTIVE_OFFSET_ABS_X, ACTIVE_OFFSET_ABS_X];
|
|
8
|
-
const endAnimationStates = [GestureHandlerState.CANCELLED, GestureHandlerState.END];
|
|
8
|
+
const endAnimationStates = [GestureHandlerState.CANCELLED, GestureHandlerState.END, GestureHandlerState.FAILED];
|
|
9
9
|
|
|
10
10
|
function shouldScrollToAdjacent(translationX, velocityX) {
|
|
11
|
-
|
|
11
|
+
const isSameDirection = translationX * velocityX > 0;
|
|
12
|
+
const isEnoughMovement = Math.abs(translationX) >= SCROLL_TO_ADJACENT_TX_THRESHOLD || Math.abs(velocityX) >= SCROLL_TO_ADJACENT_VX_THRESHOLD;
|
|
13
|
+
return isSameDirection && isEnoughMovement;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export default function ScrollViewGesture(props) {
|
|
15
17
|
const {
|
|
16
18
|
autoplayController,
|
|
17
19
|
children,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
interruptAnimation,
|
|
21
|
+
translateX,
|
|
20
22
|
scrollEnabled,
|
|
21
|
-
|
|
23
|
+
startPagingAnimation
|
|
22
24
|
} = props;
|
|
23
25
|
const {
|
|
24
26
|
pause: pauseAutoplay,
|
|
@@ -26,11 +28,11 @@ export default function ScrollViewGesture(props) {
|
|
|
26
28
|
} = autoplayController;
|
|
27
29
|
const handleGestureBegin = useCallback(() => {
|
|
28
30
|
pauseAutoplay();
|
|
29
|
-
|
|
30
|
-
}, [
|
|
31
|
+
interruptAnimation();
|
|
32
|
+
}, [interruptAnimation, pauseAutoplay]);
|
|
31
33
|
const handleGestureEvent = useCallback(Animated.event([{
|
|
32
34
|
nativeEvent: {
|
|
33
|
-
translationX:
|
|
35
|
+
translationX: translateX
|
|
34
36
|
}
|
|
35
37
|
}], {
|
|
36
38
|
useNativeDriver: true
|
|
@@ -45,11 +47,14 @@ export default function ScrollViewGesture(props) {
|
|
|
45
47
|
} = event;
|
|
46
48
|
|
|
47
49
|
if (endAnimationStates.includes(state)) {
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
+
const direction = shouldScrollToAdjacent(translationX, velocityX) ? translationX < 0 ? 'next' : 'prev' : 'stay';
|
|
51
|
+
startPagingAnimation('directional', {
|
|
52
|
+
direction: direction,
|
|
53
|
+
isOriginatedFromGesture: true
|
|
54
|
+
});
|
|
50
55
|
resumeAutoplay();
|
|
51
56
|
}
|
|
52
|
-
}, [
|
|
57
|
+
}, [startPagingAnimation, resumeAutoplay]);
|
|
53
58
|
return /*#__PURE__*/React.createElement(PanGestureHandler, {
|
|
54
59
|
activeOffsetX: activeOffsetX,
|
|
55
60
|
children: children,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useCallback","Animated","PanGestureHandler","State","GestureHandlerState","SCROLL_TO_ADJACENT_TX_THRESHOLD","SCROLL_TO_ADJACENT_VX_THRESHOLD","ACTIVE_OFFSET_ABS_X","activeOffsetX","endAnimationStates","CANCELLED","END","shouldScrollToAdjacent","translationX","velocityX","Math","abs","ScrollViewGesture","props","autoplayController","children","
|
|
1
|
+
{"version":3,"names":["React","useCallback","Animated","PanGestureHandler","State","GestureHandlerState","SCROLL_TO_ADJACENT_TX_THRESHOLD","SCROLL_TO_ADJACENT_VX_THRESHOLD","ACTIVE_OFFSET_ABS_X","activeOffsetX","endAnimationStates","CANCELLED","END","FAILED","shouldScrollToAdjacent","translationX","velocityX","isSameDirection","isEnoughMovement","Math","abs","ScrollViewGesture","props","autoplayController","children","interruptAnimation","translateX","scrollEnabled","startPagingAnimation","pause","pauseAutoplay","resume","resumeAutoplay","handleGestureBegin","handleGestureEvent","event","nativeEvent","useNativeDriver","handleHandlerStateChange","state","includes","direction","isOriginatedFromGesture"],"sources":["ScrollViewGesture.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport React, { useCallback } from 'react';\nimport { Animated } from 'react-native';\nimport type { PanGestureHandlerStateChangeEvent } from 'react-native-gesture-handler';\nimport { PanGestureHandler, State as GestureHandlerState } from 'react-native-gesture-handler';\nimport type { AutoplayController, PagingDirection, StartPagingAnimation } from '../types';\n\nexport interface ScrollViewGestureProps {\n autoplayController: AutoplayController;\n children: ReactNode;\n interruptAnimation: () => void;\n translateX: Animated.Value,\n scrollEnabled: boolean;\n startPagingAnimation: StartPagingAnimation;\n}\n\nconst SCROLL_TO_ADJACENT_TX_THRESHOLD = 80;\nconst SCROLL_TO_ADJACENT_VX_THRESHOLD = 1000;\n\nconst ACTIVE_OFFSET_ABS_X = 5;\nconst activeOffsetX: number[] = [-ACTIVE_OFFSET_ABS_X, ACTIVE_OFFSET_ABS_X];\n\nconst endAnimationStates: Readonly<GestureHandlerState[]> = [\n GestureHandlerState.CANCELLED,\n GestureHandlerState.END,\n GestureHandlerState.FAILED,\n];\n\nfunction shouldScrollToAdjacent(translationX: number, velocityX: number): boolean {\n const isSameDirection = translationX * velocityX > 0;\n const isEnoughMovement =\n Math.abs(translationX) >= SCROLL_TO_ADJACENT_TX_THRESHOLD\n || Math.abs(velocityX) >= SCROLL_TO_ADJACENT_VX_THRESHOLD;\n\n return isSameDirection && isEnoughMovement;\n}\n\nexport default function ScrollViewGesture(props: ScrollViewGestureProps) {\n const {\n autoplayController,\n children,\n interruptAnimation,\n translateX,\n scrollEnabled,\n startPagingAnimation,\n } = props;\n\n const { pause: pauseAutoplay, resume: resumeAutoplay } = autoplayController;\n\n const handleGestureBegin = useCallback(() => {\n pauseAutoplay();\n\n interruptAnimation();\n }, [interruptAnimation, pauseAutoplay]);\n\n const handleGestureEvent = useCallback(Animated.event(\n [{ nativeEvent: { translationX: translateX } }],\n { useNativeDriver: true },\n ), []);\n\n const handleHandlerStateChange = useCallback((event: PanGestureHandlerStateChangeEvent) => {\n const { nativeEvent: { translationX, velocityX, state } } = event;\n\n if (endAnimationStates.includes(state)) {\n const direction: PagingDirection = shouldScrollToAdjacent(translationX, velocityX)\n ? (translationX < 0 ? 'next' : 'prev')\n : 'stay';\n\n startPagingAnimation(\n 'directional',\n { direction: direction, isOriginatedFromGesture: true },\n );\n\n resumeAutoplay();\n }\n }, [startPagingAnimation, resumeAutoplay]);\n\n return (\n <PanGestureHandler\n activeOffsetX={activeOffsetX}\n children={children}\n enabled={scrollEnabled}\n onBegan={handleGestureBegin}\n onGestureEvent={handleGestureEvent}\n onHandlerStateChange={handleHandlerStateChange}\n />\n );\n}\n"],"mappings":"AACA,OAAOA,KAAP,IAAgBC,WAAhB,QAAmC,OAAnC;AACA,SAASC,QAAT,QAAyB,cAAzB;AAEA,SAASC,iBAAT,EAA4BC,KAAK,IAAIC,mBAArC,QAAgE,8BAAhE;AAYA,MAAMC,+BAA+B,GAAG,EAAxC;AACA,MAAMC,+BAA+B,GAAG,IAAxC;AAEA,MAAMC,mBAAmB,GAAG,CAA5B;AACA,MAAMC,aAAuB,GAAG,CAAC,CAACD,mBAAF,EAAuBA,mBAAvB,CAAhC;AAEA,MAAME,kBAAmD,GAAG,CACxDL,mBAAmB,CAACM,SADoC,EAExDN,mBAAmB,CAACO,GAFoC,EAGxDP,mBAAmB,CAACQ,MAHoC,CAA5D;;AAMA,SAASC,sBAAT,CAAgCC,YAAhC,EAAsDC,SAAtD,EAAkF;EAC9E,MAAMC,eAAe,GAAGF,YAAY,GAAGC,SAAf,GAA2B,CAAnD;EACA,MAAME,gBAAgB,GAClBC,IAAI,CAACC,GAAL,CAASL,YAAT,KAA0BT,+BAA1B,IACGa,IAAI,CAACC,GAAL,CAASJ,SAAT,KAAuBT,+BAF9B;EAIA,OAAOU,eAAe,IAAIC,gBAA1B;AACH;;AAED,eAAe,SAASG,iBAAT,CAA2BC,KAA3B,EAA0D;EACrE,MAAM;IACFC,kBADE;IAEFC,QAFE;IAGFC,kBAHE;IAIFC,UAJE;IAKFC,aALE;IAMFC;EANE,IAOFN,KAPJ;EASA,MAAM;IAAEO,KAAK,EAAEC,aAAT;IAAwBC,MAAM,EAAEC;EAAhC,IAAmDT,kBAAzD;EAEA,MAAMU,kBAAkB,GAAGhC,WAAW,CAAC,MAAM;IACzC6B,aAAa;IAEbL,kBAAkB;EACrB,CAJqC,EAInC,CAACA,kBAAD,EAAqBK,aAArB,CAJmC,CAAtC;EAMA,MAAMI,kBAAkB,GAAGjC,WAAW,CAACC,QAAQ,CAACiC,KAAT,CACnC,CAAC;IAAEC,WAAW,EAAE;MAAErB,YAAY,EAAEW;IAAhB;EAAf,CAAD,CADmC,EAEnC;IAAEW,eAAe,EAAE;EAAnB,CAFmC,CAAD,EAGnC,EAHmC,CAAtC;EAKA,MAAMC,wBAAwB,GAAGrC,WAAW,CAAEkC,KAAD,IAA8C;IACvF,MAAM;MAAEC,WAAW,EAAE;QAAErB,YAAF;QAAgBC,SAAhB;QAA2BuB;MAA3B;IAAf,IAAsDJ,KAA5D;;IAEA,IAAIzB,kBAAkB,CAAC8B,QAAnB,CAA4BD,KAA5B,CAAJ,EAAwC;MACpC,MAAME,SAA0B,GAAG3B,sBAAsB,CAACC,YAAD,EAAeC,SAAf,CAAtB,GAC5BD,YAAY,GAAG,CAAf,GAAmB,MAAnB,GAA4B,MADA,GAE7B,MAFN;MAIAa,oBAAoB,CAChB,aADgB,EAEhB;QAAEa,SAAS,EAAEA,SAAb;QAAwBC,uBAAuB,EAAE;MAAjD,CAFgB,CAApB;MAKAV,cAAc;IACjB;EACJ,CAf2C,EAezC,CAACJ,oBAAD,EAAuBI,cAAvB,CAfyC,CAA5C;EAiBA,oBACI,oBAAC,iBAAD;IACI,aAAa,EAAEvB,aADnB;IAEI,QAAQ,EAAEe,QAFd;IAGI,OAAO,EAAEG,aAHb;IAII,OAAO,EAAEM,kBAJb;IAKI,cAAc,EAAEC,kBALpB;IAMI,oBAAoB,EAAEI;EAN1B,EADJ;AAUH"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useContext, useMemo } from 'react';
|
|
2
2
|
import { Animated } from 'react-native';
|
|
3
|
-
import
|
|
3
|
+
import InternalContext from './InternalContext';
|
|
4
4
|
const OVERSCROLL_FRICTION_FACTOR = 4;
|
|
5
5
|
export default function useItemInterpolation(index) {
|
|
6
6
|
const {
|
|
@@ -43,8 +43,8 @@ export default function useItemInterpolation(index) {
|
|
|
43
43
|
}, [index, itemWidth, numberOfData]);
|
|
44
44
|
return useMemo(() => {
|
|
45
45
|
const interpolationConfig = loop ? interpolationConfigOnLoop : interpolationConfigOnNoLoop;
|
|
46
|
-
const
|
|
47
|
-
return Animated.divide(
|
|
46
|
+
const localOffsetX = globalInterpolation.interpolate(interpolationConfig);
|
|
47
|
+
return Animated.divide(localOffsetX, itemWidth);
|
|
48
48
|
}, [globalInterpolation, interpolationConfigOnLoop, interpolationConfigOnNoLoop, itemWidth, loop]);
|
|
49
49
|
}
|
|
50
50
|
;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useContext","useMemo","Animated","InternalContext","OVERSCROLL_FRICTION_FACTOR","useItemInterpolation","index","itemWidth","data","globalInterpolation","loop","numberOfData","length","interpolationConfigOnLoop","lastIndex","maxWidth","Math","abs","halfOfItemWidth","positiveCount","round","startPosition","max","min","inputRange","Number","MIN_VALUE","outputRange","extrapolate","interpolationConfigOnNoLoop","friction","interpolationConfig","localOffsetX","interpolate","divide"],"sources":["useItemInterpolation.ts"],"sourcesContent":["import { useContext, useMemo } from 'react';\nimport { Animated } from 'react-native';\nimport InternalContext from './InternalContext';\n\nconst OVERSCROLL_FRICTION_FACTOR = 4;\n\nexport default function useItemInterpolation(index: number): Animated.AnimatedInterpolation {\n const {\n itemWidth,\n data,\n globalInterpolation,\n loop,\n } = useContext(InternalContext);\n\n const numberOfData = data.length;\n\n const interpolationConfigOnLoop = useMemo<Animated.InterpolationConfigType>(() => {\n const lastIndex = numberOfData - 1;\n const maxWidth = Math.abs(itemWidth * numberOfData);\n const halfOfItemWidth = 0.5 * itemWidth;\n\n const positiveCount = Math.round(lastIndex / 2);\n const startPosition = index > positiveCount\n ? (index - numberOfData) * itemWidth\n : itemWidth * index;\n\n const max = positiveCount * itemWidth;\n const min = -((lastIndex - positiveCount) * itemWidth);\n\n const inputRange = [\n -maxWidth,\n min - halfOfItemWidth - startPosition - Number.MIN_VALUE,\n min - halfOfItemWidth - startPosition,\n 0,\n max + halfOfItemWidth - startPosition,\n max + halfOfItemWidth - startPosition + Number.MIN_VALUE,\n maxWidth,\n ];\n\n const outputRange = [\n startPosition,\n max + halfOfItemWidth - Number.MIN_VALUE,\n min - halfOfItemWidth,\n startPosition,\n max + halfOfItemWidth,\n min - halfOfItemWidth + Number.MIN_VALUE,\n startPosition,\n ];\n\n return {\n inputRange,\n outputRange,\n extrapolate: 'clamp',\n };\n }, [\n index,\n itemWidth,\n numberOfData,\n ]);\n\n const interpolationConfigOnNoLoop = useMemo<Animated.InterpolationConfigType>(() => {\n const lastIndex = numberOfData - 1;\n const maxWidth = itemWidth * lastIndex;\n const startPosition = itemWidth * index;\n const friction = itemWidth / OVERSCROLL_FRICTION_FACTOR;\n\n const inputRange = [\n -(maxWidth + itemWidth), // overscroll\n -maxWidth,\n 0,\n itemWidth, // overscroll\n ];\n\n const outputRange = [\n -maxWidth + startPosition - friction,\n -maxWidth + startPosition,\n startPosition,\n startPosition + friction,\n ];\n\n return {\n inputRange,\n outputRange,\n extrapolate: 'clamp',\n };\n }, [\n index,\n itemWidth,\n numberOfData,\n ]);\n\n return useMemo(() => {\n const interpolationConfig = loop\n ? interpolationConfigOnLoop\n : interpolationConfigOnNoLoop;\n\n const localOffsetX = globalInterpolation.interpolate(interpolationConfig);\n\n return Animated.divide(localOffsetX, itemWidth);\n }, [\n globalInterpolation,\n interpolationConfigOnLoop,\n interpolationConfigOnNoLoop,\n itemWidth,\n loop,\n ]);\n};\n"],"mappings":"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"}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
export { default as useAutoplayController } from './useAutoplayController';
|
|
2
|
-
export { default as useDimensionChangeReaction } from './useDimensionChangeReaction';
|
|
3
2
|
export { default as useIndexController } from './useIndexController';
|
|
4
|
-
export { default as useItemInterpolation } from './useItemInterpolation';
|
|
5
3
|
export { default as useLoopedData } from './useLoopedData';
|
|
6
4
|
export { default as usePagingAnimation } from './usePagingAnimation';
|
|
7
5
|
export { default as useItemVisibilityStore } from './useItemVisibilityStore';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["default","useAutoplayController","
|
|
1
|
+
{"version":3,"names":["default","useAutoplayController","useIndexController","useLoopedData","usePagingAnimation","useItemVisibilityStore"],"sources":["index.ts"],"sourcesContent":["export { default as useAutoplayController } from './useAutoplayController';\nexport { default as useIndexController } from './useIndexController';\nexport { default as useLoopedData } from './useLoopedData';\nexport { default as usePagingAnimation } from './usePagingAnimation';\nexport { default as useItemVisibilityStore } from './useItemVisibilityStore';\n"],"mappings":"AAAA,SAASA,OAAO,IAAIC,qBAApB,QAAiD,yBAAjD;AACA,SAASD,OAAO,IAAIE,kBAApB,QAA8C,sBAA9C;AACA,SAASF,OAAO,IAAIG,aAApB,QAAyC,iBAAzC;AACA,SAASH,OAAO,IAAII,kBAApB,QAA8C,sBAA9C;AACA,SAASJ,OAAO,IAAIK,sBAApB,QAAkD,0BAAlD"}
|
|
@@ -14,7 +14,10 @@ export default function useAutoplayController(config) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
executor.execute(() => {
|
|
17
|
-
startPagingAnimation('
|
|
17
|
+
startPagingAnimation('directional', {
|
|
18
|
+
direction: 'next',
|
|
19
|
+
isOriginatedFromGesture: false
|
|
20
|
+
});
|
|
18
21
|
play();
|
|
19
22
|
}, intervalMillis);
|
|
20
23
|
}, [intervalMillis, startPagingAnimation]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useEffect","useRef","useDeferredExecutor","useAutoplayController","config","enabled","intervalMillis","startPagingAnimation","paused","executor","play","current","execute","pause","cancel","resume"],"sources":["useAutoplayController.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport type { AutoplayController, StartPagingAnimation } from '../types';\nimport { useDeferredExecutor } from '../../hooks';\n\nexport interface AutoplayConfig {\n enabled: boolean;\n intervalMillis: number;\n startPagingAnimation: StartPagingAnimation;\n}\n\nexport default function useAutoplayController(config: AutoplayConfig): AutoplayController {\n const {\n enabled,\n intervalMillis,\n startPagingAnimation,\n } = config;\n\n const paused = useRef<boolean>(false);\n\n const executor = useDeferredExecutor();\n\n const play = useCallback(() => {\n if (paused.current) {\n return;\n }\n\n executor.execute(() => {\n startPagingAnimation('next', false);\n play();\n }, intervalMillis);\n }, [intervalMillis, startPagingAnimation]);\n\n const pause = useCallback(() => {\n executor.cancel();\n paused.current = true;\n }, []);\n\n const resume = useCallback(() => {\n paused.current = false;\n if (enabled) {\n play();\n }\n }, [play, enabled]);\n\n useEffect(() => {\n if (enabled) {\n resume();\n } else {\n pause();\n }\n }, [enabled]);\n\n return { pause, resume };\n};\n"],"mappings":"AAAA,SAASA,WAAT,EAAsBC,SAAtB,EAAiCC,MAAjC,QAA+C,OAA/C;AAEA,SAASC,mBAAT,QAAoC,aAApC;AAQA,eAAe,SAASC,qBAAT,CAA+BC,MAA/B,EAA2E;EACtF,MAAM;IACFC,OADE;IAEFC,cAFE;IAGFC;EAHE,IAIFH,MAJJ;EAMA,MAAMI,MAAM,GAAGP,MAAM,CAAU,KAAV,CAArB;EAEA,MAAMQ,QAAQ,GAAGP,mBAAmB,EAApC;EAEA,MAAMQ,IAAI,GAAGX,WAAW,CAAC,MAAM;IAC3B,IAAIS,MAAM,CAACG,OAAX,EAAoB;MAChB;IACH;;IAEDF,QAAQ,CAACG,OAAT,CAAiB,MAAM;MACnBL,oBAAoB,
|
|
1
|
+
{"version":3,"names":["useCallback","useEffect","useRef","useDeferredExecutor","useAutoplayController","config","enabled","intervalMillis","startPagingAnimation","paused","executor","play","current","execute","direction","isOriginatedFromGesture","pause","cancel","resume"],"sources":["useAutoplayController.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport type { AutoplayController, StartPagingAnimation } from '../types';\nimport { useDeferredExecutor } from '../../hooks';\n\nexport interface AutoplayConfig {\n enabled: boolean;\n intervalMillis: number;\n startPagingAnimation: StartPagingAnimation;\n}\n\nexport default function useAutoplayController(config: AutoplayConfig): AutoplayController {\n const {\n enabled,\n intervalMillis,\n startPagingAnimation,\n } = config;\n\n const paused = useRef<boolean>(false);\n\n const executor = useDeferredExecutor();\n\n const play = useCallback(() => {\n if (paused.current) {\n return;\n }\n\n executor.execute(() => {\n startPagingAnimation(\n 'directional',\n { direction: 'next', isOriginatedFromGesture: false },\n );\n play();\n }, intervalMillis);\n }, [intervalMillis, startPagingAnimation]);\n\n const pause = useCallback(() => {\n executor.cancel();\n paused.current = true;\n }, []);\n\n const resume = useCallback(() => {\n paused.current = false;\n if (enabled) {\n play();\n }\n }, [play, enabled]);\n\n useEffect(() => {\n if (enabled) {\n resume();\n } else {\n pause();\n }\n }, [enabled]);\n\n return { pause, resume };\n};\n"],"mappings":"AAAA,SAASA,WAAT,EAAsBC,SAAtB,EAAiCC,MAAjC,QAA+C,OAA/C;AAEA,SAASC,mBAAT,QAAoC,aAApC;AAQA,eAAe,SAASC,qBAAT,CAA+BC,MAA/B,EAA2E;EACtF,MAAM;IACFC,OADE;IAEFC,cAFE;IAGFC;EAHE,IAIFH,MAJJ;EAMA,MAAMI,MAAM,GAAGP,MAAM,CAAU,KAAV,CAArB;EAEA,MAAMQ,QAAQ,GAAGP,mBAAmB,EAApC;EAEA,MAAMQ,IAAI,GAAGX,WAAW,CAAC,MAAM;IAC3B,IAAIS,MAAM,CAACG,OAAX,EAAoB;MAChB;IACH;;IAEDF,QAAQ,CAACG,OAAT,CAAiB,MAAM;MACnBL,oBAAoB,CAChB,aADgB,EAEhB;QAAEM,SAAS,EAAE,MAAb;QAAqBC,uBAAuB,EAAE;MAA9C,CAFgB,CAApB;MAIAJ,IAAI;IACP,CAND,EAMGJ,cANH;EAOH,CAZuB,EAYrB,CAACA,cAAD,EAAiBC,oBAAjB,CAZqB,CAAxB;EAcA,MAAMQ,KAAK,GAAGhB,WAAW,CAAC,MAAM;IAC5BU,QAAQ,CAACO,MAAT;IACAR,MAAM,CAACG,OAAP,GAAiB,IAAjB;EACH,CAHwB,EAGtB,EAHsB,CAAzB;EAKA,MAAMM,MAAM,GAAGlB,WAAW,CAAC,MAAM;IAC7BS,MAAM,CAACG,OAAP,GAAiB,KAAjB;;IACA,IAAIN,OAAJ,EAAa;MACTK,IAAI;IACP;EACJ,CALyB,EAKvB,CAACA,IAAD,EAAOL,OAAP,CALuB,CAA1B;EAOAL,SAAS,CAAC,MAAM;IACZ,IAAIK,OAAJ,EAAa;MACTY,MAAM;IACT,CAFD,MAEO;MACHF,KAAK;IACR;EACJ,CANQ,EAMN,CAACV,OAAD,CANM,CAAT;EAQA,OAAO;IAAEU,KAAF;IAASE;EAAT,CAAP;AACH;AAAA"}
|
|
@@ -1,53 +1,28 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
const normalizeIndex = (maybeIndex, numberOfData) => Math.abs(Math.floor(maybeIndex)) % numberOfData;
|
|
5
|
-
|
|
1
|
+
import { useCallback, useRef } from 'react';
|
|
2
|
+
import { mod } from '@fountain-ui/utils';
|
|
6
3
|
export default function useIndexController(params) {
|
|
7
4
|
const {
|
|
8
|
-
controlledTx,
|
|
9
5
|
initialIndex,
|
|
10
6
|
itemWidth,
|
|
11
7
|
numberOfOriginalData,
|
|
12
8
|
onIndexChange
|
|
13
9
|
} = params;
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
return Animated.modulo(normalized, numberOfOriginalData);
|
|
21
|
-
}, [controlledTx, itemWidth, numberOfOriginalData]);
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
const subscriptionId = maybeIndex.addListener(observedValue => {
|
|
24
|
-
const newIndex = normalizeIndex(observedValue.value, numberOfOriginalData);
|
|
10
|
+
const currentIndexRef = useRef(initialIndex);
|
|
11
|
+
const getCurrentIndex = useCallback(() => currentIndexRef.current, []);
|
|
12
|
+
const notifyOffsetHasChanged = useCallback(offset => {
|
|
13
|
+
const roundedOffset = Math.round(offset / itemWidth) * itemWidth; // To prevent floating point problem, make sure index is integer type.
|
|
14
|
+
|
|
15
|
+
const nextIndex = Math.floor(mod(-roundedOffset / itemWidth, numberOfOriginalData));
|
|
25
16
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
});
|
|
32
|
-
return () => {
|
|
33
|
-
maybeIndex.removeListener(subscriptionId);
|
|
34
|
-
};
|
|
35
|
-
}, [maybeIndex, numberOfOriginalData, onIndexChange]);
|
|
36
|
-
const getCurrentIndex = useCallback(() => indexRef.current, []);
|
|
17
|
+
if (nextIndex !== currentIndexRef.current) {
|
|
18
|
+
currentIndexRef.current = nextIndex;
|
|
19
|
+
onIndexChange === null || onIndexChange === void 0 ? void 0 : onIndexChange(nextIndex);
|
|
20
|
+
}
|
|
21
|
+
}, [itemWidth, numberOfOriginalData, onIndexChange]);
|
|
37
22
|
return {
|
|
38
|
-
currentIndex: index,
|
|
39
23
|
getCurrentIndex,
|
|
40
24
|
lastIndex: numberOfOriginalData - 1,
|
|
41
|
-
|
|
42
|
-
collapsable: false,
|
|
43
|
-
style: [{
|
|
44
|
-
zIndex: maybeIndex
|
|
45
|
-
}, {
|
|
46
|
-
width: 1,
|
|
47
|
-
height: 1,
|
|
48
|
-
position: 'absolute'
|
|
49
|
-
}]
|
|
50
|
-
})
|
|
25
|
+
notifyOffsetHasChanged
|
|
51
26
|
};
|
|
52
27
|
}
|
|
53
28
|
;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"names":["useCallback","useRef","mod","useIndexController","params","initialIndex","itemWidth","numberOfOriginalData","onIndexChange","currentIndexRef","getCurrentIndex","current","notifyOffsetHasChanged","offset","roundedOffset","Math","round","nextIndex","floor","lastIndex"],"sources":["useIndexController.tsx"],"sourcesContent":["import React, { useCallback, useRef } from 'react';\nimport { mod } from '@fountain-ui/utils';\nimport type { IndexController } from '../types';\n\nexport interface UseIndexControllerParameters {\n initialIndex: number;\n itemWidth: number;\n numberOfOriginalData: number;\n onIndexChange?: (newIndex: number) => void;\n}\n\nexport default function useIndexController(params: UseIndexControllerParameters): IndexController {\n const {\n initialIndex,\n itemWidth,\n numberOfOriginalData,\n onIndexChange,\n } = params;\n\n const currentIndexRef = useRef<number>(initialIndex);\n\n const getCurrentIndex = useCallback(() => currentIndexRef.current, []);\n\n const notifyOffsetHasChanged = useCallback((offset: number) => {\n const roundedOffset = Math.round(offset / itemWidth) * itemWidth;\n\n // To prevent floating point problem, make sure index is integer type.\n const nextIndex = Math.floor(mod((-roundedOffset / itemWidth), numberOfOriginalData));\n\n if (nextIndex !== currentIndexRef.current) {\n currentIndexRef.current = nextIndex;\n\n onIndexChange?.(nextIndex);\n }\n }, [\n itemWidth,\n numberOfOriginalData,\n onIndexChange,\n ]);\n\n return {\n getCurrentIndex,\n lastIndex: numberOfOriginalData - 1,\n notifyOffsetHasChanged,\n };\n};\n"],"mappings":"AAAA,SAAgBA,WAAhB,EAA6BC,MAA7B,QAA2C,OAA3C;AACA,SAASC,GAAT,QAAoB,oBAApB;AAUA,eAAe,SAASC,kBAAT,CAA4BC,MAA5B,EAAmF;EAC9F,MAAM;IACFC,YADE;IAEFC,SAFE;IAGFC,oBAHE;IAIFC;EAJE,IAKFJ,MALJ;EAOA,MAAMK,eAAe,GAAGR,MAAM,CAASI,YAAT,CAA9B;EAEA,MAAMK,eAAe,GAAGV,WAAW,CAAC,MAAMS,eAAe,CAACE,OAAvB,EAAgC,EAAhC,CAAnC;EAEA,MAAMC,sBAAsB,GAAGZ,WAAW,CAAEa,MAAD,IAAoB;IAC3D,MAAMC,aAAa,GAAGC,IAAI,CAACC,KAAL,CAAWH,MAAM,GAAGP,SAApB,IAAiCA,SAAvD,CAD2D,CAG3D;;IACA,MAAMW,SAAS,GAAGF,IAAI,CAACG,KAAL,CAAWhB,GAAG,CAAE,CAACY,aAAD,GAAiBR,SAAnB,EAA+BC,oBAA/B,CAAd,CAAlB;;IAEA,IAAIU,SAAS,KAAKR,eAAe,CAACE,OAAlC,EAA2C;MACvCF,eAAe,CAACE,OAAhB,GAA0BM,SAA1B;MAEAT,aAAa,SAAb,IAAAA,aAAa,WAAb,YAAAA,aAAa,CAAGS,SAAH,CAAb;IACH;EACJ,CAXyC,EAWvC,CACCX,SADD,EAECC,oBAFD,EAGCC,aAHD,CAXuC,CAA1C;EAiBA,OAAO;IACHE,eADG;IAEHS,SAAS,EAAEZ,oBAAoB,GAAG,CAF/B;IAGHK;EAHG,CAAP;AAKH;AAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
2
2
|
|
|
3
|
-
import { useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
4
|
+
import { mod } from '@fountain-ui/utils';
|
|
4
5
|
|
|
5
6
|
class SimpleItemVisibilityStore {
|
|
6
7
|
constructor(initialValue) {
|
|
@@ -47,10 +48,6 @@ function normalize(windowSize, numberOfData) {
|
|
|
47
48
|
return windowSize;
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
function mod(value, modulo) {
|
|
51
|
-
return (value % modulo + modulo) % modulo;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
51
|
function makeVisibleIndexRanges(numberOfData, windowSize, index) {
|
|
55
52
|
const ws = normalize(windowSize, numberOfData);
|
|
56
53
|
const firstIndex = 0;
|
|
@@ -66,22 +63,24 @@ function makeVisibleIndexRanges(numberOfData, windowSize, index) {
|
|
|
66
63
|
|
|
67
64
|
export default function useItemVisibilityStore(params) {
|
|
68
65
|
const {
|
|
69
|
-
|
|
66
|
+
initialIndex,
|
|
70
67
|
numberOfData,
|
|
71
68
|
windowSize
|
|
72
69
|
} = params;
|
|
73
|
-
const [initialRange] = useState(() =>
|
|
70
|
+
const [initialRange] = useState(() => {
|
|
71
|
+
return makeVisibleIndexRanges(numberOfData, windowSize, initialIndex);
|
|
72
|
+
});
|
|
74
73
|
const store = useRef(new SimpleItemVisibilityStore(initialRange)).current;
|
|
75
|
-
|
|
76
|
-
const newRanges = makeVisibleIndexRanges(numberOfData, windowSize,
|
|
74
|
+
const onIndexChange = useCallback(newIndex => {
|
|
75
|
+
const newRanges = makeVisibleIndexRanges(numberOfData, windowSize, newIndex);
|
|
77
76
|
store.dispatch(newRanges);
|
|
78
|
-
}, [
|
|
77
|
+
}, [numberOfData, windowSize]);
|
|
79
78
|
useEffect(() => {
|
|
80
79
|
return () => {
|
|
81
80
|
store.removeAllListeners();
|
|
82
81
|
};
|
|
83
82
|
}, []);
|
|
84
|
-
return store;
|
|
83
|
+
return [store, onIndexChange];
|
|
85
84
|
}
|
|
86
85
|
;
|
|
87
86
|
//# sourceMappingURL=useItemVisibilityStore.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useEffect","useRef","useState","SimpleItemVisibilityStore","constructor","initialValue","store","subscribe","listener","listeners","push","index","indexOf","splice","dispatch","ranges","id","removeAllListeners","length","normalize","windowSize","numberOfData","
|
|
1
|
+
{"version":3,"names":["useCallback","useEffect","useRef","useState","mod","SimpleItemVisibilityStore","constructor","initialValue","store","subscribe","listener","listeners","push","index","indexOf","splice","dispatch","ranges","id","removeAllListeners","length","normalize","windowSize","numberOfData","makeVisibleIndexRanges","ws","firstIndex","lastIndex","halfNumberOfAdjacent","Math","floor","leftSide","rightSide","leftRanges","rightRanges","useItemVisibilityStore","params","initialIndex","initialRange","current","onIndexChange","newIndex","newRanges"],"sources":["useItemVisibilityStore.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\nimport { mod } from '@fountain-ui/utils';\nimport type { ItemVisibilityStore, VisibleIndexRanges } from '../types';\n\nexport interface Parameters {\n initialIndex: number;\n numberOfData: number;\n windowSize: number;\n}\n\nexport interface OnIndexChange {\n (newIndex: number): void;\n}\n\nclass SimpleItemVisibilityStore implements ItemVisibilityStore {\n\n private store: VisibleIndexRanges;\n\n constructor(initialValue: VisibleIndexRanges) {\n this.store = initialValue;\n }\n\n private listeners: Array<(ranges: VisibleIndexRanges) => void> = [];\n\n subscribe(listener: (ranges: VisibleIndexRanges) => void) {\n this.listeners.push(listener);\n\n listener(this.store);\n\n return () => {\n const index = this.listeners.indexOf(listener);\n this.listeners.splice(index, 1);\n };\n }\n\n dispatch(ranges: VisibleIndexRanges): void {\n this.store = ranges;\n for (const id in this.listeners) {\n const listener = this.listeners[id];\n listener?.(ranges);\n }\n }\n\n removeAllListeners(): void {\n this.listeners.splice(0, this.listeners.length);\n }\n\n}\n\nfunction normalize(windowSize: number, numberOfData: number): number {\n if (windowSize <= 0) {\n return numberOfData;\n }\n if (windowSize > 0 && windowSize % 2 === 0) {\n return windowSize + 1;\n }\n return windowSize;\n}\n\nfunction makeVisibleIndexRanges(numberOfData: number, windowSize: number, index: number): VisibleIndexRanges {\n const ws = normalize(windowSize, numberOfData);\n\n const firstIndex = 0;\n const lastIndex = numberOfData - 1;\n const halfNumberOfAdjacent = Math.floor(ws / 2);\n\n const leftSide = index - halfNumberOfAdjacent;\n const rightSide = index + halfNumberOfAdjacent;\n\n const leftRanges = leftSide >= 0\n ? [[leftSide, index]]\n : [[firstIndex, index], [mod(leftSide, numberOfData), lastIndex]];\n\n const rightRanges = rightSide < numberOfData\n ? [[index, rightSide]]\n : [[index, lastIndex], [firstIndex, mod(rightSide, numberOfData)]];\n\n // @ts-ignore\n return [\n ...leftRanges,\n ...rightRanges,\n ];\n}\n\nexport default function useItemVisibilityStore(params: Parameters): [ItemVisibilityStore, OnIndexChange] {\n const {\n initialIndex,\n numberOfData,\n windowSize,\n } = params;\n\n const [initialRange] = useState(() => {\n return makeVisibleIndexRanges(numberOfData, windowSize, initialIndex);\n });\n\n const store = useRef(new SimpleItemVisibilityStore(initialRange)).current;\n\n const onIndexChange: OnIndexChange = useCallback((newIndex) => {\n const newRanges = makeVisibleIndexRanges(numberOfData, windowSize, newIndex);\n\n store.dispatch(newRanges);\n }, [numberOfData, windowSize]);\n\n useEffect(() => {\n return () => {\n store.removeAllListeners();\n };\n }, []);\n\n return [store, onIndexChange];\n};\n"],"mappings":"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"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { useCallback,
|
|
2
|
-
import { Animated, Platform } from 'react-native';
|
|
1
|
+
import { useCallback, useRef } from 'react';
|
|
3
2
|
|
|
4
3
|
function directionToValue(itemWidth) {
|
|
5
4
|
return function (direction) {
|
|
@@ -16,99 +15,153 @@ function directionToValue(itemWidth) {
|
|
|
16
15
|
};
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
function toValueCompensator(itemWidth) {
|
|
19
|
+
return function (toValue, currentOffset) {
|
|
20
|
+
const remainder = Math.abs(currentOffset % itemWidth);
|
|
21
|
+
const halfOfItemWidth = Math.abs(itemWidth / 2);
|
|
22
|
+
const compensateVector = remainder > halfOfItemWidth ? remainder - itemWidth : remainder;
|
|
23
|
+
const direction = currentOffset > 0 ? -1 : 1;
|
|
24
|
+
return toValue + direction * compensateVector;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default function usePagingAnimation(params) {
|
|
20
29
|
const {
|
|
21
|
-
controlledTx,
|
|
22
30
|
createScrollAnimation,
|
|
23
|
-
getCurrentIndex,
|
|
24
31
|
itemWidth,
|
|
25
|
-
|
|
32
|
+
indexController,
|
|
26
33
|
loop,
|
|
27
34
|
numberOfData,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
offsetX,
|
|
36
|
+
translateX
|
|
37
|
+
} = params;
|
|
38
|
+
const {
|
|
39
|
+
getCurrentIndex,
|
|
40
|
+
lastIndex,
|
|
41
|
+
notifyOffsetHasChanged
|
|
42
|
+
} = indexController;
|
|
31
43
|
const toValueRef = useRef(0);
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const maxWidth = numberOfData * itemWidth;
|
|
44
|
+
const currentOffsetRef = useRef(0);
|
|
45
|
+
const isAnimatingRef = useRef(false);
|
|
46
|
+
const maxWidth = Math.abs(numberOfData * itemWidth);
|
|
47
|
+
const ensureOffsetBoundary = useCallback(offset => {
|
|
48
|
+
if (loop) {
|
|
49
|
+
const isCloseToEnd = Math.abs(offset) >= maxWidth - itemWidth;
|
|
39
50
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
51
|
+
if (isCloseToEnd) {
|
|
52
|
+
const signOfOffset = offset > 0 ? 1 : -1;
|
|
53
|
+
return offset + -signOfOffset * maxWidth;
|
|
44
54
|
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return offset % maxWidth;
|
|
58
|
+
}, [itemWidth, loop, maxWidth]);
|
|
59
|
+
const requireNewOffset = useCallback(newOffset => {
|
|
60
|
+
const nextOffset = ensureOffsetBoundary(newOffset);
|
|
61
|
+
currentOffsetRef.current = nextOffset;
|
|
62
|
+
offsetX.setValue(nextOffset);
|
|
63
|
+
toValueRef.current = 0;
|
|
64
|
+
translateX.setValue(0);
|
|
65
|
+
}, [ensureOffsetBoundary, offsetX, translateX]);
|
|
66
|
+
const interruptAnimation = useCallback(() => {
|
|
67
|
+
if (toValueRef.current === 0) {
|
|
68
|
+
// Performance optimization
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
translateX.stopAnimation(lastValue => {
|
|
73
|
+
isAnimatingRef.current = false;
|
|
74
|
+
const prevOffset = currentOffsetRef.current;
|
|
75
|
+
const totalOffset = prevOffset + lastValue;
|
|
76
|
+
notifyOffsetHasChanged(totalOffset);
|
|
77
|
+
requireNewOffset(totalOffset);
|
|
45
78
|
});
|
|
46
|
-
|
|
47
|
-
controlledTx.removeListener(subscriptionId);
|
|
48
|
-
};
|
|
49
|
-
}, [numberOfData, itemWidth]);
|
|
79
|
+
}, [requireNewOffset, translateX]);
|
|
50
80
|
const finalizeAnimation = useCallback(() => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
81
|
+
isAnimatingRef.current = false;
|
|
82
|
+
const prevOffset = currentOffsetRef.current;
|
|
83
|
+
const toValue = toValueRef.current;
|
|
84
|
+
const totalOffset = prevOffset + toValue;
|
|
85
|
+
requireNewOffset(totalOffset);
|
|
86
|
+
}, [requireNewOffset]);
|
|
87
|
+
const startPagingAnimation = useCallback((type, config) => {
|
|
88
|
+
if (isAnimatingRef.current) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
54
91
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
92
|
+
const configWithDefaults = {
|
|
93
|
+
animated: true,
|
|
94
|
+
...config
|
|
58
95
|
};
|
|
96
|
+
const currentIndex = getCurrentIndex();
|
|
97
|
+
const getValueByDirectionOnAllAdjacentItemsVisible = directionToValue(itemWidth);
|
|
98
|
+
const compensateToValue = toValueCompensator(itemWidth);
|
|
59
99
|
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// So setting same value with `value.setValue(value._value)` will trigger event listener.
|
|
100
|
+
const getValueByDirectionalPagingOnLoopDisabled = _config => {
|
|
101
|
+
const {
|
|
102
|
+
direction,
|
|
103
|
+
isOriginatedFromGesture
|
|
104
|
+
} = _config;
|
|
66
105
|
|
|
67
|
-
if (
|
|
68
|
-
//
|
|
69
|
-
|
|
106
|
+
if (currentIndex === 0 && direction === 'prev') {
|
|
107
|
+
return isOriginatedFromGesture ? getValueByDirectionOnAllAdjacentItemsVisible('stay') : -lastIndex * itemWidth; // last position
|
|
108
|
+
} else if (currentIndex === lastIndex && direction === 'next') {
|
|
109
|
+
return isOriginatedFromGesture ? getValueByDirectionOnAllAdjacentItemsVisible('stay') : lastIndex * itemWidth; // first position
|
|
70
110
|
}
|
|
71
111
|
|
|
72
|
-
|
|
73
|
-
toValueRef.current = 0;
|
|
112
|
+
return getValueByDirectionOnAllAdjacentItemsVisible(direction);
|
|
74
113
|
};
|
|
75
114
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
115
|
+
const getValueByDirectionalPaging = _config => {
|
|
116
|
+
const _configWithDefaults = {
|
|
117
|
+
isOriginatedFromGesture: false,
|
|
118
|
+
..._config
|
|
119
|
+
};
|
|
120
|
+
return loop ? getValueByDirectionOnAllAdjacentItemsVisible(_configWithDefaults.direction) : getValueByDirectionalPagingOnLoopDisabled(_configWithDefaults);
|
|
121
|
+
};
|
|
83
122
|
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
123
|
+
const getValueByIndexPaging = _ref => {
|
|
124
|
+
let {
|
|
125
|
+
index
|
|
126
|
+
} = _ref;
|
|
127
|
+
|
|
128
|
+
if (index < 0 || index > lastIndex || index === currentIndex) {
|
|
129
|
+
// no animation if index is invalid or equals to current index
|
|
130
|
+
return 0;
|
|
89
131
|
}
|
|
90
132
|
|
|
91
|
-
|
|
133
|
+
const distance = Math.abs(currentIndex - index) * itemWidth;
|
|
134
|
+
const direction = index > currentIndex ? -1 : 1;
|
|
135
|
+
return distance * direction;
|
|
92
136
|
};
|
|
93
137
|
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
138
|
+
const wantedToValue = type === 'directional' // @ts-ignore
|
|
139
|
+
? getValueByDirectionalPaging(configWithDefaults) // @ts-ignore
|
|
140
|
+
: getValueByIndexPaging(configWithDefaults);
|
|
141
|
+
const toValue = compensateToValue(wantedToValue, currentOffsetRef.current);
|
|
97
142
|
toValueRef.current = toValue;
|
|
98
|
-
|
|
99
|
-
let {
|
|
100
|
-
finished
|
|
101
|
-
} = _ref;
|
|
143
|
+
isAnimatingRef.current = true;
|
|
102
144
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
145
|
+
if (configWithDefaults.animated) {
|
|
146
|
+
const animation = createScrollAnimation(translateX, toValue);
|
|
147
|
+
animation.start(_ref2 => {
|
|
148
|
+
let {
|
|
149
|
+
finished
|
|
150
|
+
} = _ref2;
|
|
151
|
+
|
|
152
|
+
if (finished) {
|
|
153
|
+
finalizeAnimation();
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
} else {
|
|
157
|
+
finalizeAnimation();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
notifyOffsetHasChanged(currentOffsetRef.current + toValue);
|
|
161
|
+
}, [createScrollAnimation, getCurrentIndex, finalizeAnimation, itemWidth, lastIndex, loop, notifyOffsetHasChanged]);
|
|
108
162
|
return {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
startAnimation
|
|
163
|
+
interruptAnimation,
|
|
164
|
+
startPagingAnimation
|
|
112
165
|
};
|
|
113
166
|
}
|
|
114
167
|
;
|