@fountain-ui/lab 2.0.0-beta.15 → 2.0.0-beta.16
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/animation/createDefaultScrollAnimation.js +2 -2
- package/build/commonjs/Carousel/animation/createDefaultScrollAnimation.js.map +1 -1
- package/build/commonjs/Carousel/hooks/useIndexController.js +11 -2
- package/build/commonjs/Carousel/hooks/useIndexController.js.map +1 -1
- package/build/commonjs/Carousel/hooks/usePagingAnimation.js +8 -6
- package/build/commonjs/Carousel/hooks/usePagingAnimation.js.map +1 -1
- package/build/commonjs/Carousel/types.js +1 -0
- package/build/commonjs/Carousel/types.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/hooks/useIndexController.js +11 -2
- package/build/module/Carousel/hooks/useIndexController.js.map +1 -1
- package/build/module/Carousel/hooks/usePagingAnimation.js +8 -6
- package/build/module/Carousel/hooks/usePagingAnimation.js.map +1 -1
- package/build/module/Carousel/types.js +1 -0
- package/build/module/Carousel/types.js.map +1 -1
- package/build/typescript/Carousel/types.d.ts +3 -0
- package/package.json +2 -2
- package/src/Carousel/animation/createDefaultScrollAnimation.ts +2 -2
- package/src/Carousel/hooks/useIndexController.tsx +16 -8
- package/src/Carousel/hooks/usePagingAnimation.ts +14 -5
- package/src/Carousel/types.ts +5 -0
|
@@ -10,8 +10,8 @@ var _reactNative = require("react-native");
|
|
|
10
10
|
function createDefaultScrollAnimation(animatedValue, toValue) {
|
|
11
11
|
return _reactNative.Animated.timing(animatedValue, {
|
|
12
12
|
toValue: toValue,
|
|
13
|
-
duration:
|
|
14
|
-
easing: _reactNative.Easing.bezier(0.
|
|
13
|
+
duration: 180,
|
|
14
|
+
easing: _reactNative.Easing.bezier(0.2, 0.2, 0.2, 1),
|
|
15
15
|
useNativeDriver: true
|
|
16
16
|
});
|
|
17
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["createDefaultScrollAnimation","animatedValue","toValue","Animated","timing","duration","easing","Easing","bezier","useNativeDriver"],"sources":["createDefaultScrollAnimation.ts"],"sourcesContent":["import { Animated, Easing } from 'react-native';\n\nexport default function createDefaultScrollAnimation(\n animatedValue: Animated.Value,\n toValue: number,\n): Animated.CompositeAnimation {\n return Animated.timing(animatedValue, {\n toValue: toValue,\n duration:
|
|
1
|
+
{"version":3,"names":["createDefaultScrollAnimation","animatedValue","toValue","Animated","timing","duration","easing","Easing","bezier","useNativeDriver"],"sources":["createDefaultScrollAnimation.ts"],"sourcesContent":["import { Animated, Easing } from 'react-native';\n\nexport default function createDefaultScrollAnimation(\n animatedValue: Animated.Value,\n toValue: number,\n): Animated.CompositeAnimation {\n return Animated.timing(animatedValue, {\n toValue: toValue,\n duration: 180,\n easing: Easing.bezier(0.2, 0.2, 0.2, 1),\n useNativeDriver: true,\n });\n};\n"],"mappings":";;;;;;;AAAA;;AAEe,SAASA,4BAAT,CACXC,aADW,EAEXC,OAFW,EAGgB;EAC3B,OAAOC,qBAAA,CAASC,MAAT,CAAgBH,aAAhB,EAA+B;IAClCC,OAAO,EAAEA,OADyB;IAElCG,QAAQ,EAAE,GAFwB;IAGlCC,MAAM,EAAEC,mBAAA,CAAOC,MAAP,CAAc,GAAd,EAAmB,GAAnB,EAAwB,GAAxB,EAA6B,CAA7B,CAH0B;IAIlCC,eAAe,EAAE;EAJiB,CAA/B,CAAP;AAMH;;AAAA"}
|
|
@@ -17,7 +17,15 @@ function useIndexController(params) {
|
|
|
17
17
|
onIndexChange
|
|
18
18
|
} = params;
|
|
19
19
|
const currentIndexRef = (0, _react.useRef)(initialIndex);
|
|
20
|
+
const indexChangedRef = (0, _react.useRef)(false);
|
|
20
21
|
const getCurrentIndex = (0, _react.useCallback)(() => currentIndexRef.current, []);
|
|
22
|
+
const notifyAnimationState = (0, _react.useCallback)(state => {
|
|
23
|
+
if (state === 'finished' || state === 'interrupted') {
|
|
24
|
+
if (indexChangedRef.current) {
|
|
25
|
+
onIndexChange === null || onIndexChange === void 0 ? void 0 : onIndexChange(getCurrentIndex());
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}, [getCurrentIndex, onIndexChange]);
|
|
21
29
|
const notifyOffsetHasChanged = (0, _react.useCallback)(offset => {
|
|
22
30
|
const roundedOffset = Math.round(offset / itemWidth) * itemWidth; // To prevent floating point problem, make sure index is integer type.
|
|
23
31
|
|
|
@@ -25,12 +33,13 @@ function useIndexController(params) {
|
|
|
25
33
|
|
|
26
34
|
if (nextIndex !== currentIndexRef.current) {
|
|
27
35
|
currentIndexRef.current = nextIndex;
|
|
28
|
-
|
|
36
|
+
indexChangedRef.current = true;
|
|
29
37
|
}
|
|
30
|
-
}, [itemWidth, numberOfOriginalData
|
|
38
|
+
}, [itemWidth, numberOfOriginalData]);
|
|
31
39
|
return {
|
|
32
40
|
getCurrentIndex,
|
|
33
41
|
lastIndex: numberOfOriginalData - 1,
|
|
42
|
+
notifyAnimationState,
|
|
34
43
|
notifyOffsetHasChanged
|
|
35
44
|
};
|
|
36
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useIndexController","params","initialIndex","itemWidth","numberOfOriginalData","onIndexChange","currentIndexRef","useRef","getCurrentIndex","useCallback","current","notifyOffsetHasChanged","offset","roundedOffset","Math","round","nextIndex","floor","mod","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
|
|
1
|
+
{"version":3,"names":["useIndexController","params","initialIndex","itemWidth","numberOfOriginalData","onIndexChange","currentIndexRef","useRef","indexChangedRef","getCurrentIndex","useCallback","current","notifyAnimationState","state","notifyOffsetHasChanged","offset","roundedOffset","Math","round","nextIndex","floor","mod","lastIndex"],"sources":["useIndexController.tsx"],"sourcesContent":["import React, { useCallback, useRef } from 'react';\nimport { mod } from '@fountain-ui/utils';\nimport type { AnimationState, 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 const indexChangedRef = useRef<boolean>(false);\n\n const getCurrentIndex = useCallback(() => currentIndexRef.current, []);\n\n const notifyAnimationState = useCallback((state: AnimationState) => {\n if (state === 'finished' || state === 'interrupted') {\n if (indexChangedRef.current) {\n onIndexChange?.(getCurrentIndex());\n }\n }\n }, [\n getCurrentIndex,\n onIndexChange,\n ]);\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 indexChangedRef.current = true;\n }\n }, [itemWidth, numberOfOriginalData]);\n\n return {\n getCurrentIndex,\n lastIndex: numberOfOriginalData - 1,\n notifyAnimationState,\n notifyOffsetHasChanged,\n };\n};\n"],"mappings":";;;;;;;AAAA;;AACA;;AAUe,SAASA,kBAAT,CAA4BC,MAA5B,EAAmF;EAC9F,MAAM;IACFC,YADE;IAEFC,SAFE;IAGFC,oBAHE;IAIFC;EAJE,IAKFJ,MALJ;EAOA,MAAMK,eAAe,GAAG,IAAAC,aAAA,EAAeL,YAAf,CAAxB;EACA,MAAMM,eAAe,GAAG,IAAAD,aAAA,EAAgB,KAAhB,CAAxB;EAEA,MAAME,eAAe,GAAG,IAAAC,kBAAA,EAAY,MAAMJ,eAAe,CAACK,OAAlC,EAA2C,EAA3C,CAAxB;EAEA,MAAMC,oBAAoB,GAAG,IAAAF,kBAAA,EAAaG,KAAD,IAA2B;IAChE,IAAIA,KAAK,KAAK,UAAV,IAAwBA,KAAK,KAAK,aAAtC,EAAqD;MACjD,IAAIL,eAAe,CAACG,OAApB,EAA6B;QACzBN,aAAa,SAAb,IAAAA,aAAa,WAAb,YAAAA,aAAa,CAAGI,eAAe,EAAlB,CAAb;MACH;IACJ;EACJ,CAN4B,EAM1B,CACCA,eADD,EAECJ,aAFD,CAN0B,CAA7B;EAWA,MAAMS,sBAAsB,GAAG,IAAAJ,kBAAA,EAAaK,MAAD,IAAoB;IAC3D,MAAMC,aAAa,GAAGC,IAAI,CAACC,KAAL,CAAWH,MAAM,GAAGZ,SAApB,IAAiCA,SAAvD,CAD2D,CAG3D;;IACA,MAAMgB,SAAS,GAAGF,IAAI,CAACG,KAAL,CAAW,IAAAC,UAAA,EAAK,CAACL,aAAD,GAAiBb,SAAtB,EAAkCC,oBAAlC,CAAX,CAAlB;;IAEA,IAAIe,SAAS,KAAKb,eAAe,CAACK,OAAlC,EAA2C;MACvCL,eAAe,CAACK,OAAhB,GAA0BQ,SAA1B;MACAX,eAAe,CAACG,OAAhB,GAA0B,IAA1B;IACH;EACJ,CAV8B,EAU5B,CAACR,SAAD,EAAYC,oBAAZ,CAV4B,CAA/B;EAYA,OAAO;IACHK,eADG;IAEHa,SAAS,EAAElB,oBAAoB,GAAG,CAF/B;IAGHQ,oBAHG;IAIHE;EAJG,CAAP;AAMH;;AAAA"}
|
|
@@ -45,6 +45,7 @@ function usePagingAnimation(params) {
|
|
|
45
45
|
const {
|
|
46
46
|
getCurrentIndex,
|
|
47
47
|
lastIndex,
|
|
48
|
+
notifyAnimationState,
|
|
48
49
|
notifyOffsetHasChanged
|
|
49
50
|
} = indexController;
|
|
50
51
|
const toValueRef = (0, _react.useRef)(0);
|
|
@@ -71,8 +72,7 @@ function usePagingAnimation(params) {
|
|
|
71
72
|
translateX.setValue(0);
|
|
72
73
|
}, [ensureOffsetBoundary, offsetX, translateX]);
|
|
73
74
|
const interruptAnimation = (0, _react.useCallback)(() => {
|
|
74
|
-
if (
|
|
75
|
-
// Performance optimization
|
|
75
|
+
if (!isAnimatingRef.current) {
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
78
78
|
|
|
@@ -81,16 +81,18 @@ function usePagingAnimation(params) {
|
|
|
81
81
|
const prevOffset = currentOffsetRef.current;
|
|
82
82
|
const totalOffset = prevOffset + lastValue;
|
|
83
83
|
notifyOffsetHasChanged(totalOffset);
|
|
84
|
+
notifyAnimationState('interrupted');
|
|
84
85
|
requireNewOffset(totalOffset);
|
|
85
86
|
});
|
|
86
87
|
}, [requireNewOffset, translateX]);
|
|
87
88
|
const finalizeAnimation = (0, _react.useCallback)(() => {
|
|
89
|
+
notifyAnimationState('finished');
|
|
88
90
|
isAnimatingRef.current = false;
|
|
89
91
|
const prevOffset = currentOffsetRef.current;
|
|
90
92
|
const toValue = toValueRef.current;
|
|
91
93
|
const totalOffset = prevOffset + toValue;
|
|
92
94
|
requireNewOffset(totalOffset);
|
|
93
|
-
}, [requireNewOffset]);
|
|
95
|
+
}, [notifyAnimationState, requireNewOffset]);
|
|
94
96
|
const startPagingAnimation = (0, _react.useCallback)((type, config) => {
|
|
95
97
|
if (isAnimatingRef.current) {
|
|
96
98
|
return;
|
|
@@ -148,6 +150,7 @@ function usePagingAnimation(params) {
|
|
|
148
150
|
const toValue = compensateToValue(wantedToValue, currentOffsetRef.current);
|
|
149
151
|
toValueRef.current = toValue;
|
|
150
152
|
isAnimatingRef.current = true;
|
|
153
|
+
notifyOffsetHasChanged(currentOffsetRef.current + toValue);
|
|
151
154
|
|
|
152
155
|
if (configWithDefaults.animated) {
|
|
153
156
|
const animation = createScrollAnimation(translateX, toValue);
|
|
@@ -160,12 +163,11 @@ function usePagingAnimation(params) {
|
|
|
160
163
|
finalizeAnimation();
|
|
161
164
|
}
|
|
162
165
|
});
|
|
166
|
+
notifyAnimationState('started');
|
|
163
167
|
} else {
|
|
164
168
|
finalizeAnimation();
|
|
165
169
|
}
|
|
166
|
-
|
|
167
|
-
notifyOffsetHasChanged(currentOffsetRef.current + toValue);
|
|
168
|
-
}, [createScrollAnimation, getCurrentIndex, finalizeAnimation, itemWidth, lastIndex, loop, notifyOffsetHasChanged]);
|
|
170
|
+
}, [createScrollAnimation, getCurrentIndex, finalizeAnimation, itemWidth, lastIndex, loop, notifyAnimationState, notifyOffsetHasChanged]);
|
|
169
171
|
return {
|
|
170
172
|
interruptAnimation,
|
|
171
173
|
startPagingAnimation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["directionToValue","itemWidth","direction","toValueCompensator","toValue","currentOffset","remainder","Math","abs","halfOfItemWidth","compensateVector","usePagingAnimation","params","createScrollAnimation","indexController","loop","numberOfData","offsetX","translateX","getCurrentIndex","lastIndex","notifyOffsetHasChanged","toValueRef","useRef","currentOffsetRef","isAnimatingRef","maxWidth","ensureOffsetBoundary","useCallback","offset","isCloseToEnd","signOfOffset","requireNewOffset","newOffset","nextOffset","current","setValue","interruptAnimation","stopAnimation","lastValue","prevOffset","totalOffset","finalizeAnimation","startPagingAnimation","type","config","configWithDefaults","animated","currentIndex","getValueByDirectionOnAllAdjacentItemsVisible","compensateToValue","getValueByDirectionalPagingOnLoopDisabled","_config","isOriginatedFromGesture","getValueByDirectionalPaging","_configWithDefaults","getValueByIndexPaging","index","distance","wantedToValue","animation","start","finished"],"sources":["usePagingAnimation.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { Animated } from 'react-native';\nimport type {\n CreateScrollAnimation,\n DirectionalPagingAnimationConfig,\n IndexController,\n IndexPagingAnimationConfig,\n PagingAnimationConfig,\n PagingAnimationType,\n PagingDirection,\n StartPagingAnimation,\n} from '../types';\n\nexport interface PagingAnimationParameters {\n createScrollAnimation: CreateScrollAnimation;\n itemWidth: number;\n indexController: IndexController;\n loop: boolean;\n numberOfData: number;\n offsetX: Animated.Value;\n translateX: Animated.Value;\n}\n\nexport interface UsePagingAnimation {\n interruptAnimation: () => void;\n startPagingAnimation: StartPagingAnimation;\n}\n\nfunction directionToValue(itemWidth: number) {\n return function (direction: PagingDirection): number {\n switch (direction) {\n case 'next':\n return -itemWidth;\n case 'prev':\n return itemWidth;\n case 'stay':\n return 0;\n }\n };\n}\n\nfunction toValueCompensator(itemWidth: number) {\n return function (toValue: number, currentOffset: number): number {\n const remainder = Math.abs(currentOffset % itemWidth);\n\n const halfOfItemWidth = Math.abs(itemWidth / 2);\n const compensateVector = remainder > halfOfItemWidth\n ? remainder - itemWidth\n : remainder;\n\n const direction = currentOffset > 0 ? -1 : 1;\n\n return toValue + (direction * compensateVector);\n };\n}\n\nexport default function usePagingAnimation(params: PagingAnimationParameters): UsePagingAnimation {\n const {\n createScrollAnimation,\n itemWidth,\n indexController,\n loop,\n numberOfData,\n offsetX,\n translateX,\n } = params;\n\n const {\n getCurrentIndex,\n lastIndex,\n notifyOffsetHasChanged,\n } = indexController;\n\n const toValueRef = useRef<number>(0);\n const currentOffsetRef = useRef<number>(0);\n\n const isAnimatingRef = useRef<boolean>(false);\n\n const maxWidth = Math.abs(numberOfData * itemWidth);\n\n const ensureOffsetBoundary: (offset: number) => number = useCallback((offset: number) => {\n if (loop) {\n const isCloseToEnd = Math.abs(offset) >= (maxWidth - itemWidth);\n if (isCloseToEnd) {\n const signOfOffset = offset > 0 ? 1 : -1;\n return offset + (-signOfOffset * maxWidth);\n }\n }\n\n return offset % maxWidth;\n }, [itemWidth, loop, maxWidth]);\n\n const requireNewOffset = useCallback((newOffset: number) => {\n const nextOffset = ensureOffsetBoundary(newOffset);\n\n currentOffsetRef.current = nextOffset;\n offsetX.setValue(nextOffset);\n\n toValueRef.current = 0;\n translateX.setValue(0);\n }, [\n ensureOffsetBoundary,\n offsetX,\n translateX,\n ]);\n\n const interruptAnimation = useCallback(() => {\n if (toValueRef.current === 0) {\n // Performance optimization\n return;\n }\n\n translateX.stopAnimation(lastValue => {\n isAnimatingRef.current = false;\n\n const prevOffset = currentOffsetRef.current;\n const totalOffset = prevOffset + lastValue;\n\n notifyOffsetHasChanged(totalOffset);\n\n requireNewOffset(totalOffset);\n });\n }, [requireNewOffset, translateX]);\n\n const finalizeAnimation = useCallback(() => {\n isAnimatingRef.current = false;\n\n const prevOffset = currentOffsetRef.current;\n const toValue = toValueRef.current;\n const totalOffset = prevOffset + toValue;\n\n requireNewOffset(totalOffset);\n }, [requireNewOffset]);\n\n const startPagingAnimation = useCallback((type: PagingAnimationType, config: PagingAnimationConfig) => {\n if (isAnimatingRef.current) {\n return;\n }\n\n const configWithDefaults: PagingAnimationConfig = {\n animated: true,\n ...config,\n };\n\n const currentIndex = getCurrentIndex();\n\n const getValueByDirectionOnAllAdjacentItemsVisible = directionToValue(itemWidth);\n const compensateToValue = toValueCompensator(itemWidth);\n\n const getValueByDirectionalPagingOnLoopDisabled = (_config: DirectionalPagingAnimationConfig): number => {\n const { direction, isOriginatedFromGesture } = _config;\n\n if (currentIndex === 0 && direction === 'prev') {\n return isOriginatedFromGesture\n ? getValueByDirectionOnAllAdjacentItemsVisible('stay')\n : -lastIndex * itemWidth; // last position\n } else if (currentIndex === lastIndex && direction === 'next') {\n return isOriginatedFromGesture\n ? getValueByDirectionOnAllAdjacentItemsVisible('stay')\n : lastIndex * itemWidth; // first position\n }\n return getValueByDirectionOnAllAdjacentItemsVisible(direction);\n };\n\n const getValueByDirectionalPaging = (_config: DirectionalPagingAnimationConfig): number => {\n const _configWithDefaults: DirectionalPagingAnimationConfig = {\n isOriginatedFromGesture: false,\n ..._config,\n };\n\n return loop\n ? getValueByDirectionOnAllAdjacentItemsVisible(_configWithDefaults.direction)\n : getValueByDirectionalPagingOnLoopDisabled(_configWithDefaults);\n };\n\n const getValueByIndexPaging = ({ index }: IndexPagingAnimationConfig): number => {\n if (index < 0 || index > lastIndex || index === currentIndex) {\n // no animation if index is invalid or equals to current index\n return 0;\n }\n\n const distance = Math.abs(currentIndex - index) * itemWidth;\n const direction = index > currentIndex ? -1 : 1;\n\n return distance * direction;\n };\n\n const wantedToValue = type === 'directional'\n // @ts-ignore\n ? getValueByDirectionalPaging(configWithDefaults)\n // @ts-ignore\n : getValueByIndexPaging(configWithDefaults);\n\n const toValue = compensateToValue(wantedToValue, currentOffsetRef.current);\n\n toValueRef.current = toValue;\n isAnimatingRef.current = true;\n\n if (configWithDefaults.animated) {\n const animation = createScrollAnimation(translateX, toValue);\n\n animation.start(({ finished }) => {\n if (finished) {\n finalizeAnimation();\n }\n });\n } else {\n finalizeAnimation();\n }\n\n notifyOffsetHasChanged(currentOffsetRef.current + toValue);\n }, [\n createScrollAnimation,\n getCurrentIndex,\n finalizeAnimation,\n itemWidth,\n lastIndex,\n loop,\n notifyOffsetHasChanged,\n ]);\n\n return {\n interruptAnimation,\n startPagingAnimation,\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["directionToValue","itemWidth","direction","toValueCompensator","toValue","currentOffset","remainder","Math","abs","halfOfItemWidth","compensateVector","usePagingAnimation","params","createScrollAnimation","indexController","loop","numberOfData","offsetX","translateX","getCurrentIndex","lastIndex","notifyAnimationState","notifyOffsetHasChanged","toValueRef","useRef","currentOffsetRef","isAnimatingRef","maxWidth","ensureOffsetBoundary","useCallback","offset","isCloseToEnd","signOfOffset","requireNewOffset","newOffset","nextOffset","current","setValue","interruptAnimation","stopAnimation","lastValue","prevOffset","totalOffset","finalizeAnimation","startPagingAnimation","type","config","configWithDefaults","animated","currentIndex","getValueByDirectionOnAllAdjacentItemsVisible","compensateToValue","getValueByDirectionalPagingOnLoopDisabled","_config","isOriginatedFromGesture","getValueByDirectionalPaging","_configWithDefaults","getValueByIndexPaging","index","distance","wantedToValue","animation","start","finished"],"sources":["usePagingAnimation.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { Animated } from 'react-native';\nimport type {\n CreateScrollAnimation,\n DirectionalPagingAnimationConfig,\n IndexController,\n IndexPagingAnimationConfig,\n PagingAnimationConfig,\n PagingAnimationType,\n PagingDirection,\n StartPagingAnimation,\n} from '../types';\n\nexport interface PagingAnimationParameters {\n createScrollAnimation: CreateScrollAnimation;\n itemWidth: number;\n indexController: IndexController;\n loop: boolean;\n numberOfData: number;\n offsetX: Animated.Value;\n translateX: Animated.Value;\n}\n\nexport interface UsePagingAnimation {\n interruptAnimation: () => void;\n startPagingAnimation: StartPagingAnimation;\n}\n\nfunction directionToValue(itemWidth: number) {\n return function (direction: PagingDirection): number {\n switch (direction) {\n case 'next':\n return -itemWidth;\n case 'prev':\n return itemWidth;\n case 'stay':\n return 0;\n }\n };\n}\n\nfunction toValueCompensator(itemWidth: number) {\n return function (toValue: number, currentOffset: number): number {\n const remainder = Math.abs(currentOffset % itemWidth);\n\n const halfOfItemWidth = Math.abs(itemWidth / 2);\n const compensateVector = remainder > halfOfItemWidth\n ? remainder - itemWidth\n : remainder;\n\n const direction = currentOffset > 0 ? -1 : 1;\n\n return toValue + (direction * compensateVector);\n };\n}\n\nexport default function usePagingAnimation(params: PagingAnimationParameters): UsePagingAnimation {\n const {\n createScrollAnimation,\n itemWidth,\n indexController,\n loop,\n numberOfData,\n offsetX,\n translateX,\n } = params;\n\n const {\n getCurrentIndex,\n lastIndex,\n notifyAnimationState,\n notifyOffsetHasChanged,\n } = indexController;\n\n const toValueRef = useRef<number>(0);\n const currentOffsetRef = useRef<number>(0);\n\n const isAnimatingRef = useRef<boolean>(false);\n\n const maxWidth = Math.abs(numberOfData * itemWidth);\n\n const ensureOffsetBoundary: (offset: number) => number = useCallback((offset: number) => {\n if (loop) {\n const isCloseToEnd = Math.abs(offset) >= (maxWidth - itemWidth);\n if (isCloseToEnd) {\n const signOfOffset = offset > 0 ? 1 : -1;\n return offset + (-signOfOffset * maxWidth);\n }\n }\n\n return offset % maxWidth;\n }, [itemWidth, loop, maxWidth]);\n\n const requireNewOffset = useCallback((newOffset: number) => {\n const nextOffset = ensureOffsetBoundary(newOffset);\n\n currentOffsetRef.current = nextOffset;\n offsetX.setValue(nextOffset);\n\n toValueRef.current = 0;\n translateX.setValue(0);\n }, [\n ensureOffsetBoundary,\n offsetX,\n translateX,\n ]);\n\n const interruptAnimation = useCallback(() => {\n if (!isAnimatingRef.current) {\n return;\n }\n\n translateX.stopAnimation(lastValue => {\n isAnimatingRef.current = false;\n\n const prevOffset = currentOffsetRef.current;\n const totalOffset = prevOffset + lastValue;\n\n notifyOffsetHasChanged(totalOffset);\n notifyAnimationState('interrupted');\n\n requireNewOffset(totalOffset);\n });\n }, [requireNewOffset, translateX]);\n\n const finalizeAnimation = useCallback(() => {\n notifyAnimationState('finished');\n\n isAnimatingRef.current = false;\n\n const prevOffset = currentOffsetRef.current;\n const toValue = toValueRef.current;\n const totalOffset = prevOffset + toValue;\n\n requireNewOffset(totalOffset);\n }, [\n notifyAnimationState,\n requireNewOffset,\n ]);\n\n const startPagingAnimation = useCallback((type: PagingAnimationType, config: PagingAnimationConfig) => {\n if (isAnimatingRef.current) {\n return;\n }\n\n const configWithDefaults: PagingAnimationConfig = {\n animated: true,\n ...config,\n };\n\n const currentIndex = getCurrentIndex();\n\n const getValueByDirectionOnAllAdjacentItemsVisible = directionToValue(itemWidth);\n const compensateToValue = toValueCompensator(itemWidth);\n\n const getValueByDirectionalPagingOnLoopDisabled = (_config: DirectionalPagingAnimationConfig): number => {\n const { direction, isOriginatedFromGesture } = _config;\n\n if (currentIndex === 0 && direction === 'prev') {\n return isOriginatedFromGesture\n ? getValueByDirectionOnAllAdjacentItemsVisible('stay')\n : -lastIndex * itemWidth; // last position\n } else if (currentIndex === lastIndex && direction === 'next') {\n return isOriginatedFromGesture\n ? getValueByDirectionOnAllAdjacentItemsVisible('stay')\n : lastIndex * itemWidth; // first position\n }\n return getValueByDirectionOnAllAdjacentItemsVisible(direction);\n };\n\n const getValueByDirectionalPaging = (_config: DirectionalPagingAnimationConfig): number => {\n const _configWithDefaults: DirectionalPagingAnimationConfig = {\n isOriginatedFromGesture: false,\n ..._config,\n };\n\n return loop\n ? getValueByDirectionOnAllAdjacentItemsVisible(_configWithDefaults.direction)\n : getValueByDirectionalPagingOnLoopDisabled(_configWithDefaults);\n };\n\n const getValueByIndexPaging = ({ index }: IndexPagingAnimationConfig): number => {\n if (index < 0 || index > lastIndex || index === currentIndex) {\n // no animation if index is invalid or equals to current index\n return 0;\n }\n\n const distance = Math.abs(currentIndex - index) * itemWidth;\n const direction = index > currentIndex ? -1 : 1;\n\n return distance * direction;\n };\n\n const wantedToValue = type === 'directional'\n // @ts-ignore\n ? getValueByDirectionalPaging(configWithDefaults)\n // @ts-ignore\n : getValueByIndexPaging(configWithDefaults);\n\n const toValue = compensateToValue(wantedToValue, currentOffsetRef.current);\n\n toValueRef.current = toValue;\n isAnimatingRef.current = true;\n\n notifyOffsetHasChanged(currentOffsetRef.current + toValue);\n\n if (configWithDefaults.animated) {\n const animation = createScrollAnimation(translateX, toValue);\n\n animation.start(({ finished }) => {\n if (finished) {\n finalizeAnimation();\n }\n });\n\n notifyAnimationState('started');\n } else {\n finalizeAnimation();\n }\n }, [\n createScrollAnimation,\n getCurrentIndex,\n finalizeAnimation,\n itemWidth,\n lastIndex,\n loop,\n notifyAnimationState,\n notifyOffsetHasChanged,\n ]);\n\n return {\n interruptAnimation,\n startPagingAnimation,\n };\n};\n"],"mappings":";;;;;;;AAAA;;AA4BA,SAASA,gBAAT,CAA0BC,SAA1B,EAA6C;EACzC,OAAO,UAAUC,SAAV,EAA8C;IACjD,QAAQA,SAAR;MACI,KAAK,MAAL;QACI,OAAO,CAACD,SAAR;;MACJ,KAAK,MAAL;QACI,OAAOA,SAAP;;MACJ,KAAK,MAAL;QACI,OAAO,CAAP;IANR;EAQH,CATD;AAUH;;AAED,SAASE,kBAAT,CAA4BF,SAA5B,EAA+C;EAC3C,OAAO,UAAUG,OAAV,EAA2BC,aAA3B,EAA0D;IAC7D,MAAMC,SAAS,GAAGC,IAAI,CAACC,GAAL,CAASH,aAAa,GAAGJ,SAAzB,CAAlB;IAEA,MAAMQ,eAAe,GAAGF,IAAI,CAACC,GAAL,CAASP,SAAS,GAAG,CAArB,CAAxB;IACA,MAAMS,gBAAgB,GAAGJ,SAAS,GAAGG,eAAZ,GACnBH,SAAS,GAAGL,SADO,GAEnBK,SAFN;IAIA,MAAMJ,SAAS,GAAGG,aAAa,GAAG,CAAhB,GAAoB,CAAC,CAArB,GAAyB,CAA3C;IAEA,OAAOD,OAAO,GAAIF,SAAS,GAAGQ,gBAA9B;EACH,CAXD;AAYH;;AAEc,SAASC,kBAAT,CAA4BC,MAA5B,EAAmF;EAC9F,MAAM;IACFC,qBADE;IAEFZ,SAFE;IAGFa,eAHE;IAIFC,IAJE;IAKFC,YALE;IAMFC,OANE;IAOFC;EAPE,IAQFN,MARJ;EAUA,MAAM;IACFO,eADE;IAEFC,SAFE;IAGFC,oBAHE;IAIFC;EAJE,IAKFR,eALJ;EAOA,MAAMS,UAAU,GAAG,IAAAC,aAAA,EAAe,CAAf,CAAnB;EACA,MAAMC,gBAAgB,GAAG,IAAAD,aAAA,EAAe,CAAf,CAAzB;EAEA,MAAME,cAAc,GAAG,IAAAF,aAAA,EAAgB,KAAhB,CAAvB;EAEA,MAAMG,QAAQ,GAAGpB,IAAI,CAACC,GAAL,CAASQ,YAAY,GAAGf,SAAxB,CAAjB;EAEA,MAAM2B,oBAAgD,GAAG,IAAAC,kBAAA,EAAaC,MAAD,IAAoB;IACrF,IAAIf,IAAJ,EAAU;MACN,MAAMgB,YAAY,GAAGxB,IAAI,CAACC,GAAL,CAASsB,MAAT,KAAqBH,QAAQ,GAAG1B,SAArD;;MACA,IAAI8B,YAAJ,EAAkB;QACd,MAAMC,YAAY,GAAGF,MAAM,GAAG,CAAT,GAAa,CAAb,GAAiB,CAAC,CAAvC;QACA,OAAOA,MAAM,GAAI,CAACE,YAAD,GAAgBL,QAAjC;MACH;IACJ;;IAED,OAAOG,MAAM,GAAGH,QAAhB;EACH,CAVwD,EAUtD,CAAC1B,SAAD,EAAYc,IAAZ,EAAkBY,QAAlB,CAVsD,CAAzD;EAYA,MAAMM,gBAAgB,GAAG,IAAAJ,kBAAA,EAAaK,SAAD,IAAuB;IACxD,MAAMC,UAAU,GAAGP,oBAAoB,CAACM,SAAD,CAAvC;IAEAT,gBAAgB,CAACW,OAAjB,GAA2BD,UAA3B;IACAlB,OAAO,CAACoB,QAAR,CAAiBF,UAAjB;IAEAZ,UAAU,CAACa,OAAX,GAAqB,CAArB;IACAlB,UAAU,CAACmB,QAAX,CAAoB,CAApB;EACH,CARwB,EAQtB,CACCT,oBADD,EAECX,OAFD,EAGCC,UAHD,CARsB,CAAzB;EAcA,MAAMoB,kBAAkB,GAAG,IAAAT,kBAAA,EAAY,MAAM;IACzC,IAAI,CAACH,cAAc,CAACU,OAApB,EAA6B;MACzB;IACH;;IAEDlB,UAAU,CAACqB,aAAX,CAAyBC,SAAS,IAAI;MAClCd,cAAc,CAACU,OAAf,GAAyB,KAAzB;MAEA,MAAMK,UAAU,GAAGhB,gBAAgB,CAACW,OAApC;MACA,MAAMM,WAAW,GAAGD,UAAU,GAAGD,SAAjC;MAEAlB,sBAAsB,CAACoB,WAAD,CAAtB;MACArB,oBAAoB,CAAC,aAAD,CAApB;MAEAY,gBAAgB,CAACS,WAAD,CAAhB;IACH,CAVD;EAWH,CAhB0B,EAgBxB,CAACT,gBAAD,EAAmBf,UAAnB,CAhBwB,CAA3B;EAkBA,MAAMyB,iBAAiB,GAAG,IAAAd,kBAAA,EAAY,MAAM;IACxCR,oBAAoB,CAAC,UAAD,CAApB;IAEAK,cAAc,CAACU,OAAf,GAAyB,KAAzB;IAEA,MAAMK,UAAU,GAAGhB,gBAAgB,CAACW,OAApC;IACA,MAAMhC,OAAO,GAAGmB,UAAU,CAACa,OAA3B;IACA,MAAMM,WAAW,GAAGD,UAAU,GAAGrC,OAAjC;IAEA6B,gBAAgB,CAACS,WAAD,CAAhB;EACH,CAVyB,EAUvB,CACCrB,oBADD,EAECY,gBAFD,CAVuB,CAA1B;EAeA,MAAMW,oBAAoB,GAAG,IAAAf,kBAAA,EAAY,CAACgB,IAAD,EAA4BC,MAA5B,KAA8D;IACnG,IAAIpB,cAAc,CAACU,OAAnB,EAA4B;MACxB;IACH;;IAED,MAAMW,kBAAyC,GAAG;MAC9CC,QAAQ,EAAE,IADoC;MAE9C,GAAGF;IAF2C,CAAlD;IAKA,MAAMG,YAAY,GAAG9B,eAAe,EAApC;IAEA,MAAM+B,4CAA4C,GAAGlD,gBAAgB,CAACC,SAAD,CAArE;IACA,MAAMkD,iBAAiB,GAAGhD,kBAAkB,CAACF,SAAD,CAA5C;;IAEA,MAAMmD,yCAAyC,GAAIC,OAAD,IAAuD;MACrG,MAAM;QAAEnD,SAAF;QAAaoD;MAAb,IAAyCD,OAA/C;;MAEA,IAAIJ,YAAY,KAAK,CAAjB,IAAsB/C,SAAS,KAAK,MAAxC,EAAgD;QAC5C,OAAOoD,uBAAuB,GACxBJ,4CAA4C,CAAC,MAAD,CADpB,GAExB,CAAC9B,SAAD,GAAanB,SAFnB,CAD4C,CAGd;MACjC,CAJD,MAIO,IAAIgD,YAAY,KAAK7B,SAAjB,IAA8BlB,SAAS,KAAK,MAAhD,EAAwD;QAC3D,OAAOoD,uBAAuB,GACxBJ,4CAA4C,CAAC,MAAD,CADpB,GAExB9B,SAAS,GAAGnB,SAFlB,CAD2D,CAG9B;MAChC;;MACD,OAAOiD,4CAA4C,CAAChD,SAAD,CAAnD;IACH,CAbD;;IAeA,MAAMqD,2BAA2B,GAAIF,OAAD,IAAuD;MACvF,MAAMG,mBAAqD,GAAG;QAC1DF,uBAAuB,EAAE,KADiC;QAE1D,GAAGD;MAFuD,CAA9D;MAKA,OAAOtC,IAAI,GACLmC,4CAA4C,CAACM,mBAAmB,CAACtD,SAArB,CADvC,GAELkD,yCAAyC,CAACI,mBAAD,CAF/C;IAGH,CATD;;IAWA,MAAMC,qBAAqB,GAAG,QAAmD;MAAA,IAAlD;QAAEC;MAAF,CAAkD;;MAC7E,IAAIA,KAAK,GAAG,CAAR,IAAaA,KAAK,GAAGtC,SAArB,IAAkCsC,KAAK,KAAKT,YAAhD,EAA8D;QAC1D;QACA,OAAO,CAAP;MACH;;MAED,MAAMU,QAAQ,GAAGpD,IAAI,CAACC,GAAL,CAASyC,YAAY,GAAGS,KAAxB,IAAiCzD,SAAlD;MACA,MAAMC,SAAS,GAAGwD,KAAK,GAAGT,YAAR,GAAuB,CAAC,CAAxB,GAA4B,CAA9C;MAEA,OAAOU,QAAQ,GAAGzD,SAAlB;IACH,CAVD;;IAYA,MAAM0D,aAAa,GAAGf,IAAI,KAAK,aAAT,CAClB;IADkB,EAEhBU,2BAA2B,CAACR,kBAAD,CAFX,CAGlB;IAHkB,EAIhBU,qBAAqB,CAACV,kBAAD,CAJ3B;IAMA,MAAM3C,OAAO,GAAG+C,iBAAiB,CAACS,aAAD,EAAgBnC,gBAAgB,CAACW,OAAjC,CAAjC;IAEAb,UAAU,CAACa,OAAX,GAAqBhC,OAArB;IACAsB,cAAc,CAACU,OAAf,GAAyB,IAAzB;IAEAd,sBAAsB,CAACG,gBAAgB,CAACW,OAAjB,GAA2BhC,OAA5B,CAAtB;;IAEA,IAAI2C,kBAAkB,CAACC,QAAvB,EAAiC;MAC7B,MAAMa,SAAS,GAAGhD,qBAAqB,CAACK,UAAD,EAAad,OAAb,CAAvC;MAEAyD,SAAS,CAACC,KAAV,CAAgB,SAAkB;QAAA,IAAjB;UAAEC;QAAF,CAAiB;;QAC9B,IAAIA,QAAJ,EAAc;UACVpB,iBAAiB;QACpB;MACJ,CAJD;MAMAtB,oBAAoB,CAAC,SAAD,CAApB;IACH,CAVD,MAUO;MACHsB,iBAAiB;IACpB;EACJ,CA/E4B,EA+E1B,CACC9B,qBADD,EAECM,eAFD,EAGCwB,iBAHD,EAIC1C,SAJD,EAKCmB,SALD,EAMCL,IAND,EAOCM,oBAPD,EAQCC,sBARD,CA/E0B,CAA7B;EA0FA,OAAO;IACHgB,kBADG;IAEHM;EAFG,CAAP;AAIH;;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["directions"],"sources":["types.ts"],"sourcesContent":["import type { ReactElement } from 'react';\nimport type { Animated, ViewProps } from 'react-native';\n\nconst directions = ['next', 'prev', 'stay'] as const;\n\nexport type PagingDirection = (typeof directions)[number];\n\nexport type ItemHeight = number | 'auto';\n\nexport interface RenderItem<T> {\n (info: { item: T, index: number, interpolation: Animated.AnimatedInterpolation }): ReactElement | null;\n}\n\nexport interface CreateScrollAnimation {\n (aValue: Animated.AnimatedValue, toValue: number): Animated.CompositeAnimation;\n}\n\nexport interface CreateItemStyle {\n (itemInterpolation: Animated.AnimatedInterpolation, itemWidth: number): Animated.AnimatedProps<ViewProps['style']>;\n}\n\nexport interface GetCurrentIndex {\n (): number;\n}\n\nexport interface IndexController {\n getCurrentIndex: GetCurrentIndex;\n lastIndex: number;\n notifyOffsetHasChanged: (offset: number) => void;\n}\n\nexport type PagingAnimationType = 'directional' | 'index';\n\nexport interface BasePagingAnimationConfig {\n animated?: boolean;\n}\n\nexport interface DirectionalPagingAnimationConfig extends BasePagingAnimationConfig {\n direction: PagingDirection;\n isOriginatedFromGesture?: boolean;\n}\n\nexport interface IndexPagingAnimationConfig extends BasePagingAnimationConfig {\n index: number;\n}\n\nexport type PagingAnimationConfig = DirectionalPagingAnimationConfig | IndexPagingAnimationConfig;\n\nexport interface StartPagingAnimation {\n (type: PagingAnimationType, config: PagingAnimationConfig): void;\n}\n\nexport type VisibleIndexRanges = Array<[number, number]>;\n\nexport interface StoreSubscription {\n (): void;\n}\n\nexport interface ItemVisibilityStore {\n dispatch: (ranges: VisibleIndexRanges) => void;\n subscribe: (listener: (ranges: VisibleIndexRanges) => void) => StoreSubscription;\n removeAllListeners: () => void;\n}\n\nexport interface AutoplayController {\n pause: () => void;\n resume: () => void;\n}\n\nexport interface ScrollToOption {\n index: number;\n animated?: boolean;\n}\n\nexport interface CarouselInstance {\n /**\n * Get current visible item index.\n */\n getCurrentIndex: GetCurrentIndex;\n\n /**\n * Scroll to next visible item.\n */\n next: () => void;\n\n /**\n * Scroll to previous visible item.\n */\n prev: () => void;\n\n /**\n * Scroll to desired indexed item.\n * Invalid index is ignored.\n */\n scrollTo: (option: ScrollToOption) => void;\n}\n"],"mappings":";;;;;AAGA,MAAMA,UAAU,GAAG,CAAC,MAAD,EAAS,MAAT,EAAiB,MAAjB,CAAnB"}
|
|
1
|
+
{"version":3,"names":["directions","animationStates"],"sources":["types.ts"],"sourcesContent":["import type { ReactElement } from 'react';\nimport type { Animated, ViewProps } from 'react-native';\n\nconst directions = ['next', 'prev', 'stay'] as const;\n\nexport type PagingDirection = (typeof directions)[number];\n\nconst animationStates = ['started', 'finished', 'interrupted'] as const;\n\nexport type AnimationState = (typeof animationStates)[number];\n\nexport type ItemHeight = number | 'auto';\n\nexport interface RenderItem<T> {\n (info: { item: T, index: number, interpolation: Animated.AnimatedInterpolation }): ReactElement | null;\n}\n\nexport interface CreateScrollAnimation {\n (aValue: Animated.AnimatedValue, toValue: number): Animated.CompositeAnimation;\n}\n\nexport interface CreateItemStyle {\n (itemInterpolation: Animated.AnimatedInterpolation, itemWidth: number): Animated.AnimatedProps<ViewProps['style']>;\n}\n\nexport interface GetCurrentIndex {\n (): number;\n}\n\nexport interface IndexController {\n getCurrentIndex: GetCurrentIndex;\n lastIndex: number;\n notifyAnimationState: (state: AnimationState) => void;\n notifyOffsetHasChanged: (offset: number) => void;\n}\n\nexport type PagingAnimationType = 'directional' | 'index';\n\nexport interface BasePagingAnimationConfig {\n animated?: boolean;\n}\n\nexport interface DirectionalPagingAnimationConfig extends BasePagingAnimationConfig {\n direction: PagingDirection;\n isOriginatedFromGesture?: boolean;\n}\n\nexport interface IndexPagingAnimationConfig extends BasePagingAnimationConfig {\n index: number;\n}\n\nexport type PagingAnimationConfig = DirectionalPagingAnimationConfig | IndexPagingAnimationConfig;\n\nexport interface StartPagingAnimation {\n (type: PagingAnimationType, config: PagingAnimationConfig): void;\n}\n\nexport type VisibleIndexRanges = Array<[number, number]>;\n\nexport interface StoreSubscription {\n (): void;\n}\n\nexport interface ItemVisibilityStore {\n dispatch: (ranges: VisibleIndexRanges) => void;\n subscribe: (listener: (ranges: VisibleIndexRanges) => void) => StoreSubscription;\n removeAllListeners: () => void;\n}\n\nexport interface AutoplayController {\n pause: () => void;\n resume: () => void;\n}\n\nexport interface ScrollToOption {\n index: number;\n animated?: boolean;\n}\n\nexport interface CarouselInstance {\n /**\n * Get current visible item index.\n */\n getCurrentIndex: GetCurrentIndex;\n\n /**\n * Scroll to next visible item.\n */\n next: () => void;\n\n /**\n * Scroll to previous visible item.\n */\n prev: () => void;\n\n /**\n * Scroll to desired indexed item.\n * Invalid index is ignored.\n */\n scrollTo: (option: ScrollToOption) => void;\n}\n"],"mappings":";;;;;AAGA,MAAMA,UAAU,GAAG,CAAC,MAAD,EAAS,MAAT,EAAiB,MAAjB,CAAnB;AAIA,MAAMC,eAAe,GAAG,CAAC,SAAD,EAAY,UAAZ,EAAwB,aAAxB,CAAxB"}
|
|
@@ -2,8 +2,8 @@ import { Animated, Easing } from 'react-native';
|
|
|
2
2
|
export default function createDefaultScrollAnimation(animatedValue, toValue) {
|
|
3
3
|
return Animated.timing(animatedValue, {
|
|
4
4
|
toValue: toValue,
|
|
5
|
-
duration:
|
|
6
|
-
easing: Easing.bezier(0.
|
|
5
|
+
duration: 180,
|
|
6
|
+
easing: Easing.bezier(0.2, 0.2, 0.2, 1),
|
|
7
7
|
useNativeDriver: true
|
|
8
8
|
});
|
|
9
9
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Animated","Easing","createDefaultScrollAnimation","animatedValue","toValue","timing","duration","easing","bezier","useNativeDriver"],"sources":["createDefaultScrollAnimation.ts"],"sourcesContent":["import { Animated, Easing } from 'react-native';\n\nexport default function createDefaultScrollAnimation(\n animatedValue: Animated.Value,\n toValue: number,\n): Animated.CompositeAnimation {\n return Animated.timing(animatedValue, {\n toValue: toValue,\n duration:
|
|
1
|
+
{"version":3,"names":["Animated","Easing","createDefaultScrollAnimation","animatedValue","toValue","timing","duration","easing","bezier","useNativeDriver"],"sources":["createDefaultScrollAnimation.ts"],"sourcesContent":["import { Animated, Easing } from 'react-native';\n\nexport default function createDefaultScrollAnimation(\n animatedValue: Animated.Value,\n toValue: number,\n): Animated.CompositeAnimation {\n return Animated.timing(animatedValue, {\n toValue: toValue,\n duration: 180,\n easing: Easing.bezier(0.2, 0.2, 0.2, 1),\n useNativeDriver: true,\n });\n};\n"],"mappings":"AAAA,SAASA,QAAT,EAAmBC,MAAnB,QAAiC,cAAjC;AAEA,eAAe,SAASC,4BAAT,CACXC,aADW,EAEXC,OAFW,EAGgB;EAC3B,OAAOJ,QAAQ,CAACK,MAAT,CAAgBF,aAAhB,EAA+B;IAClCC,OAAO,EAAEA,OADyB;IAElCE,QAAQ,EAAE,GAFwB;IAGlCC,MAAM,EAAEN,MAAM,CAACO,MAAP,CAAc,GAAd,EAAmB,GAAnB,EAAwB,GAAxB,EAA6B,CAA7B,CAH0B;IAIlCC,eAAe,EAAE;EAJiB,CAA/B,CAAP;AAMH;AAAA"}
|
|
@@ -8,7 +8,15 @@ export default function useIndexController(params) {
|
|
|
8
8
|
onIndexChange
|
|
9
9
|
} = params;
|
|
10
10
|
const currentIndexRef = useRef(initialIndex);
|
|
11
|
+
const indexChangedRef = useRef(false);
|
|
11
12
|
const getCurrentIndex = useCallback(() => currentIndexRef.current, []);
|
|
13
|
+
const notifyAnimationState = useCallback(state => {
|
|
14
|
+
if (state === 'finished' || state === 'interrupted') {
|
|
15
|
+
if (indexChangedRef.current) {
|
|
16
|
+
onIndexChange === null || onIndexChange === void 0 ? void 0 : onIndexChange(getCurrentIndex());
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}, [getCurrentIndex, onIndexChange]);
|
|
12
20
|
const notifyOffsetHasChanged = useCallback(offset => {
|
|
13
21
|
const roundedOffset = Math.round(offset / itemWidth) * itemWidth; // To prevent floating point problem, make sure index is integer type.
|
|
14
22
|
|
|
@@ -16,12 +24,13 @@ export default function useIndexController(params) {
|
|
|
16
24
|
|
|
17
25
|
if (nextIndex !== currentIndexRef.current) {
|
|
18
26
|
currentIndexRef.current = nextIndex;
|
|
19
|
-
|
|
27
|
+
indexChangedRef.current = true;
|
|
20
28
|
}
|
|
21
|
-
}, [itemWidth, numberOfOriginalData
|
|
29
|
+
}, [itemWidth, numberOfOriginalData]);
|
|
22
30
|
return {
|
|
23
31
|
getCurrentIndex,
|
|
24
32
|
lastIndex: numberOfOriginalData - 1,
|
|
33
|
+
notifyAnimationState,
|
|
25
34
|
notifyOffsetHasChanged
|
|
26
35
|
};
|
|
27
36
|
}
|
|
@@ -1 +1 @@
|
|
|
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
|
|
1
|
+
{"version":3,"names":["useCallback","useRef","mod","useIndexController","params","initialIndex","itemWidth","numberOfOriginalData","onIndexChange","currentIndexRef","indexChangedRef","getCurrentIndex","current","notifyAnimationState","state","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 { AnimationState, 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 const indexChangedRef = useRef<boolean>(false);\n\n const getCurrentIndex = useCallback(() => currentIndexRef.current, []);\n\n const notifyAnimationState = useCallback((state: AnimationState) => {\n if (state === 'finished' || state === 'interrupted') {\n if (indexChangedRef.current) {\n onIndexChange?.(getCurrentIndex());\n }\n }\n }, [\n getCurrentIndex,\n onIndexChange,\n ]);\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 indexChangedRef.current = true;\n }\n }, [itemWidth, numberOfOriginalData]);\n\n return {\n getCurrentIndex,\n lastIndex: numberOfOriginalData - 1,\n notifyAnimationState,\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;EACA,MAAMK,eAAe,GAAGT,MAAM,CAAU,KAAV,CAA9B;EAEA,MAAMU,eAAe,GAAGX,WAAW,CAAC,MAAMS,eAAe,CAACG,OAAvB,EAAgC,EAAhC,CAAnC;EAEA,MAAMC,oBAAoB,GAAGb,WAAW,CAAEc,KAAD,IAA2B;IAChE,IAAIA,KAAK,KAAK,UAAV,IAAwBA,KAAK,KAAK,aAAtC,EAAqD;MACjD,IAAIJ,eAAe,CAACE,OAApB,EAA6B;QACzBJ,aAAa,SAAb,IAAAA,aAAa,WAAb,YAAAA,aAAa,CAAGG,eAAe,EAAlB,CAAb;MACH;IACJ;EACJ,CANuC,EAMrC,CACCA,eADD,EAECH,aAFD,CANqC,CAAxC;EAWA,MAAMO,sBAAsB,GAAGf,WAAW,CAAEgB,MAAD,IAAoB;IAC3D,MAAMC,aAAa,GAAGC,IAAI,CAACC,KAAL,CAAWH,MAAM,GAAGV,SAApB,IAAiCA,SAAvD,CAD2D,CAG3D;;IACA,MAAMc,SAAS,GAAGF,IAAI,CAACG,KAAL,CAAWnB,GAAG,CAAE,CAACe,aAAD,GAAiBX,SAAnB,EAA+BC,oBAA/B,CAAd,CAAlB;;IAEA,IAAIa,SAAS,KAAKX,eAAe,CAACG,OAAlC,EAA2C;MACvCH,eAAe,CAACG,OAAhB,GAA0BQ,SAA1B;MACAV,eAAe,CAACE,OAAhB,GAA0B,IAA1B;IACH;EACJ,CAVyC,EAUvC,CAACN,SAAD,EAAYC,oBAAZ,CAVuC,CAA1C;EAYA,OAAO;IACHI,eADG;IAEHW,SAAS,EAAEf,oBAAoB,GAAG,CAF/B;IAGHM,oBAHG;IAIHE;EAJG,CAAP;AAMH;AAAA"}
|
|
@@ -38,6 +38,7 @@ export default function usePagingAnimation(params) {
|
|
|
38
38
|
const {
|
|
39
39
|
getCurrentIndex,
|
|
40
40
|
lastIndex,
|
|
41
|
+
notifyAnimationState,
|
|
41
42
|
notifyOffsetHasChanged
|
|
42
43
|
} = indexController;
|
|
43
44
|
const toValueRef = useRef(0);
|
|
@@ -64,8 +65,7 @@ export default function usePagingAnimation(params) {
|
|
|
64
65
|
translateX.setValue(0);
|
|
65
66
|
}, [ensureOffsetBoundary, offsetX, translateX]);
|
|
66
67
|
const interruptAnimation = useCallback(() => {
|
|
67
|
-
if (
|
|
68
|
-
// Performance optimization
|
|
68
|
+
if (!isAnimatingRef.current) {
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -74,16 +74,18 @@ export default function usePagingAnimation(params) {
|
|
|
74
74
|
const prevOffset = currentOffsetRef.current;
|
|
75
75
|
const totalOffset = prevOffset + lastValue;
|
|
76
76
|
notifyOffsetHasChanged(totalOffset);
|
|
77
|
+
notifyAnimationState('interrupted');
|
|
77
78
|
requireNewOffset(totalOffset);
|
|
78
79
|
});
|
|
79
80
|
}, [requireNewOffset, translateX]);
|
|
80
81
|
const finalizeAnimation = useCallback(() => {
|
|
82
|
+
notifyAnimationState('finished');
|
|
81
83
|
isAnimatingRef.current = false;
|
|
82
84
|
const prevOffset = currentOffsetRef.current;
|
|
83
85
|
const toValue = toValueRef.current;
|
|
84
86
|
const totalOffset = prevOffset + toValue;
|
|
85
87
|
requireNewOffset(totalOffset);
|
|
86
|
-
}, [requireNewOffset]);
|
|
88
|
+
}, [notifyAnimationState, requireNewOffset]);
|
|
87
89
|
const startPagingAnimation = useCallback((type, config) => {
|
|
88
90
|
if (isAnimatingRef.current) {
|
|
89
91
|
return;
|
|
@@ -141,6 +143,7 @@ export default function usePagingAnimation(params) {
|
|
|
141
143
|
const toValue = compensateToValue(wantedToValue, currentOffsetRef.current);
|
|
142
144
|
toValueRef.current = toValue;
|
|
143
145
|
isAnimatingRef.current = true;
|
|
146
|
+
notifyOffsetHasChanged(currentOffsetRef.current + toValue);
|
|
144
147
|
|
|
145
148
|
if (configWithDefaults.animated) {
|
|
146
149
|
const animation = createScrollAnimation(translateX, toValue);
|
|
@@ -153,12 +156,11 @@ export default function usePagingAnimation(params) {
|
|
|
153
156
|
finalizeAnimation();
|
|
154
157
|
}
|
|
155
158
|
});
|
|
159
|
+
notifyAnimationState('started');
|
|
156
160
|
} else {
|
|
157
161
|
finalizeAnimation();
|
|
158
162
|
}
|
|
159
|
-
|
|
160
|
-
notifyOffsetHasChanged(currentOffsetRef.current + toValue);
|
|
161
|
-
}, [createScrollAnimation, getCurrentIndex, finalizeAnimation, itemWidth, lastIndex, loop, notifyOffsetHasChanged]);
|
|
163
|
+
}, [createScrollAnimation, getCurrentIndex, finalizeAnimation, itemWidth, lastIndex, loop, notifyAnimationState, notifyOffsetHasChanged]);
|
|
162
164
|
return {
|
|
163
165
|
interruptAnimation,
|
|
164
166
|
startPagingAnimation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useRef","directionToValue","itemWidth","direction","toValueCompensator","toValue","currentOffset","remainder","Math","abs","halfOfItemWidth","compensateVector","usePagingAnimation","params","createScrollAnimation","indexController","loop","numberOfData","offsetX","translateX","getCurrentIndex","lastIndex","notifyOffsetHasChanged","toValueRef","currentOffsetRef","isAnimatingRef","maxWidth","ensureOffsetBoundary","offset","isCloseToEnd","signOfOffset","requireNewOffset","newOffset","nextOffset","current","setValue","interruptAnimation","stopAnimation","lastValue","prevOffset","totalOffset","finalizeAnimation","startPagingAnimation","type","config","configWithDefaults","animated","currentIndex","getValueByDirectionOnAllAdjacentItemsVisible","compensateToValue","getValueByDirectionalPagingOnLoopDisabled","_config","isOriginatedFromGesture","getValueByDirectionalPaging","_configWithDefaults","getValueByIndexPaging","index","distance","wantedToValue","animation","start","finished"],"sources":["usePagingAnimation.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { Animated } from 'react-native';\nimport type {\n CreateScrollAnimation,\n DirectionalPagingAnimationConfig,\n IndexController,\n IndexPagingAnimationConfig,\n PagingAnimationConfig,\n PagingAnimationType,\n PagingDirection,\n StartPagingAnimation,\n} from '../types';\n\nexport interface PagingAnimationParameters {\n createScrollAnimation: CreateScrollAnimation;\n itemWidth: number;\n indexController: IndexController;\n loop: boolean;\n numberOfData: number;\n offsetX: Animated.Value;\n translateX: Animated.Value;\n}\n\nexport interface UsePagingAnimation {\n interruptAnimation: () => void;\n startPagingAnimation: StartPagingAnimation;\n}\n\nfunction directionToValue(itemWidth: number) {\n return function (direction: PagingDirection): number {\n switch (direction) {\n case 'next':\n return -itemWidth;\n case 'prev':\n return itemWidth;\n case 'stay':\n return 0;\n }\n };\n}\n\nfunction toValueCompensator(itemWidth: number) {\n return function (toValue: number, currentOffset: number): number {\n const remainder = Math.abs(currentOffset % itemWidth);\n\n const halfOfItemWidth = Math.abs(itemWidth / 2);\n const compensateVector = remainder > halfOfItemWidth\n ? remainder - itemWidth\n : remainder;\n\n const direction = currentOffset > 0 ? -1 : 1;\n\n return toValue + (direction * compensateVector);\n };\n}\n\nexport default function usePagingAnimation(params: PagingAnimationParameters): UsePagingAnimation {\n const {\n createScrollAnimation,\n itemWidth,\n indexController,\n loop,\n numberOfData,\n offsetX,\n translateX,\n } = params;\n\n const {\n getCurrentIndex,\n lastIndex,\n notifyOffsetHasChanged,\n } = indexController;\n\n const toValueRef = useRef<number>(0);\n const currentOffsetRef = useRef<number>(0);\n\n const isAnimatingRef = useRef<boolean>(false);\n\n const maxWidth = Math.abs(numberOfData * itemWidth);\n\n const ensureOffsetBoundary: (offset: number) => number = useCallback((offset: number) => {\n if (loop) {\n const isCloseToEnd = Math.abs(offset) >= (maxWidth - itemWidth);\n if (isCloseToEnd) {\n const signOfOffset = offset > 0 ? 1 : -1;\n return offset + (-signOfOffset * maxWidth);\n }\n }\n\n return offset % maxWidth;\n }, [itemWidth, loop, maxWidth]);\n\n const requireNewOffset = useCallback((newOffset: number) => {\n const nextOffset = ensureOffsetBoundary(newOffset);\n\n currentOffsetRef.current = nextOffset;\n offsetX.setValue(nextOffset);\n\n toValueRef.current = 0;\n translateX.setValue(0);\n }, [\n ensureOffsetBoundary,\n offsetX,\n translateX,\n ]);\n\n const interruptAnimation = useCallback(() => {\n if (toValueRef.current === 0) {\n // Performance optimization\n return;\n }\n\n translateX.stopAnimation(lastValue => {\n isAnimatingRef.current = false;\n\n const prevOffset = currentOffsetRef.current;\n const totalOffset = prevOffset + lastValue;\n\n notifyOffsetHasChanged(totalOffset);\n\n requireNewOffset(totalOffset);\n });\n }, [requireNewOffset, translateX]);\n\n const finalizeAnimation = useCallback(() => {\n isAnimatingRef.current = false;\n\n const prevOffset = currentOffsetRef.current;\n const toValue = toValueRef.current;\n const totalOffset = prevOffset + toValue;\n\n requireNewOffset(totalOffset);\n }, [requireNewOffset]);\n\n const startPagingAnimation = useCallback((type: PagingAnimationType, config: PagingAnimationConfig) => {\n if (isAnimatingRef.current) {\n return;\n }\n\n const configWithDefaults: PagingAnimationConfig = {\n animated: true,\n ...config,\n };\n\n const currentIndex = getCurrentIndex();\n\n const getValueByDirectionOnAllAdjacentItemsVisible = directionToValue(itemWidth);\n const compensateToValue = toValueCompensator(itemWidth);\n\n const getValueByDirectionalPagingOnLoopDisabled = (_config: DirectionalPagingAnimationConfig): number => {\n const { direction, isOriginatedFromGesture } = _config;\n\n if (currentIndex === 0 && direction === 'prev') {\n return isOriginatedFromGesture\n ? getValueByDirectionOnAllAdjacentItemsVisible('stay')\n : -lastIndex * itemWidth; // last position\n } else if (currentIndex === lastIndex && direction === 'next') {\n return isOriginatedFromGesture\n ? getValueByDirectionOnAllAdjacentItemsVisible('stay')\n : lastIndex * itemWidth; // first position\n }\n return getValueByDirectionOnAllAdjacentItemsVisible(direction);\n };\n\n const getValueByDirectionalPaging = (_config: DirectionalPagingAnimationConfig): number => {\n const _configWithDefaults: DirectionalPagingAnimationConfig = {\n isOriginatedFromGesture: false,\n ..._config,\n };\n\n return loop\n ? getValueByDirectionOnAllAdjacentItemsVisible(_configWithDefaults.direction)\n : getValueByDirectionalPagingOnLoopDisabled(_configWithDefaults);\n };\n\n const getValueByIndexPaging = ({ index }: IndexPagingAnimationConfig): number => {\n if (index < 0 || index > lastIndex || index === currentIndex) {\n // no animation if index is invalid or equals to current index\n return 0;\n }\n\n const distance = Math.abs(currentIndex - index) * itemWidth;\n const direction = index > currentIndex ? -1 : 1;\n\n return distance * direction;\n };\n\n const wantedToValue = type === 'directional'\n // @ts-ignore\n ? getValueByDirectionalPaging(configWithDefaults)\n // @ts-ignore\n : getValueByIndexPaging(configWithDefaults);\n\n const toValue = compensateToValue(wantedToValue, currentOffsetRef.current);\n\n toValueRef.current = toValue;\n isAnimatingRef.current = true;\n\n if (configWithDefaults.animated) {\n const animation = createScrollAnimation(translateX, toValue);\n\n animation.start(({ finished }) => {\n if (finished) {\n finalizeAnimation();\n }\n });\n } else {\n finalizeAnimation();\n }\n\n notifyOffsetHasChanged(currentOffsetRef.current + toValue);\n }, [\n createScrollAnimation,\n getCurrentIndex,\n finalizeAnimation,\n itemWidth,\n lastIndex,\n loop,\n notifyOffsetHasChanged,\n ]);\n\n return {\n interruptAnimation,\n startPagingAnimation,\n };\n};\n"],"mappings":"AAAA,SAASA,WAAT,EAAsBC,MAAtB,QAAoC,OAApC;;AA4BA,SAASC,gBAAT,CAA0BC,SAA1B,EAA6C;EACzC,OAAO,UAAUC,SAAV,EAA8C;IACjD,QAAQA,SAAR;MACI,KAAK,MAAL;QACI,OAAO,CAACD,SAAR;;MACJ,KAAK,MAAL;QACI,OAAOA,SAAP;;MACJ,KAAK,MAAL;QACI,OAAO,CAAP;IANR;EAQH,CATD;AAUH;;AAED,SAASE,kBAAT,CAA4BF,SAA5B,EAA+C;EAC3C,OAAO,UAAUG,OAAV,EAA2BC,aAA3B,EAA0D;IAC7D,MAAMC,SAAS,GAAGC,IAAI,CAACC,GAAL,CAASH,aAAa,GAAGJ,SAAzB,CAAlB;IAEA,MAAMQ,eAAe,GAAGF,IAAI,CAACC,GAAL,CAASP,SAAS,GAAG,CAArB,CAAxB;IACA,MAAMS,gBAAgB,GAAGJ,SAAS,GAAGG,eAAZ,GACnBH,SAAS,GAAGL,SADO,GAEnBK,SAFN;IAIA,MAAMJ,SAAS,GAAGG,aAAa,GAAG,CAAhB,GAAoB,CAAC,CAArB,GAAyB,CAA3C;IAEA,OAAOD,OAAO,GAAIF,SAAS,GAAGQ,gBAA9B;EACH,CAXD;AAYH;;AAED,eAAe,SAASC,kBAAT,CAA4BC,MAA5B,EAAmF;EAC9F,MAAM;IACFC,qBADE;IAEFZ,SAFE;IAGFa,eAHE;IAIFC,IAJE;IAKFC,YALE;IAMFC,OANE;IAOFC;EAPE,IAQFN,MARJ;EAUA,MAAM;IACFO,eADE;IAEFC,SAFE;IAGFC;EAHE,IAIFP,eAJJ;EAMA,MAAMQ,UAAU,GAAGvB,MAAM,CAAS,CAAT,CAAzB;EACA,MAAMwB,gBAAgB,GAAGxB,MAAM,CAAS,CAAT,CAA/B;EAEA,MAAMyB,cAAc,GAAGzB,MAAM,CAAU,KAAV,CAA7B;EAEA,MAAM0B,QAAQ,GAAGlB,IAAI,CAACC,GAAL,CAASQ,YAAY,GAAGf,SAAxB,CAAjB;EAEA,MAAMyB,oBAAgD,GAAG5B,WAAW,CAAE6B,MAAD,IAAoB;IACrF,IAAIZ,IAAJ,EAAU;MACN,MAAMa,YAAY,GAAGrB,IAAI,CAACC,GAAL,CAASmB,MAAT,KAAqBF,QAAQ,GAAGxB,SAArD;;MACA,IAAI2B,YAAJ,EAAkB;QACd,MAAMC,YAAY,GAAGF,MAAM,GAAG,CAAT,GAAa,CAAb,GAAiB,CAAC,CAAvC;QACA,OAAOA,MAAM,GAAI,CAACE,YAAD,GAAgBJ,QAAjC;MACH;IACJ;;IAED,OAAOE,MAAM,GAAGF,QAAhB;EACH,CAVmE,EAUjE,CAACxB,SAAD,EAAYc,IAAZ,EAAkBU,QAAlB,CAViE,CAApE;EAYA,MAAMK,gBAAgB,GAAGhC,WAAW,CAAEiC,SAAD,IAAuB;IACxD,MAAMC,UAAU,GAAGN,oBAAoB,CAACK,SAAD,CAAvC;IAEAR,gBAAgB,CAACU,OAAjB,GAA2BD,UAA3B;IACAf,OAAO,CAACiB,QAAR,CAAiBF,UAAjB;IAEAV,UAAU,CAACW,OAAX,GAAqB,CAArB;IACAf,UAAU,CAACgB,QAAX,CAAoB,CAApB;EACH,CARmC,EAQjC,CACCR,oBADD,EAECT,OAFD,EAGCC,UAHD,CARiC,CAApC;EAcA,MAAMiB,kBAAkB,GAAGrC,WAAW,CAAC,MAAM;IACzC,IAAIwB,UAAU,CAACW,OAAX,KAAuB,CAA3B,EAA8B;MAC1B;MACA;IACH;;IAEDf,UAAU,CAACkB,aAAX,CAAyBC,SAAS,IAAI;MAClCb,cAAc,CAACS,OAAf,GAAyB,KAAzB;MAEA,MAAMK,UAAU,GAAGf,gBAAgB,CAACU,OAApC;MACA,MAAMM,WAAW,GAAGD,UAAU,GAAGD,SAAjC;MAEAhB,sBAAsB,CAACkB,WAAD,CAAtB;MAEAT,gBAAgB,CAACS,WAAD,CAAhB;IACH,CATD;EAUH,CAhBqC,EAgBnC,CAACT,gBAAD,EAAmBZ,UAAnB,CAhBmC,CAAtC;EAkBA,MAAMsB,iBAAiB,GAAG1C,WAAW,CAAC,MAAM;IACxC0B,cAAc,CAACS,OAAf,GAAyB,KAAzB;IAEA,MAAMK,UAAU,GAAGf,gBAAgB,CAACU,OAApC;IACA,MAAM7B,OAAO,GAAGkB,UAAU,CAACW,OAA3B;IACA,MAAMM,WAAW,GAAGD,UAAU,GAAGlC,OAAjC;IAEA0B,gBAAgB,CAACS,WAAD,CAAhB;EACH,CARoC,EAQlC,CAACT,gBAAD,CARkC,CAArC;EAUA,MAAMW,oBAAoB,GAAG3C,WAAW,CAAC,CAAC4C,IAAD,EAA4BC,MAA5B,KAA8D;IACnG,IAAInB,cAAc,CAACS,OAAnB,EAA4B;MACxB;IACH;;IAED,MAAMW,kBAAyC,GAAG;MAC9CC,QAAQ,EAAE,IADoC;MAE9C,GAAGF;IAF2C,CAAlD;IAKA,MAAMG,YAAY,GAAG3B,eAAe,EAApC;IAEA,MAAM4B,4CAA4C,GAAG/C,gBAAgB,CAACC,SAAD,CAArE;IACA,MAAM+C,iBAAiB,GAAG7C,kBAAkB,CAACF,SAAD,CAA5C;;IAEA,MAAMgD,yCAAyC,GAAIC,OAAD,IAAuD;MACrG,MAAM;QAAEhD,SAAF;QAAaiD;MAAb,IAAyCD,OAA/C;;MAEA,IAAIJ,YAAY,KAAK,CAAjB,IAAsB5C,SAAS,KAAK,MAAxC,EAAgD;QAC5C,OAAOiD,uBAAuB,GACxBJ,4CAA4C,CAAC,MAAD,CADpB,GAExB,CAAC3B,SAAD,GAAanB,SAFnB,CAD4C,CAGd;MACjC,CAJD,MAIO,IAAI6C,YAAY,KAAK1B,SAAjB,IAA8BlB,SAAS,KAAK,MAAhD,EAAwD;QAC3D,OAAOiD,uBAAuB,GACxBJ,4CAA4C,CAAC,MAAD,CADpB,GAExB3B,SAAS,GAAGnB,SAFlB,CAD2D,CAG9B;MAChC;;MACD,OAAO8C,4CAA4C,CAAC7C,SAAD,CAAnD;IACH,CAbD;;IAeA,MAAMkD,2BAA2B,GAAIF,OAAD,IAAuD;MACvF,MAAMG,mBAAqD,GAAG;QAC1DF,uBAAuB,EAAE,KADiC;QAE1D,GAAGD;MAFuD,CAA9D;MAKA,OAAOnC,IAAI,GACLgC,4CAA4C,CAACM,mBAAmB,CAACnD,SAArB,CADvC,GAEL+C,yCAAyC,CAACI,mBAAD,CAF/C;IAGH,CATD;;IAWA,MAAMC,qBAAqB,GAAG,QAAmD;MAAA,IAAlD;QAAEC;MAAF,CAAkD;;MAC7E,IAAIA,KAAK,GAAG,CAAR,IAAaA,KAAK,GAAGnC,SAArB,IAAkCmC,KAAK,KAAKT,YAAhD,EAA8D;QAC1D;QACA,OAAO,CAAP;MACH;;MAED,MAAMU,QAAQ,GAAGjD,IAAI,CAACC,GAAL,CAASsC,YAAY,GAAGS,KAAxB,IAAiCtD,SAAlD;MACA,MAAMC,SAAS,GAAGqD,KAAK,GAAGT,YAAR,GAAuB,CAAC,CAAxB,GAA4B,CAA9C;MAEA,OAAOU,QAAQ,GAAGtD,SAAlB;IACH,CAVD;;IAYA,MAAMuD,aAAa,GAAGf,IAAI,KAAK,aAAT,CAClB;IADkB,EAEhBU,2BAA2B,CAACR,kBAAD,CAFX,CAGlB;IAHkB,EAIhBU,qBAAqB,CAACV,kBAAD,CAJ3B;IAMA,MAAMxC,OAAO,GAAG4C,iBAAiB,CAACS,aAAD,EAAgBlC,gBAAgB,CAACU,OAAjC,CAAjC;IAEAX,UAAU,CAACW,OAAX,GAAqB7B,OAArB;IACAoB,cAAc,CAACS,OAAf,GAAyB,IAAzB;;IAEA,IAAIW,kBAAkB,CAACC,QAAvB,EAAiC;MAC7B,MAAMa,SAAS,GAAG7C,qBAAqB,CAACK,UAAD,EAAad,OAAb,CAAvC;MAEAsD,SAAS,CAACC,KAAV,CAAgB,SAAkB;QAAA,IAAjB;UAAEC;QAAF,CAAiB;;QAC9B,IAAIA,QAAJ,EAAc;UACVpB,iBAAiB;QACpB;MACJ,CAJD;IAKH,CARD,MAQO;MACHA,iBAAiB;IACpB;;IAEDnB,sBAAsB,CAACE,gBAAgB,CAACU,OAAjB,GAA2B7B,OAA5B,CAAtB;EACH,CA7EuC,EA6ErC,CACCS,qBADD,EAECM,eAFD,EAGCqB,iBAHD,EAICvC,SAJD,EAKCmB,SALD,EAMCL,IAND,EAOCM,sBAPD,CA7EqC,CAAxC;EAuFA,OAAO;IACHc,kBADG;IAEHM;EAFG,CAAP;AAIH;AAAA"}
|
|
1
|
+
{"version":3,"names":["useCallback","useRef","directionToValue","itemWidth","direction","toValueCompensator","toValue","currentOffset","remainder","Math","abs","halfOfItemWidth","compensateVector","usePagingAnimation","params","createScrollAnimation","indexController","loop","numberOfData","offsetX","translateX","getCurrentIndex","lastIndex","notifyAnimationState","notifyOffsetHasChanged","toValueRef","currentOffsetRef","isAnimatingRef","maxWidth","ensureOffsetBoundary","offset","isCloseToEnd","signOfOffset","requireNewOffset","newOffset","nextOffset","current","setValue","interruptAnimation","stopAnimation","lastValue","prevOffset","totalOffset","finalizeAnimation","startPagingAnimation","type","config","configWithDefaults","animated","currentIndex","getValueByDirectionOnAllAdjacentItemsVisible","compensateToValue","getValueByDirectionalPagingOnLoopDisabled","_config","isOriginatedFromGesture","getValueByDirectionalPaging","_configWithDefaults","getValueByIndexPaging","index","distance","wantedToValue","animation","start","finished"],"sources":["usePagingAnimation.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { Animated } from 'react-native';\nimport type {\n CreateScrollAnimation,\n DirectionalPagingAnimationConfig,\n IndexController,\n IndexPagingAnimationConfig,\n PagingAnimationConfig,\n PagingAnimationType,\n PagingDirection,\n StartPagingAnimation,\n} from '../types';\n\nexport interface PagingAnimationParameters {\n createScrollAnimation: CreateScrollAnimation;\n itemWidth: number;\n indexController: IndexController;\n loop: boolean;\n numberOfData: number;\n offsetX: Animated.Value;\n translateX: Animated.Value;\n}\n\nexport interface UsePagingAnimation {\n interruptAnimation: () => void;\n startPagingAnimation: StartPagingAnimation;\n}\n\nfunction directionToValue(itemWidth: number) {\n return function (direction: PagingDirection): number {\n switch (direction) {\n case 'next':\n return -itemWidth;\n case 'prev':\n return itemWidth;\n case 'stay':\n return 0;\n }\n };\n}\n\nfunction toValueCompensator(itemWidth: number) {\n return function (toValue: number, currentOffset: number): number {\n const remainder = Math.abs(currentOffset % itemWidth);\n\n const halfOfItemWidth = Math.abs(itemWidth / 2);\n const compensateVector = remainder > halfOfItemWidth\n ? remainder - itemWidth\n : remainder;\n\n const direction = currentOffset > 0 ? -1 : 1;\n\n return toValue + (direction * compensateVector);\n };\n}\n\nexport default function usePagingAnimation(params: PagingAnimationParameters): UsePagingAnimation {\n const {\n createScrollAnimation,\n itemWidth,\n indexController,\n loop,\n numberOfData,\n offsetX,\n translateX,\n } = params;\n\n const {\n getCurrentIndex,\n lastIndex,\n notifyAnimationState,\n notifyOffsetHasChanged,\n } = indexController;\n\n const toValueRef = useRef<number>(0);\n const currentOffsetRef = useRef<number>(0);\n\n const isAnimatingRef = useRef<boolean>(false);\n\n const maxWidth = Math.abs(numberOfData * itemWidth);\n\n const ensureOffsetBoundary: (offset: number) => number = useCallback((offset: number) => {\n if (loop) {\n const isCloseToEnd = Math.abs(offset) >= (maxWidth - itemWidth);\n if (isCloseToEnd) {\n const signOfOffset = offset > 0 ? 1 : -1;\n return offset + (-signOfOffset * maxWidth);\n }\n }\n\n return offset % maxWidth;\n }, [itemWidth, loop, maxWidth]);\n\n const requireNewOffset = useCallback((newOffset: number) => {\n const nextOffset = ensureOffsetBoundary(newOffset);\n\n currentOffsetRef.current = nextOffset;\n offsetX.setValue(nextOffset);\n\n toValueRef.current = 0;\n translateX.setValue(0);\n }, [\n ensureOffsetBoundary,\n offsetX,\n translateX,\n ]);\n\n const interruptAnimation = useCallback(() => {\n if (!isAnimatingRef.current) {\n return;\n }\n\n translateX.stopAnimation(lastValue => {\n isAnimatingRef.current = false;\n\n const prevOffset = currentOffsetRef.current;\n const totalOffset = prevOffset + lastValue;\n\n notifyOffsetHasChanged(totalOffset);\n notifyAnimationState('interrupted');\n\n requireNewOffset(totalOffset);\n });\n }, [requireNewOffset, translateX]);\n\n const finalizeAnimation = useCallback(() => {\n notifyAnimationState('finished');\n\n isAnimatingRef.current = false;\n\n const prevOffset = currentOffsetRef.current;\n const toValue = toValueRef.current;\n const totalOffset = prevOffset + toValue;\n\n requireNewOffset(totalOffset);\n }, [\n notifyAnimationState,\n requireNewOffset,\n ]);\n\n const startPagingAnimation = useCallback((type: PagingAnimationType, config: PagingAnimationConfig) => {\n if (isAnimatingRef.current) {\n return;\n }\n\n const configWithDefaults: PagingAnimationConfig = {\n animated: true,\n ...config,\n };\n\n const currentIndex = getCurrentIndex();\n\n const getValueByDirectionOnAllAdjacentItemsVisible = directionToValue(itemWidth);\n const compensateToValue = toValueCompensator(itemWidth);\n\n const getValueByDirectionalPagingOnLoopDisabled = (_config: DirectionalPagingAnimationConfig): number => {\n const { direction, isOriginatedFromGesture } = _config;\n\n if (currentIndex === 0 && direction === 'prev') {\n return isOriginatedFromGesture\n ? getValueByDirectionOnAllAdjacentItemsVisible('stay')\n : -lastIndex * itemWidth; // last position\n } else if (currentIndex === lastIndex && direction === 'next') {\n return isOriginatedFromGesture\n ? getValueByDirectionOnAllAdjacentItemsVisible('stay')\n : lastIndex * itemWidth; // first position\n }\n return getValueByDirectionOnAllAdjacentItemsVisible(direction);\n };\n\n const getValueByDirectionalPaging = (_config: DirectionalPagingAnimationConfig): number => {\n const _configWithDefaults: DirectionalPagingAnimationConfig = {\n isOriginatedFromGesture: false,\n ..._config,\n };\n\n return loop\n ? getValueByDirectionOnAllAdjacentItemsVisible(_configWithDefaults.direction)\n : getValueByDirectionalPagingOnLoopDisabled(_configWithDefaults);\n };\n\n const getValueByIndexPaging = ({ index }: IndexPagingAnimationConfig): number => {\n if (index < 0 || index > lastIndex || index === currentIndex) {\n // no animation if index is invalid or equals to current index\n return 0;\n }\n\n const distance = Math.abs(currentIndex - index) * itemWidth;\n const direction = index > currentIndex ? -1 : 1;\n\n return distance * direction;\n };\n\n const wantedToValue = type === 'directional'\n // @ts-ignore\n ? getValueByDirectionalPaging(configWithDefaults)\n // @ts-ignore\n : getValueByIndexPaging(configWithDefaults);\n\n const toValue = compensateToValue(wantedToValue, currentOffsetRef.current);\n\n toValueRef.current = toValue;\n isAnimatingRef.current = true;\n\n notifyOffsetHasChanged(currentOffsetRef.current + toValue);\n\n if (configWithDefaults.animated) {\n const animation = createScrollAnimation(translateX, toValue);\n\n animation.start(({ finished }) => {\n if (finished) {\n finalizeAnimation();\n }\n });\n\n notifyAnimationState('started');\n } else {\n finalizeAnimation();\n }\n }, [\n createScrollAnimation,\n getCurrentIndex,\n finalizeAnimation,\n itemWidth,\n lastIndex,\n loop,\n notifyAnimationState,\n notifyOffsetHasChanged,\n ]);\n\n return {\n interruptAnimation,\n startPagingAnimation,\n };\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["directions"],"sources":["types.ts"],"sourcesContent":["import type { ReactElement } from 'react';\nimport type { Animated, ViewProps } from 'react-native';\n\nconst directions = ['next', 'prev', 'stay'] as const;\n\nexport type PagingDirection = (typeof directions)[number];\n\nexport type ItemHeight = number | 'auto';\n\nexport interface RenderItem<T> {\n (info: { item: T, index: number, interpolation: Animated.AnimatedInterpolation }): ReactElement | null;\n}\n\nexport interface CreateScrollAnimation {\n (aValue: Animated.AnimatedValue, toValue: number): Animated.CompositeAnimation;\n}\n\nexport interface CreateItemStyle {\n (itemInterpolation: Animated.AnimatedInterpolation, itemWidth: number): Animated.AnimatedProps<ViewProps['style']>;\n}\n\nexport interface GetCurrentIndex {\n (): number;\n}\n\nexport interface IndexController {\n getCurrentIndex: GetCurrentIndex;\n lastIndex: number;\n notifyOffsetHasChanged: (offset: number) => void;\n}\n\nexport type PagingAnimationType = 'directional' | 'index';\n\nexport interface BasePagingAnimationConfig {\n animated?: boolean;\n}\n\nexport interface DirectionalPagingAnimationConfig extends BasePagingAnimationConfig {\n direction: PagingDirection;\n isOriginatedFromGesture?: boolean;\n}\n\nexport interface IndexPagingAnimationConfig extends BasePagingAnimationConfig {\n index: number;\n}\n\nexport type PagingAnimationConfig = DirectionalPagingAnimationConfig | IndexPagingAnimationConfig;\n\nexport interface StartPagingAnimation {\n (type: PagingAnimationType, config: PagingAnimationConfig): void;\n}\n\nexport type VisibleIndexRanges = Array<[number, number]>;\n\nexport interface StoreSubscription {\n (): void;\n}\n\nexport interface ItemVisibilityStore {\n dispatch: (ranges: VisibleIndexRanges) => void;\n subscribe: (listener: (ranges: VisibleIndexRanges) => void) => StoreSubscription;\n removeAllListeners: () => void;\n}\n\nexport interface AutoplayController {\n pause: () => void;\n resume: () => void;\n}\n\nexport interface ScrollToOption {\n index: number;\n animated?: boolean;\n}\n\nexport interface CarouselInstance {\n /**\n * Get current visible item index.\n */\n getCurrentIndex: GetCurrentIndex;\n\n /**\n * Scroll to next visible item.\n */\n next: () => void;\n\n /**\n * Scroll to previous visible item.\n */\n prev: () => void;\n\n /**\n * Scroll to desired indexed item.\n * Invalid index is ignored.\n */\n scrollTo: (option: ScrollToOption) => void;\n}\n"],"mappings":"AAGA,MAAMA,UAAU,GAAG,CAAC,MAAD,EAAS,MAAT,EAAiB,MAAjB,CAAnB"}
|
|
1
|
+
{"version":3,"names":["directions","animationStates"],"sources":["types.ts"],"sourcesContent":["import type { ReactElement } from 'react';\nimport type { Animated, ViewProps } from 'react-native';\n\nconst directions = ['next', 'prev', 'stay'] as const;\n\nexport type PagingDirection = (typeof directions)[number];\n\nconst animationStates = ['started', 'finished', 'interrupted'] as const;\n\nexport type AnimationState = (typeof animationStates)[number];\n\nexport type ItemHeight = number | 'auto';\n\nexport interface RenderItem<T> {\n (info: { item: T, index: number, interpolation: Animated.AnimatedInterpolation }): ReactElement | null;\n}\n\nexport interface CreateScrollAnimation {\n (aValue: Animated.AnimatedValue, toValue: number): Animated.CompositeAnimation;\n}\n\nexport interface CreateItemStyle {\n (itemInterpolation: Animated.AnimatedInterpolation, itemWidth: number): Animated.AnimatedProps<ViewProps['style']>;\n}\n\nexport interface GetCurrentIndex {\n (): number;\n}\n\nexport interface IndexController {\n getCurrentIndex: GetCurrentIndex;\n lastIndex: number;\n notifyAnimationState: (state: AnimationState) => void;\n notifyOffsetHasChanged: (offset: number) => void;\n}\n\nexport type PagingAnimationType = 'directional' | 'index';\n\nexport interface BasePagingAnimationConfig {\n animated?: boolean;\n}\n\nexport interface DirectionalPagingAnimationConfig extends BasePagingAnimationConfig {\n direction: PagingDirection;\n isOriginatedFromGesture?: boolean;\n}\n\nexport interface IndexPagingAnimationConfig extends BasePagingAnimationConfig {\n index: number;\n}\n\nexport type PagingAnimationConfig = DirectionalPagingAnimationConfig | IndexPagingAnimationConfig;\n\nexport interface StartPagingAnimation {\n (type: PagingAnimationType, config: PagingAnimationConfig): void;\n}\n\nexport type VisibleIndexRanges = Array<[number, number]>;\n\nexport interface StoreSubscription {\n (): void;\n}\n\nexport interface ItemVisibilityStore {\n dispatch: (ranges: VisibleIndexRanges) => void;\n subscribe: (listener: (ranges: VisibleIndexRanges) => void) => StoreSubscription;\n removeAllListeners: () => void;\n}\n\nexport interface AutoplayController {\n pause: () => void;\n resume: () => void;\n}\n\nexport interface ScrollToOption {\n index: number;\n animated?: boolean;\n}\n\nexport interface CarouselInstance {\n /**\n * Get current visible item index.\n */\n getCurrentIndex: GetCurrentIndex;\n\n /**\n * Scroll to next visible item.\n */\n next: () => void;\n\n /**\n * Scroll to previous visible item.\n */\n prev: () => void;\n\n /**\n * Scroll to desired indexed item.\n * Invalid index is ignored.\n */\n scrollTo: (option: ScrollToOption) => void;\n}\n"],"mappings":"AAGA,MAAMA,UAAU,GAAG,CAAC,MAAD,EAAS,MAAT,EAAiB,MAAjB,CAAnB;AAIA,MAAMC,eAAe,GAAG,CAAC,SAAD,EAAY,UAAZ,EAAwB,aAAxB,CAAxB"}
|
|
@@ -2,6 +2,8 @@ import type { ReactElement } from 'react';
|
|
|
2
2
|
import type { Animated, ViewProps } from 'react-native';
|
|
3
3
|
declare const directions: readonly ["next", "prev", "stay"];
|
|
4
4
|
export declare type PagingDirection = (typeof directions)[number];
|
|
5
|
+
declare const animationStates: readonly ["started", "finished", "interrupted"];
|
|
6
|
+
export declare type AnimationState = (typeof animationStates)[number];
|
|
5
7
|
export declare type ItemHeight = number | 'auto';
|
|
6
8
|
export interface RenderItem<T> {
|
|
7
9
|
(info: {
|
|
@@ -22,6 +24,7 @@ export interface GetCurrentIndex {
|
|
|
22
24
|
export interface IndexController {
|
|
23
25
|
getCurrentIndex: GetCurrentIndex;
|
|
24
26
|
lastIndex: number;
|
|
27
|
+
notifyAnimationState: (state: AnimationState) => void;
|
|
25
28
|
notifyOffsetHasChanged: (offset: number) => void;
|
|
26
29
|
}
|
|
27
30
|
export declare type PagingAnimationType = 'directional' | 'index';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fountain-ui/lab",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.16",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Fountain-UI Team",
|
|
6
6
|
"description": "Incubator for Fountain-UI React components.",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"publishConfig": {
|
|
71
71
|
"access": "public"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "44c50a4474a3bca589e8cedd3ff476927e12061c"
|
|
74
74
|
}
|
|
@@ -6,8 +6,8 @@ export default function createDefaultScrollAnimation(
|
|
|
6
6
|
): Animated.CompositeAnimation {
|
|
7
7
|
return Animated.timing(animatedValue, {
|
|
8
8
|
toValue: toValue,
|
|
9
|
-
duration:
|
|
10
|
-
easing: Easing.bezier(0.
|
|
9
|
+
duration: 180,
|
|
10
|
+
easing: Easing.bezier(0.2, 0.2, 0.2, 1),
|
|
11
11
|
useNativeDriver: true,
|
|
12
12
|
});
|
|
13
13
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useCallback, useRef } from 'react';
|
|
2
2
|
import { mod } from '@fountain-ui/utils';
|
|
3
|
-
import type { IndexController } from '../types';
|
|
3
|
+
import type { AnimationState, IndexController } from '../types';
|
|
4
4
|
|
|
5
5
|
export interface UseIndexControllerParameters {
|
|
6
6
|
initialIndex: number;
|
|
@@ -18,9 +18,21 @@ export default function useIndexController(params: UseIndexControllerParameters)
|
|
|
18
18
|
} = params;
|
|
19
19
|
|
|
20
20
|
const currentIndexRef = useRef<number>(initialIndex);
|
|
21
|
+
const indexChangedRef = useRef<boolean>(false);
|
|
21
22
|
|
|
22
23
|
const getCurrentIndex = useCallback(() => currentIndexRef.current, []);
|
|
23
24
|
|
|
25
|
+
const notifyAnimationState = useCallback((state: AnimationState) => {
|
|
26
|
+
if (state === 'finished' || state === 'interrupted') {
|
|
27
|
+
if (indexChangedRef.current) {
|
|
28
|
+
onIndexChange?.(getCurrentIndex());
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}, [
|
|
32
|
+
getCurrentIndex,
|
|
33
|
+
onIndexChange,
|
|
34
|
+
]);
|
|
35
|
+
|
|
24
36
|
const notifyOffsetHasChanged = useCallback((offset: number) => {
|
|
25
37
|
const roundedOffset = Math.round(offset / itemWidth) * itemWidth;
|
|
26
38
|
|
|
@@ -29,18 +41,14 @@ export default function useIndexController(params: UseIndexControllerParameters)
|
|
|
29
41
|
|
|
30
42
|
if (nextIndex !== currentIndexRef.current) {
|
|
31
43
|
currentIndexRef.current = nextIndex;
|
|
32
|
-
|
|
33
|
-
onIndexChange?.(nextIndex);
|
|
44
|
+
indexChangedRef.current = true;
|
|
34
45
|
}
|
|
35
|
-
}, [
|
|
36
|
-
itemWidth,
|
|
37
|
-
numberOfOriginalData,
|
|
38
|
-
onIndexChange,
|
|
39
|
-
]);
|
|
46
|
+
}, [itemWidth, numberOfOriginalData]);
|
|
40
47
|
|
|
41
48
|
return {
|
|
42
49
|
getCurrentIndex,
|
|
43
50
|
lastIndex: numberOfOriginalData - 1,
|
|
51
|
+
notifyAnimationState,
|
|
44
52
|
notifyOffsetHasChanged,
|
|
45
53
|
};
|
|
46
54
|
};
|
|
@@ -68,6 +68,7 @@ export default function usePagingAnimation(params: PagingAnimationParameters): U
|
|
|
68
68
|
const {
|
|
69
69
|
getCurrentIndex,
|
|
70
70
|
lastIndex,
|
|
71
|
+
notifyAnimationState,
|
|
71
72
|
notifyOffsetHasChanged,
|
|
72
73
|
} = indexController;
|
|
73
74
|
|
|
@@ -105,8 +106,7 @@ export default function usePagingAnimation(params: PagingAnimationParameters): U
|
|
|
105
106
|
]);
|
|
106
107
|
|
|
107
108
|
const interruptAnimation = useCallback(() => {
|
|
108
|
-
if (
|
|
109
|
-
// Performance optimization
|
|
109
|
+
if (!isAnimatingRef.current) {
|
|
110
110
|
return;
|
|
111
111
|
}
|
|
112
112
|
|
|
@@ -117,12 +117,15 @@ export default function usePagingAnimation(params: PagingAnimationParameters): U
|
|
|
117
117
|
const totalOffset = prevOffset + lastValue;
|
|
118
118
|
|
|
119
119
|
notifyOffsetHasChanged(totalOffset);
|
|
120
|
+
notifyAnimationState('interrupted');
|
|
120
121
|
|
|
121
122
|
requireNewOffset(totalOffset);
|
|
122
123
|
});
|
|
123
124
|
}, [requireNewOffset, translateX]);
|
|
124
125
|
|
|
125
126
|
const finalizeAnimation = useCallback(() => {
|
|
127
|
+
notifyAnimationState('finished');
|
|
128
|
+
|
|
126
129
|
isAnimatingRef.current = false;
|
|
127
130
|
|
|
128
131
|
const prevOffset = currentOffsetRef.current;
|
|
@@ -130,7 +133,10 @@ export default function usePagingAnimation(params: PagingAnimationParameters): U
|
|
|
130
133
|
const totalOffset = prevOffset + toValue;
|
|
131
134
|
|
|
132
135
|
requireNewOffset(totalOffset);
|
|
133
|
-
}, [
|
|
136
|
+
}, [
|
|
137
|
+
notifyAnimationState,
|
|
138
|
+
requireNewOffset,
|
|
139
|
+
]);
|
|
134
140
|
|
|
135
141
|
const startPagingAnimation = useCallback((type: PagingAnimationType, config: PagingAnimationConfig) => {
|
|
136
142
|
if (isAnimatingRef.current) {
|
|
@@ -196,6 +202,8 @@ export default function usePagingAnimation(params: PagingAnimationParameters): U
|
|
|
196
202
|
toValueRef.current = toValue;
|
|
197
203
|
isAnimatingRef.current = true;
|
|
198
204
|
|
|
205
|
+
notifyOffsetHasChanged(currentOffsetRef.current + toValue);
|
|
206
|
+
|
|
199
207
|
if (configWithDefaults.animated) {
|
|
200
208
|
const animation = createScrollAnimation(translateX, toValue);
|
|
201
209
|
|
|
@@ -204,11 +212,11 @@ export default function usePagingAnimation(params: PagingAnimationParameters): U
|
|
|
204
212
|
finalizeAnimation();
|
|
205
213
|
}
|
|
206
214
|
});
|
|
215
|
+
|
|
216
|
+
notifyAnimationState('started');
|
|
207
217
|
} else {
|
|
208
218
|
finalizeAnimation();
|
|
209
219
|
}
|
|
210
|
-
|
|
211
|
-
notifyOffsetHasChanged(currentOffsetRef.current + toValue);
|
|
212
220
|
}, [
|
|
213
221
|
createScrollAnimation,
|
|
214
222
|
getCurrentIndex,
|
|
@@ -216,6 +224,7 @@ export default function usePagingAnimation(params: PagingAnimationParameters): U
|
|
|
216
224
|
itemWidth,
|
|
217
225
|
lastIndex,
|
|
218
226
|
loop,
|
|
227
|
+
notifyAnimationState,
|
|
219
228
|
notifyOffsetHasChanged,
|
|
220
229
|
]);
|
|
221
230
|
|
package/src/Carousel/types.ts
CHANGED
|
@@ -5,6 +5,10 @@ const directions = ['next', 'prev', 'stay'] as const;
|
|
|
5
5
|
|
|
6
6
|
export type PagingDirection = (typeof directions)[number];
|
|
7
7
|
|
|
8
|
+
const animationStates = ['started', 'finished', 'interrupted'] as const;
|
|
9
|
+
|
|
10
|
+
export type AnimationState = (typeof animationStates)[number];
|
|
11
|
+
|
|
8
12
|
export type ItemHeight = number | 'auto';
|
|
9
13
|
|
|
10
14
|
export interface RenderItem<T> {
|
|
@@ -26,6 +30,7 @@ export interface GetCurrentIndex {
|
|
|
26
30
|
export interface IndexController {
|
|
27
31
|
getCurrentIndex: GetCurrentIndex;
|
|
28
32
|
lastIndex: number;
|
|
33
|
+
notifyAnimationState: (state: AnimationState) => void;
|
|
29
34
|
notifyOffsetHasChanged: (offset: number) => void;
|
|
30
35
|
}
|
|
31
36
|
|