decathlon-ui 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/accordion/accordion.component.d.ts +1 -1
- package/dist/components/accordion/accordion.component.d.ts.map +1 -1
- package/dist/components/accordion/accordion.component.js +5 -15
- package/dist/components/action-button/action-button.component.d.ts +1 -1
- package/dist/components/action-button/action-button.component.d.ts.map +1 -1
- package/dist/components/action-button/action-button.component.js +7 -8
- package/dist/components/badge/badge.component.d.ts +2 -5
- package/dist/components/badge/badge.component.d.ts.map +1 -1
- package/dist/components/badge/badge.component.js +4 -1
- package/dist/components/banner-carousel/banner-carousel.component.d.ts +5 -0
- package/dist/components/banner-carousel/banner-carousel.component.d.ts.map +1 -0
- package/dist/components/banner-carousel/banner-carousel.component.js +68 -0
- package/dist/components/banner-carousel/banner-carousel.styles.d.ts +17 -0
- package/dist/components/banner-carousel/banner-carousel.styles.d.ts.map +1 -0
- package/dist/components/banner-carousel/banner-carousel.styles.js +20 -0
- package/dist/components/banner-carousel/banner-carousel.types.d.ts +11 -0
- package/dist/components/banner-carousel/banner-carousel.types.d.ts.map +1 -0
- package/dist/components/banner-carousel/banner-carousel.types.js +1 -0
- package/dist/components/banner-carousel/index.d.ts +3 -0
- package/dist/components/banner-carousel/index.d.ts.map +1 -0
- package/dist/components/banner-carousel/index.js +1 -0
- package/dist/components/button/button.component.d.ts +1 -1
- package/dist/components/button/button.component.d.ts.map +1 -1
- package/dist/components/button/button.component.js +7 -3
- package/dist/components/card/card.component.d.ts +1 -1
- package/dist/components/card/card.component.d.ts.map +1 -1
- package/dist/components/card/card.component.js +4 -1
- package/dist/components/cashback-banner/cashback-banner.component.d.ts +1 -1
- package/dist/components/cashback-banner/cashback-banner.component.d.ts.map +1 -1
- package/dist/components/cashback-banner/cashback-banner.component.js +4 -1
- package/dist/components/category-item/category-item.component.d.ts +1 -4
- package/dist/components/category-item/category-item.component.d.ts.map +1 -1
- package/dist/components/category-item/category-item.component.js +9 -7
- package/dist/components/category-item/category-item.styles.d.ts +2 -2
- package/dist/components/category-item/category-item.styles.js +2 -2
- package/dist/components/category-item/category-item.types.d.ts +2 -2
- package/dist/components/category-item/category-item.types.d.ts.map +1 -1
- package/dist/components/checkbox/checkbox.component.d.ts +1 -1
- package/dist/components/checkbox/checkbox.component.d.ts.map +1 -1
- package/dist/components/checkbox/checkbox.component.js +3 -1
- package/dist/components/event-card/event-card.component.d.ts +4 -0
- package/dist/components/event-card/event-card.component.d.ts.map +1 -0
- package/dist/components/event-card/event-card.component.js +23 -0
- package/dist/components/event-card/event-card.styles.d.ts +15 -0
- package/dist/components/event-card/event-card.styles.d.ts.map +1 -0
- package/dist/components/event-card/event-card.styles.js +62 -0
- package/dist/components/event-card/event-card.types.d.ts +25 -0
- package/dist/components/event-card/event-card.types.d.ts.map +1 -0
- package/dist/components/event-card/event-card.types.js +1 -0
- package/dist/components/event-card/index.d.ts +3 -0
- package/dist/components/event-card/index.d.ts.map +1 -0
- package/dist/components/event-card/index.js +1 -0
- package/dist/components/filter-chip/filter-chip.component.d.ts +1 -4
- package/dist/components/filter-chip/filter-chip.component.d.ts.map +1 -1
- package/dist/components/filter-chip/filter-chip.component.js +4 -1
- package/dist/components/image-gallery/image-gallery.component.d.ts +3 -0
- package/dist/components/image-gallery/image-gallery.component.d.ts.map +1 -0
- package/dist/components/image-gallery/image-gallery.component.js +50 -0
- package/dist/components/image-gallery/image-gallery.styles.d.ts +58 -0
- package/dist/components/image-gallery/image-gallery.styles.d.ts.map +1 -0
- package/dist/components/image-gallery/image-gallery.styles.js +62 -0
- package/dist/components/image-gallery/image-gallery.types.d.ts +11 -0
- package/dist/components/image-gallery/image-gallery.types.d.ts.map +1 -0
- package/dist/components/image-gallery/image-gallery.types.js +1 -0
- package/dist/components/image-viewing/components/image-default-header.d.ts +13 -0
- package/dist/components/image-viewing/components/image-default-header.d.ts.map +1 -0
- package/dist/components/image-viewing/components/image-default-header.js +27 -0
- package/dist/components/image-viewing/components/image-item/image-item.component.android.d.ts +14 -0
- package/dist/components/image-viewing/components/image-item/image-item.component.android.d.ts.map +1 -0
- package/dist/components/image-viewing/components/image-item/image-item.component.android.js +74 -0
- package/dist/components/image-viewing/components/image-item/image-item.component.d.ts +11 -0
- package/dist/components/image-viewing/components/image-item/image-item.component.d.ts.map +1 -0
- package/dist/components/image-viewing/components/image-item/image-item.component.ios.d.ts +14 -0
- package/dist/components/image-viewing/components/image-item/image-item.component.ios.d.ts.map +1 -0
- package/dist/components/image-viewing/components/image-item/image-item.component.ios.js +66 -0
- package/dist/components/image-viewing/components/image-item/image-item.component.js +5 -0
- package/dist/components/image-viewing/components/image-item/image-item.constants.d.ts +4 -0
- package/dist/components/image-viewing/components/image-item/image-item.constants.d.ts.map +1 -0
- package/dist/components/image-viewing/components/image-item/image-item.constants.js +5 -0
- package/dist/components/image-viewing/components/image-item/image-loading.component.d.ts +2 -0
- package/dist/components/image-viewing/components/image-item/image-loading.component.d.ts.map +1 -0
- package/dist/components/image-viewing/components/image-item/image-loading.component.js +14 -0
- package/dist/components/image-viewing/components/status-bar-manager.d.ts +6 -0
- package/dist/components/image-viewing/components/status-bar-manager.d.ts.map +1 -0
- package/dist/components/image-viewing/components/status-bar-manager.js +14 -0
- package/dist/components/image-viewing/hooks/index.d.ts +8 -0
- package/dist/components/image-viewing/hooks/index.d.ts.map +1 -0
- package/dist/components/image-viewing/hooks/index.js +7 -0
- package/dist/components/image-viewing/hooks/useAnimatedComponents.d.ts +19 -0
- package/dist/components/image-viewing/hooks/useAnimatedComponents.d.ts.map +1 -0
- package/dist/components/image-viewing/hooks/useAnimatedComponents.js +41 -0
- package/dist/components/image-viewing/hooks/useDoubleTapToZoom.d.ts +17 -0
- package/dist/components/image-viewing/hooks/useDoubleTapToZoom.d.ts.map +1 -0
- package/dist/components/image-viewing/hooks/useDoubleTapToZoom.js +49 -0
- package/dist/components/image-viewing/hooks/useImageDimensions.d.ts +11 -0
- package/dist/components/image-viewing/hooks/useImageDimensions.d.ts.map +1 -0
- package/dist/components/image-viewing/hooks/useImageDimensions.js +64 -0
- package/dist/components/image-viewing/hooks/useImageIndexChange.d.ts +12 -0
- package/dist/components/image-viewing/hooks/useImageIndexChange.d.ts.map +1 -0
- package/dist/components/image-viewing/hooks/useImageIndexChange.js +20 -0
- package/dist/components/image-viewing/hooks/useImagePrefetch.d.ts +11 -0
- package/dist/components/image-viewing/hooks/useImagePrefetch.d.ts.map +1 -0
- package/dist/components/image-viewing/hooks/useImagePrefetch.js +21 -0
- package/dist/components/image-viewing/hooks/usePanResponder.d.ts +20 -0
- package/dist/components/image-viewing/hooks/usePanResponder.d.ts.map +1 -0
- package/dist/components/image-viewing/hooks/usePanResponder.js +273 -0
- package/dist/components/image-viewing/hooks/useRequestClose.d.ts +10 -0
- package/dist/components/image-viewing/hooks/useRequestClose.d.ts.map +1 -0
- package/dist/components/image-viewing/hooks/useRequestClose.js +20 -0
- package/dist/components/image-viewing/image-viewing.component.d.ts +34 -0
- package/dist/components/image-viewing/image-viewing.component.d.ts.map +1 -0
- package/dist/components/image-viewing/image-viewing.component.js +74 -0
- package/dist/components/image-viewing/image-viewing.types.d.ts +11 -0
- package/dist/components/image-viewing/image-viewing.types.d.ts.map +1 -0
- package/dist/components/image-viewing/image-viewing.types.js +1 -0
- package/dist/components/image-viewing/util.d.ts +47 -0
- package/dist/components/image-viewing/util.d.ts.map +1 -0
- package/dist/components/image-viewing/util.js +99 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +2 -0
- package/dist/components/input/input.component.d.ts +1 -1
- package/dist/components/input/input.component.d.ts.map +1 -1
- package/dist/components/input/input.component.js +3 -1
- package/dist/components/loading/loading.component.d.ts +1 -1
- package/dist/components/loading/loading.component.d.ts.map +1 -1
- package/dist/components/loading/loading.component.js +8 -4
- package/dist/components/order-card/order-card.component.d.ts +1 -1
- package/dist/components/order-card/order-card.component.d.ts.map +1 -1
- package/dist/components/order-card/order-card.component.js +4 -1
- package/dist/components/product-card/product-card.component.d.ts +1 -1
- package/dist/components/product-card/product-card.component.d.ts.map +1 -1
- package/dist/components/product-card/product-card.component.js +3 -1
- package/dist/components/product-highlight/product-highlight.component.d.ts +2 -2
- package/dist/components/product-highlight/product-highlight.component.d.ts.map +1 -1
- package/dist/components/product-highlight/product-highlight.component.js +7 -2
- package/dist/components/product-highlight/product-highlight.d.ts +1 -1
- package/dist/components/product-list-item/product-list-item.component.d.ts +1 -1
- package/dist/components/product-list-item/product-list-item.component.d.ts.map +1 -1
- package/dist/components/product-list-item/product-list-item.component.js +6 -3
- package/dist/components/product-review/product-review.component.d.ts +1 -1
- package/dist/components/product-review/product-review.component.d.ts.map +1 -1
- package/dist/components/product-review/product-review.component.js +6 -3
- package/dist/components/quick-add-product-card/quick-add-product-card.component.d.ts +1 -1
- package/dist/components/quick-add-product-card/quick-add-product-card.component.d.ts.map +1 -1
- package/dist/components/quick-add-product-card/quick-add-product-card.component.js +3 -1
- package/dist/components/radio/radio.component.d.ts +1 -1
- package/dist/components/radio/radio.component.d.ts.map +1 -1
- package/dist/components/radio/radio.component.js +3 -1
- package/dist/components/range-slider/range-slider.component.d.ts +1 -1
- package/dist/components/range-slider/range-slider.component.d.ts.map +1 -1
- package/dist/components/range-slider/range-slider.component.js +3 -1
- package/dist/components/search-button/search-button.component.d.ts +1 -1
- package/dist/components/search-button/search-button.component.d.ts.map +1 -1
- package/dist/components/search-button/search-button.component.js +4 -1
- package/dist/components/seller-box/seller-box.component.d.ts +1 -1
- package/dist/components/seller-box/seller-box.component.d.ts.map +1 -1
- package/dist/components/seller-box/seller-box.component.js +4 -1
- package/dist/components/toggle-switch/toggle-switch.component.d.ts +1 -1
- package/dist/components/toggle-switch/toggle-switch.component.d.ts.map +1 -1
- package/dist/components/toggle-switch/toggle-switch.component.js +3 -1
- package/dist/components/typography/typography.component.d.ts +1 -1
- package/dist/components/typography/typography.component.d.ts.map +1 -1
- package/dist/components/typography/typography.component.js +4 -1
- package/package.json +3 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ActivityIndicator, Dimensions, StyleSheet, View } from "react-native";
|
|
3
|
+
const SCREEN = Dimensions.get("screen");
|
|
4
|
+
const SCREEN_WIDTH = SCREEN.width;
|
|
5
|
+
const SCREEN_HEIGHT = SCREEN.height;
|
|
6
|
+
export const ImageLoading = () => (_jsx(View, { style: styles.loading, children: _jsx(ActivityIndicator, { size: "small", color: "#FFF" }) }));
|
|
7
|
+
const styles = StyleSheet.create({
|
|
8
|
+
loading: {
|
|
9
|
+
width: SCREEN_WIDTH,
|
|
10
|
+
height: SCREEN_HEIGHT,
|
|
11
|
+
alignItems: "center",
|
|
12
|
+
justifyContent: "center",
|
|
13
|
+
},
|
|
14
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-bar-manager.d.ts","sourceRoot":"","sources":["../../../../src/components/image-viewing/components/status-bar-manager.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,UAAU,EAEX,MAAM,cAAc,CAAC;AAEtB,QAAA,MAAM,gBAAgB,GAAI,wBAEvB;IACD,iBAAiB,CAAC,EAAE,UAAU,CAAC,mBAAmB,CAAC,CAAC;CACrD,SAaA,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { Platform, StatusBar, } from "react-native";
|
|
3
|
+
const StatusBarManager = ({ presentationStyle, }) => {
|
|
4
|
+
if (Platform.OS === "ios" || presentationStyle !== "overFullScreen") {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
//Can't get an actual state of app status bar with default RN. Gonna rely on "presentationStyle === overFullScreen" prop and guess application status bar state to be visible in this case.
|
|
8
|
+
StatusBar.setHidden(true);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
return () => StatusBar.setHidden(false);
|
|
11
|
+
}, []);
|
|
12
|
+
return null;
|
|
13
|
+
};
|
|
14
|
+
export default StatusBarManager;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { default as useAnimatedComponents } from "./useAnimatedComponents";
|
|
2
|
+
export { default as useDoubleTapToZoom } from "./useDoubleTapToZoom";
|
|
3
|
+
export { default as useImageDimensions } from "./useImageDimensions";
|
|
4
|
+
export { default as useImageIndexChange } from "./useImageIndexChange";
|
|
5
|
+
export { default as useImagePrefetch } from "./useImagePrefetch";
|
|
6
|
+
export { default as usePanResponder } from "./usePanResponder";
|
|
7
|
+
export { default as useRequestClose } from "./useRequestClose";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/image-viewing/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { default as useAnimatedComponents } from "./useAnimatedComponents";
|
|
2
|
+
export { default as useDoubleTapToZoom } from "./useDoubleTapToZoom";
|
|
3
|
+
export { default as useImageDimensions } from "./useImageDimensions";
|
|
4
|
+
export { default as useImageIndexChange } from "./useImageIndexChange";
|
|
5
|
+
export { default as useImagePrefetch } from "./useImagePrefetch";
|
|
6
|
+
export { default as usePanResponder } from "./usePanResponder";
|
|
7
|
+
export { default as useRequestClose } from "./useRequestClose";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) JOB TODAY S.A. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import { Animated } from "react-native";
|
|
9
|
+
declare const useAnimatedComponents: () => readonly [[{
|
|
10
|
+
translateX: Animated.AnimatedValue;
|
|
11
|
+
}, {
|
|
12
|
+
translateY: Animated.AnimatedValue;
|
|
13
|
+
}], [{
|
|
14
|
+
translateX: Animated.AnimatedValue;
|
|
15
|
+
}, {
|
|
16
|
+
translateY: Animated.AnimatedValue;
|
|
17
|
+
}], (isVisible: boolean) => void];
|
|
18
|
+
export default useAnimatedComponents;
|
|
19
|
+
//# sourceMappingURL=useAnimatedComponents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAnimatedComponents.d.ts","sourceRoot":"","sources":["../../../../src/components/image-viewing/hooks/useAnimatedComponents.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAQxC,QAAA,MAAM,qBAAqB;;;;;;;;gBAIS,OAAO,UAwB1C,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) JOB TODAY S.A. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import { Animated } from "react-native";
|
|
9
|
+
const INITIAL_POSITION = { x: 0, y: 0 };
|
|
10
|
+
const ANIMATION_CONFIG = {
|
|
11
|
+
duration: 200,
|
|
12
|
+
useNativeDriver: true,
|
|
13
|
+
};
|
|
14
|
+
const useAnimatedComponents = () => {
|
|
15
|
+
const headerTranslate = new Animated.ValueXY(INITIAL_POSITION);
|
|
16
|
+
const footerTranslate = new Animated.ValueXY(INITIAL_POSITION);
|
|
17
|
+
const toggleVisible = (isVisible) => {
|
|
18
|
+
if (isVisible) {
|
|
19
|
+
Animated.parallel([
|
|
20
|
+
Animated.timing(headerTranslate.y, { ...ANIMATION_CONFIG, toValue: 0 }),
|
|
21
|
+
Animated.timing(footerTranslate.y, { ...ANIMATION_CONFIG, toValue: 0 }),
|
|
22
|
+
]).start();
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
Animated.parallel([
|
|
26
|
+
Animated.timing(headerTranslate.y, {
|
|
27
|
+
...ANIMATION_CONFIG,
|
|
28
|
+
toValue: -300,
|
|
29
|
+
}),
|
|
30
|
+
Animated.timing(footerTranslate.y, {
|
|
31
|
+
...ANIMATION_CONFIG,
|
|
32
|
+
toValue: 300,
|
|
33
|
+
}),
|
|
34
|
+
]).start();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const headerTransform = headerTranslate.getTranslateTransform();
|
|
38
|
+
const footerTransform = footerTranslate.getTranslateTransform();
|
|
39
|
+
return [headerTransform, footerTransform, toggleVisible];
|
|
40
|
+
};
|
|
41
|
+
export default useAnimatedComponents;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) JOB TODAY S.A. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import React from "react";
|
|
9
|
+
import { NativeSyntheticEvent, NativeTouchEvent, ScrollView } from "react-native";
|
|
10
|
+
import { Dimensions } from "../image-viewing.types";
|
|
11
|
+
/**
|
|
12
|
+
* This is iOS only.
|
|
13
|
+
* Same functionality for Android implemented inside usePanResponder hook.
|
|
14
|
+
*/
|
|
15
|
+
declare function useDoubleTapToZoom(scrollViewRef: React.RefObject<ScrollView>, scaled: boolean, screen: Dimensions): (event: NativeSyntheticEvent<NativeTouchEvent>) => void;
|
|
16
|
+
export default useDoubleTapToZoom;
|
|
17
|
+
//# sourceMappingURL=useDoubleTapToZoom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDoubleTapToZoom.d.ts","sourceRoot":"","sources":["../../../../src/components/image-viewing/hooks/useDoubleTapToZoom.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAsB,MAAM,OAAO,CAAC;AAC3C,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACX,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAKpD;;;GAGG;AACH,iBAAS,kBAAkB,CACzB,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,EAC1C,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,UAAU,WAGR,oBAAoB,CAAC,gBAAgB,CAAC,UAoCjD;AAED,eAAe,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) JOB TODAY S.A. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import { useCallback } from "react";
|
|
9
|
+
const DOUBLE_TAP_DELAY = 300;
|
|
10
|
+
let lastTapTS = null;
|
|
11
|
+
/**
|
|
12
|
+
* This is iOS only.
|
|
13
|
+
* Same functionality for Android implemented inside usePanResponder hook.
|
|
14
|
+
*/
|
|
15
|
+
function useDoubleTapToZoom(scrollViewRef, scaled, screen) {
|
|
16
|
+
const handleDoubleTap = useCallback((event) => {
|
|
17
|
+
var _a;
|
|
18
|
+
const nowTS = new Date().getTime();
|
|
19
|
+
const scrollResponderRef = (_a = scrollViewRef === null || scrollViewRef === void 0 ? void 0 : scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.getScrollResponder();
|
|
20
|
+
if (lastTapTS && nowTS - lastTapTS < DOUBLE_TAP_DELAY) {
|
|
21
|
+
const { pageX, pageY } = event.nativeEvent;
|
|
22
|
+
let targetX = 0;
|
|
23
|
+
let targetY = 0;
|
|
24
|
+
let targetWidth = screen.width;
|
|
25
|
+
let targetHeight = screen.height;
|
|
26
|
+
// Zooming in
|
|
27
|
+
// TODO: Add more precise calculation of targetX, targetY based on touch
|
|
28
|
+
if (!scaled) {
|
|
29
|
+
targetX = pageX / 2;
|
|
30
|
+
targetY = pageY / 2;
|
|
31
|
+
targetWidth = screen.width / 2;
|
|
32
|
+
targetHeight = screen.height / 2;
|
|
33
|
+
}
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
scrollResponderRef === null || scrollResponderRef === void 0 ? void 0 : scrollResponderRef.scrollResponderZoomTo({
|
|
36
|
+
x: targetX,
|
|
37
|
+
y: targetY,
|
|
38
|
+
width: targetWidth,
|
|
39
|
+
height: targetHeight,
|
|
40
|
+
animated: true,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
lastTapTS = nowTS;
|
|
45
|
+
}
|
|
46
|
+
}, [scaled]);
|
|
47
|
+
return handleDoubleTap;
|
|
48
|
+
}
|
|
49
|
+
export default useDoubleTapToZoom;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) JOB TODAY S.A. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import { Dimensions, ImageSource } from "../image-viewing.types";
|
|
9
|
+
declare const useImageDimensions: (image: ImageSource) => Dimensions | null;
|
|
10
|
+
export default useImageDimensions;
|
|
11
|
+
//# sourceMappingURL=useImageDimensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useImageDimensions.d.ts","sourceRoot":"","sources":["../../../../src/components/image-viewing/hooks/useImageDimensions.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAMjE,QAAA,MAAM,kBAAkB,GAAI,OAAO,WAAW,KAAG,UAAU,GAAG,IAiE7D,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) JOB TODAY S.A. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import { useEffect, useState } from "react";
|
|
9
|
+
import { Image } from "react-native";
|
|
10
|
+
import { createCache } from "../util";
|
|
11
|
+
const CACHE_SIZE = 50;
|
|
12
|
+
const imageDimensionsCache = createCache(CACHE_SIZE);
|
|
13
|
+
const useImageDimensions = (image) => {
|
|
14
|
+
const [dimensions, setDimensions] = useState(null);
|
|
15
|
+
const getImageDimensions = (image) => {
|
|
16
|
+
return new Promise((resolve) => {
|
|
17
|
+
if (typeof image == "number") {
|
|
18
|
+
const cacheKey = `${image}`;
|
|
19
|
+
let imageDimensions = imageDimensionsCache.get(cacheKey);
|
|
20
|
+
if (!imageDimensions) {
|
|
21
|
+
const { width, height } = Image.resolveAssetSource(image);
|
|
22
|
+
imageDimensions = { width, height };
|
|
23
|
+
imageDimensionsCache.set(cacheKey, imageDimensions);
|
|
24
|
+
}
|
|
25
|
+
resolve(imageDimensions);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
// @ts-ignore
|
|
29
|
+
if (image.uri) {
|
|
30
|
+
const source = image;
|
|
31
|
+
const cacheKey = source.uri;
|
|
32
|
+
const imageDimensions = imageDimensionsCache.get(cacheKey);
|
|
33
|
+
if (imageDimensions) {
|
|
34
|
+
resolve(imageDimensions);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// @ts-ignore
|
|
38
|
+
Image.getSizeWithHeaders(source.uri, source.headers, (width, height) => {
|
|
39
|
+
imageDimensionsCache.set(cacheKey, { width, height });
|
|
40
|
+
resolve({ width, height });
|
|
41
|
+
}, () => {
|
|
42
|
+
resolve({ width: 0, height: 0 });
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
resolve({ width: 0, height: 0 });
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
let isImageUnmounted = false;
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
getImageDimensions(image).then((dimensions) => {
|
|
54
|
+
if (!isImageUnmounted) {
|
|
55
|
+
setDimensions(dimensions);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return () => {
|
|
59
|
+
isImageUnmounted = true;
|
|
60
|
+
};
|
|
61
|
+
}, [image]);
|
|
62
|
+
return dimensions;
|
|
63
|
+
};
|
|
64
|
+
export default useImageDimensions;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) JOB TODAY S.A. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import { NativeScrollEvent, NativeSyntheticEvent } from "react-native";
|
|
9
|
+
import { Dimensions } from "../image-viewing.types";
|
|
10
|
+
declare const useImageIndexChange: (imageIndex: number, screen: Dimensions) => readonly [number, (event: NativeSyntheticEvent<NativeScrollEvent>) => void];
|
|
11
|
+
export default useImageIndexChange;
|
|
12
|
+
//# sourceMappingURL=useImageIndexChange.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useImageIndexChange.d.ts","sourceRoot":"","sources":["../../../../src/components/image-viewing/hooks/useImageIndexChange.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEvE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,QAAA,MAAM,mBAAmB,GAAI,YAAY,MAAM,EAAE,QAAQ,UAAU,+BAExC,oBAAoB,CAAC,iBAAiB,CAAC,UAcjE,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) JOB TODAY S.A. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import { useState } from "react";
|
|
9
|
+
const useImageIndexChange = (imageIndex, screen) => {
|
|
10
|
+
const [currentImageIndex, setImageIndex] = useState(imageIndex);
|
|
11
|
+
const onScroll = (event) => {
|
|
12
|
+
const { nativeEvent: { contentOffset: { x: scrollX }, }, } = event;
|
|
13
|
+
if (screen.width) {
|
|
14
|
+
const nextIndex = Math.round(scrollX / screen.width);
|
|
15
|
+
setImageIndex(nextIndex < 0 ? 0 : nextIndex);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
return [currentImageIndex, onScroll];
|
|
19
|
+
};
|
|
20
|
+
export default useImageIndexChange;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) JOB TODAY S.A. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import { ImageSource } from "../image-viewing.types";
|
|
9
|
+
declare const useImagePrefetch: (images: ImageSource[]) => void;
|
|
10
|
+
export default useImagePrefetch;
|
|
11
|
+
//# sourceMappingURL=useImagePrefetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useImagePrefetch.d.ts","sourceRoot":"","sources":["../../../../src/components/image-viewing/hooks/useImagePrefetch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,QAAA,MAAM,gBAAgB,GAAI,QAAQ,WAAW,EAAE,SAU9C,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) JOB TODAY S.A. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import { useEffect } from "react";
|
|
9
|
+
import { Image } from "react-native";
|
|
10
|
+
const useImagePrefetch = (images) => {
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
images.forEach((image) => {
|
|
13
|
+
//@ts-ignore
|
|
14
|
+
if (image.uri) {
|
|
15
|
+
//@ts-ignore
|
|
16
|
+
return Image.prefetch(image.uri);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}, []);
|
|
20
|
+
};
|
|
21
|
+
export default useImagePrefetch;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) JOB TODAY S.A. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import { Animated, GestureResponderHandlers } from "react-native";
|
|
9
|
+
import { Position } from "../image-viewing.types";
|
|
10
|
+
type Props = {
|
|
11
|
+
initialScale: number;
|
|
12
|
+
initialTranslate: Position;
|
|
13
|
+
onZoom: (isZoomed: boolean) => void;
|
|
14
|
+
doubleTapToZoomEnabled: boolean;
|
|
15
|
+
onLongPress: () => void;
|
|
16
|
+
delayLongPress: number;
|
|
17
|
+
};
|
|
18
|
+
declare const usePanResponder: ({ initialScale, initialTranslate, onZoom, doubleTapToZoomEnabled, onLongPress, delayLongPress, }: Props) => Readonly<[GestureResponderHandlers, Animated.Value, Animated.ValueXY]>;
|
|
19
|
+
export default usePanResponder;
|
|
20
|
+
//# sourceMappingURL=usePanResponder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePanResponder.d.ts","sourceRoot":"","sources":["../../../../src/components/image-viewing/hooks/usePanResponder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,QAAQ,EAGR,wBAAwB,EAGzB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAiBlD,KAAK,KAAK,GAAG;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,QAAQ,CAAC;IAC3B,MAAM,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC,sBAAsB,EAAE,OAAO,CAAC;IAChC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,QAAA,MAAM,eAAe,GAAI,kGAOtB,KAAK,KAAG,QAAQ,CACjB,CAAC,wBAAwB,EAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,CAuV7D,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) JOB TODAY S.A. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import { useEffect, useMemo } from "react";
|
|
9
|
+
import { Animated, Dimensions, } from "react-native";
|
|
10
|
+
import { createPanResponder, getDistanceBetweenTouches, getImageDimensionsByTranslate, getImageTranslate, } from "../util";
|
|
11
|
+
const SCREEN = Dimensions.get("window");
|
|
12
|
+
const SCREEN_WIDTH = SCREEN.width;
|
|
13
|
+
const SCREEN_HEIGHT = SCREEN.height;
|
|
14
|
+
const MIN_DIMENSION = Math.min(SCREEN_WIDTH, SCREEN_HEIGHT);
|
|
15
|
+
const SCALE_MAX = 2;
|
|
16
|
+
const DOUBLE_TAP_DELAY = 300;
|
|
17
|
+
const OUT_BOUND_MULTIPLIER = 0.75;
|
|
18
|
+
const usePanResponder = ({ initialScale, initialTranslate, onZoom, doubleTapToZoomEnabled, onLongPress, delayLongPress, }) => {
|
|
19
|
+
let numberInitialTouches = 1;
|
|
20
|
+
let initialTouches = [];
|
|
21
|
+
let currentScale = initialScale;
|
|
22
|
+
let currentTranslate = initialTranslate;
|
|
23
|
+
let tmpScale = 0;
|
|
24
|
+
let tmpTranslate = null;
|
|
25
|
+
let isDoubleTapPerformed = false;
|
|
26
|
+
let lastTapTS = null;
|
|
27
|
+
let longPressHandlerRef = null;
|
|
28
|
+
const meaningfulShift = MIN_DIMENSION * 0.01;
|
|
29
|
+
const scaleValue = new Animated.Value(initialScale);
|
|
30
|
+
const translateValue = new Animated.ValueXY(initialTranslate);
|
|
31
|
+
const imageDimensions = getImageDimensionsByTranslate(initialTranslate, SCREEN);
|
|
32
|
+
const getBounds = (scale) => {
|
|
33
|
+
const scaledImageDimensions = {
|
|
34
|
+
width: imageDimensions.width * scale,
|
|
35
|
+
height: imageDimensions.height * scale,
|
|
36
|
+
};
|
|
37
|
+
const translateDelta = getImageTranslate(scaledImageDimensions, SCREEN);
|
|
38
|
+
const left = initialTranslate.x - translateDelta.x;
|
|
39
|
+
const right = left - (scaledImageDimensions.width - SCREEN.width);
|
|
40
|
+
const top = initialTranslate.y - translateDelta.y;
|
|
41
|
+
const bottom = top - (scaledImageDimensions.height - SCREEN.height);
|
|
42
|
+
return [top, left, bottom, right];
|
|
43
|
+
};
|
|
44
|
+
const getTranslateInBounds = (translate, scale) => {
|
|
45
|
+
const inBoundTranslate = { x: translate.x, y: translate.y };
|
|
46
|
+
const [topBound, leftBound, bottomBound, rightBound] = getBounds(scale);
|
|
47
|
+
if (translate.x > leftBound) {
|
|
48
|
+
inBoundTranslate.x = leftBound;
|
|
49
|
+
}
|
|
50
|
+
else if (translate.x < rightBound) {
|
|
51
|
+
inBoundTranslate.x = rightBound;
|
|
52
|
+
}
|
|
53
|
+
if (translate.y > topBound) {
|
|
54
|
+
inBoundTranslate.y = topBound;
|
|
55
|
+
}
|
|
56
|
+
else if (translate.y < bottomBound) {
|
|
57
|
+
inBoundTranslate.y = bottomBound;
|
|
58
|
+
}
|
|
59
|
+
return inBoundTranslate;
|
|
60
|
+
};
|
|
61
|
+
const fitsScreenByWidth = () => imageDimensions.width * currentScale < SCREEN_WIDTH;
|
|
62
|
+
const fitsScreenByHeight = () => imageDimensions.height * currentScale < SCREEN_HEIGHT;
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
scaleValue.addListener(({ value }) => {
|
|
65
|
+
if (typeof onZoom === "function") {
|
|
66
|
+
onZoom(value !== initialScale);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
return () => scaleValue.removeAllListeners();
|
|
70
|
+
});
|
|
71
|
+
const cancelLongPressHandle = () => {
|
|
72
|
+
longPressHandlerRef && clearTimeout(longPressHandlerRef);
|
|
73
|
+
};
|
|
74
|
+
const handlers = {
|
|
75
|
+
onGrant: (_, gestureState) => {
|
|
76
|
+
numberInitialTouches = gestureState.numberActiveTouches;
|
|
77
|
+
if (gestureState.numberActiveTouches > 1)
|
|
78
|
+
return;
|
|
79
|
+
longPressHandlerRef = setTimeout(onLongPress, delayLongPress);
|
|
80
|
+
},
|
|
81
|
+
onStart: (event, gestureState) => {
|
|
82
|
+
initialTouches = event.nativeEvent.touches;
|
|
83
|
+
numberInitialTouches = gestureState.numberActiveTouches;
|
|
84
|
+
if (gestureState.numberActiveTouches > 1)
|
|
85
|
+
return;
|
|
86
|
+
const tapTS = Date.now();
|
|
87
|
+
// Handle double tap event by calculating diff between first and second taps timestamps
|
|
88
|
+
isDoubleTapPerformed = Boolean(lastTapTS && tapTS - lastTapTS < DOUBLE_TAP_DELAY);
|
|
89
|
+
if (doubleTapToZoomEnabled && isDoubleTapPerformed) {
|
|
90
|
+
const isScaled = currentTranslate.x !== initialTranslate.x; // currentScale !== initialScale;
|
|
91
|
+
const { pageX: touchX, pageY: touchY } = event.nativeEvent.touches[0];
|
|
92
|
+
const targetScale = SCALE_MAX;
|
|
93
|
+
const nextScale = isScaled ? initialScale : targetScale;
|
|
94
|
+
const nextTranslate = isScaled
|
|
95
|
+
? initialTranslate
|
|
96
|
+
: getTranslateInBounds({
|
|
97
|
+
x: initialTranslate.x +
|
|
98
|
+
(SCREEN_WIDTH / 2 - touchX) * (targetScale / currentScale),
|
|
99
|
+
y: initialTranslate.y +
|
|
100
|
+
(SCREEN_HEIGHT / 2 - touchY) * (targetScale / currentScale),
|
|
101
|
+
}, targetScale);
|
|
102
|
+
onZoom(!isScaled);
|
|
103
|
+
Animated.parallel([
|
|
104
|
+
Animated.timing(translateValue.x, {
|
|
105
|
+
toValue: nextTranslate.x,
|
|
106
|
+
duration: 300,
|
|
107
|
+
useNativeDriver: true,
|
|
108
|
+
}),
|
|
109
|
+
Animated.timing(translateValue.y, {
|
|
110
|
+
toValue: nextTranslate.y,
|
|
111
|
+
duration: 300,
|
|
112
|
+
useNativeDriver: true,
|
|
113
|
+
}),
|
|
114
|
+
Animated.timing(scaleValue, {
|
|
115
|
+
toValue: nextScale,
|
|
116
|
+
duration: 300,
|
|
117
|
+
useNativeDriver: true,
|
|
118
|
+
}),
|
|
119
|
+
], { stopTogether: false }).start(() => {
|
|
120
|
+
currentScale = nextScale;
|
|
121
|
+
currentTranslate = nextTranslate;
|
|
122
|
+
});
|
|
123
|
+
lastTapTS = null;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
lastTapTS = Date.now();
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
onMove: (event, gestureState) => {
|
|
130
|
+
const { dx, dy } = gestureState;
|
|
131
|
+
if (Math.abs(dx) >= meaningfulShift || Math.abs(dy) >= meaningfulShift) {
|
|
132
|
+
cancelLongPressHandle();
|
|
133
|
+
}
|
|
134
|
+
// Don't need to handle move because double tap in progress (was handled in onStart)
|
|
135
|
+
if (doubleTapToZoomEnabled && isDoubleTapPerformed) {
|
|
136
|
+
cancelLongPressHandle();
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (numberInitialTouches === 1 &&
|
|
140
|
+
gestureState.numberActiveTouches === 2) {
|
|
141
|
+
numberInitialTouches = 2;
|
|
142
|
+
initialTouches = event.nativeEvent.touches;
|
|
143
|
+
}
|
|
144
|
+
const isTapGesture = numberInitialTouches == 1 && gestureState.numberActiveTouches === 1;
|
|
145
|
+
const isPinchGesture = numberInitialTouches === 2 && gestureState.numberActiveTouches === 2;
|
|
146
|
+
if (isPinchGesture) {
|
|
147
|
+
cancelLongPressHandle();
|
|
148
|
+
const initialDistance = getDistanceBetweenTouches(initialTouches);
|
|
149
|
+
const currentDistance = getDistanceBetweenTouches(event.nativeEvent.touches);
|
|
150
|
+
let nextScale = (currentDistance / initialDistance) * currentScale;
|
|
151
|
+
/**
|
|
152
|
+
* In case image is scaling smaller than initial size ->
|
|
153
|
+
* slow down this transition by applying OUT_BOUND_MULTIPLIER
|
|
154
|
+
*/
|
|
155
|
+
if (nextScale < initialScale) {
|
|
156
|
+
nextScale =
|
|
157
|
+
nextScale + (initialScale - nextScale) * OUT_BOUND_MULTIPLIER;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* In case image is scaling down -> move it in direction of initial position
|
|
161
|
+
*/
|
|
162
|
+
if (currentScale > initialScale && currentScale > nextScale) {
|
|
163
|
+
const k = (currentScale - initialScale) / (currentScale - nextScale);
|
|
164
|
+
const nextTranslateX = nextScale < initialScale
|
|
165
|
+
? initialTranslate.x
|
|
166
|
+
: currentTranslate.x -
|
|
167
|
+
(currentTranslate.x - initialTranslate.x) / k;
|
|
168
|
+
const nextTranslateY = nextScale < initialScale
|
|
169
|
+
? initialTranslate.y
|
|
170
|
+
: currentTranslate.y -
|
|
171
|
+
(currentTranslate.y - initialTranslate.y) / k;
|
|
172
|
+
translateValue.x.setValue(nextTranslateX);
|
|
173
|
+
translateValue.y.setValue(nextTranslateY);
|
|
174
|
+
tmpTranslate = { x: nextTranslateX, y: nextTranslateY };
|
|
175
|
+
}
|
|
176
|
+
scaleValue.setValue(nextScale);
|
|
177
|
+
tmpScale = nextScale;
|
|
178
|
+
}
|
|
179
|
+
if (isTapGesture && currentScale > initialScale) {
|
|
180
|
+
const { x, y } = currentTranslate;
|
|
181
|
+
const { dx, dy } = gestureState;
|
|
182
|
+
const [topBound, leftBound, bottomBound, rightBound] = getBounds(currentScale);
|
|
183
|
+
let nextTranslateX = x + dx;
|
|
184
|
+
let nextTranslateY = y + dy;
|
|
185
|
+
if (nextTranslateX > leftBound) {
|
|
186
|
+
nextTranslateX =
|
|
187
|
+
nextTranslateX -
|
|
188
|
+
(nextTranslateX - leftBound) * OUT_BOUND_MULTIPLIER;
|
|
189
|
+
}
|
|
190
|
+
if (nextTranslateX < rightBound) {
|
|
191
|
+
nextTranslateX =
|
|
192
|
+
nextTranslateX -
|
|
193
|
+
(nextTranslateX - rightBound) * OUT_BOUND_MULTIPLIER;
|
|
194
|
+
}
|
|
195
|
+
if (nextTranslateY > topBound) {
|
|
196
|
+
nextTranslateY =
|
|
197
|
+
nextTranslateY - (nextTranslateY - topBound) * OUT_BOUND_MULTIPLIER;
|
|
198
|
+
}
|
|
199
|
+
if (nextTranslateY < bottomBound) {
|
|
200
|
+
nextTranslateY =
|
|
201
|
+
nextTranslateY -
|
|
202
|
+
(nextTranslateY - bottomBound) * OUT_BOUND_MULTIPLIER;
|
|
203
|
+
}
|
|
204
|
+
if (fitsScreenByWidth()) {
|
|
205
|
+
nextTranslateX = x;
|
|
206
|
+
}
|
|
207
|
+
if (fitsScreenByHeight()) {
|
|
208
|
+
nextTranslateY = y;
|
|
209
|
+
}
|
|
210
|
+
translateValue.x.setValue(nextTranslateX);
|
|
211
|
+
translateValue.y.setValue(nextTranslateY);
|
|
212
|
+
tmpTranslate = { x: nextTranslateX, y: nextTranslateY };
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
onRelease: () => {
|
|
216
|
+
cancelLongPressHandle();
|
|
217
|
+
if (isDoubleTapPerformed) {
|
|
218
|
+
isDoubleTapPerformed = false;
|
|
219
|
+
}
|
|
220
|
+
if (tmpScale > 0) {
|
|
221
|
+
if (tmpScale < initialScale || tmpScale > SCALE_MAX) {
|
|
222
|
+
tmpScale = tmpScale < initialScale ? initialScale : SCALE_MAX;
|
|
223
|
+
Animated.timing(scaleValue, {
|
|
224
|
+
toValue: tmpScale,
|
|
225
|
+
duration: 100,
|
|
226
|
+
useNativeDriver: true,
|
|
227
|
+
}).start();
|
|
228
|
+
}
|
|
229
|
+
currentScale = tmpScale;
|
|
230
|
+
tmpScale = 0;
|
|
231
|
+
}
|
|
232
|
+
if (tmpTranslate) {
|
|
233
|
+
const { x, y } = tmpTranslate;
|
|
234
|
+
const [topBound, leftBound, bottomBound, rightBound] = getBounds(currentScale);
|
|
235
|
+
let nextTranslateX = x;
|
|
236
|
+
let nextTranslateY = y;
|
|
237
|
+
if (!fitsScreenByWidth()) {
|
|
238
|
+
if (nextTranslateX > leftBound) {
|
|
239
|
+
nextTranslateX = leftBound;
|
|
240
|
+
}
|
|
241
|
+
else if (nextTranslateX < rightBound) {
|
|
242
|
+
nextTranslateX = rightBound;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (!fitsScreenByHeight()) {
|
|
246
|
+
if (nextTranslateY > topBound) {
|
|
247
|
+
nextTranslateY = topBound;
|
|
248
|
+
}
|
|
249
|
+
else if (nextTranslateY < bottomBound) {
|
|
250
|
+
nextTranslateY = bottomBound;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
Animated.parallel([
|
|
254
|
+
Animated.timing(translateValue.x, {
|
|
255
|
+
toValue: nextTranslateX,
|
|
256
|
+
duration: 100,
|
|
257
|
+
useNativeDriver: true,
|
|
258
|
+
}),
|
|
259
|
+
Animated.timing(translateValue.y, {
|
|
260
|
+
toValue: nextTranslateY,
|
|
261
|
+
duration: 100,
|
|
262
|
+
useNativeDriver: true,
|
|
263
|
+
}),
|
|
264
|
+
]).start();
|
|
265
|
+
currentTranslate = { x: nextTranslateX, y: nextTranslateY };
|
|
266
|
+
tmpTranslate = null;
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
};
|
|
270
|
+
const panResponder = useMemo(() => createPanResponder(handlers), [handlers]);
|
|
271
|
+
return [panResponder.panHandlers, scaleValue, translateValue];
|
|
272
|
+
};
|
|
273
|
+
export default usePanResponder;
|