From 8f3faa7acaa136c25e566814b43aefed5db0d4b7 Mon Sep 17 00:00:00 2001 From: MD MOHIBUR RAHMAN Date: Tue, 4 Oct 2022 14:50:46 +0600 Subject: [PATCH] add slider support --- .../CompareSlider/CompareSlider.tsx | 60 +++ .../components/CompareSlider/index.ts | 3 + .../components/CompareSlider/styles.ts | 21 + .../components/Slider/Slider.tsx | 62 +++ .../components/Slider/index.test.ts | 5 + src/compare-slider/components/Slider/index.ts | 3 + .../components/Slider/styles.ts | 41 ++ src/compare-slider/index.ts | 3 + src/compare-slider/types.ts | 39 ++ src/compare-slider/utils/constants.ts | 4 + src/index.tsx | 472 ++++++------------ 11 files changed, 402 insertions(+), 311 deletions(-) create mode 100644 src/compare-slider/components/CompareSlider/CompareSlider.tsx create mode 100644 src/compare-slider/components/CompareSlider/index.ts create mode 100644 src/compare-slider/components/CompareSlider/styles.ts create mode 100644 src/compare-slider/components/Slider/Slider.tsx create mode 100644 src/compare-slider/components/Slider/index.test.ts create mode 100644 src/compare-slider/components/Slider/index.ts create mode 100644 src/compare-slider/components/Slider/styles.ts create mode 100644 src/compare-slider/index.ts create mode 100644 src/compare-slider/types.ts create mode 100644 src/compare-slider/utils/constants.ts diff --git a/src/compare-slider/components/CompareSlider/CompareSlider.tsx b/src/compare-slider/components/CompareSlider/CompareSlider.tsx new file mode 100644 index 0000000..b67feda --- /dev/null +++ b/src/compare-slider/components/CompareSlider/CompareSlider.tsx @@ -0,0 +1,60 @@ +import React from 'react'; +import { View } from 'react-native'; + +import { Slider } from '../Slider'; +import { ICompareSlider } from '../../types'; + +import { styles } from './styles'; +import Animated, { useAnimatedStyle, useDerivedValue, useSharedValue } from 'react-native-reanimated'; + +export const CompareSlider: React.FC = props => { + const { before, after, containerSize, sliderSize, SliderComponent, sliderStyles, showSeparationLine } = props; + const { width: containerWidth, height: containerHeight } = containerSize; + + const translateX = useSharedValue(0); + const boxWidth = useDerivedValue(() => translateX.value + containerWidth / 2, [translateX]); + + const updateTranslateX = (value: any) => { + 'worklet'; + translateX.value = value; + }; + const animatedStyle = { + before: useAnimatedStyle(() => ({ + width: boxWidth.value, + })), + after: useAnimatedStyle(() => ({ + left: boxWidth.value, + })), + }; + return ( + + + {before} + + {after} + + + + + ); +}; diff --git a/src/compare-slider/components/CompareSlider/index.ts b/src/compare-slider/components/CompareSlider/index.ts new file mode 100644 index 0000000..397cffc --- /dev/null +++ b/src/compare-slider/components/CompareSlider/index.ts @@ -0,0 +1,3 @@ +import { CompareSlider } from './CompareSlider'; + +export { CompareSlider }; diff --git a/src/compare-slider/components/CompareSlider/styles.ts b/src/compare-slider/components/CompareSlider/styles.ts new file mode 100644 index 0000000..eccc35a --- /dev/null +++ b/src/compare-slider/components/CompareSlider/styles.ts @@ -0,0 +1,21 @@ +import { StyleSheet } from 'react-native'; + +export const styles = StyleSheet.create({ + item: { + position: 'absolute', + top: 0, + bottom: 0, + overflow: 'hidden', + }, + itemBefore: { + left: 0, + }, + itemAfter: { + right: 0, + }, + itemAfterChild: { + position: 'absolute', + right: 0, + top: 0, + }, +}); diff --git a/src/compare-slider/components/Slider/Slider.tsx b/src/compare-slider/components/Slider/Slider.tsx new file mode 100644 index 0000000..d0b60f9 --- /dev/null +++ b/src/compare-slider/components/Slider/Slider.tsx @@ -0,0 +1,62 @@ +import React from 'react'; +import { View } from 'react-native'; +import { PanGestureHandler, PanGestureHandlerGestureEvent } from 'react-native-gesture-handler'; + +import { DEFAULT_SLIDER_SIZE } from '../../utils/constants'; +import { IDefaultSliderProps, ISliderProps } from '../../types'; + +import { styles } from './styles'; +import Animated, { useAnimatedGestureHandler, useAnimatedStyle, Value } from 'react-native-reanimated'; +import { clamp } from 'react-native-redash'; + +const initialAnimatedValue = new Value(0); + +const DefaultSlider: React.FC = ({ sliderSize = DEFAULT_SLIDER_SIZE, sliderStyles }) => { + return ( + + + + + ); +}; + +export const Slider: React.FC = props => { + const { + containerSize: { height: containerHeight, width }, + translateX = initialAnimatedValue, + updateTranslateX, + sliderSize = DEFAULT_SLIDER_SIZE, + sliderStyles, + showSeparationLine = true, + separationLineStyles, + SliderComponent = , + } = props; + + const offsetFromEdges = 30; + const boundX = width / 2 - offsetFromEdges; + + const onGestureEvent = useAnimatedGestureHandler({ + onStart: (_event, ctx) => { + ctx.offsetX = translateX.value; + }, + onActive: (event, ctx) => { + translateX.value = clamp(ctx.offsetX + event.translationX, -boundX, boundX); + updateTranslateX(translateX.value); + }, + onEnd: () => {}, + }); + const animatedStyle = useAnimatedStyle(() => { + return { transform: [{ translateX: translateX.value }] }; + }); + + return ( + + + {showSeparationLine && ( + + )} + {SliderComponent} + + + ); +}; diff --git a/src/compare-slider/components/Slider/index.test.ts b/src/compare-slider/components/Slider/index.test.ts new file mode 100644 index 0000000..de8ba0a --- /dev/null +++ b/src/compare-slider/components/Slider/index.test.ts @@ -0,0 +1,5 @@ +import { Slider } from './Slider'; + +it('Run fake test', () => { + expect(Slider).not.toBe(null); +}); diff --git a/src/compare-slider/components/Slider/index.ts b/src/compare-slider/components/Slider/index.ts new file mode 100644 index 0000000..516db3a --- /dev/null +++ b/src/compare-slider/components/Slider/index.ts @@ -0,0 +1,3 @@ +import { Slider } from './Slider'; + +export { Slider }; diff --git a/src/compare-slider/components/Slider/styles.ts b/src/compare-slider/components/Slider/styles.ts new file mode 100644 index 0000000..e3ed7f7 --- /dev/null +++ b/src/compare-slider/components/Slider/styles.ts @@ -0,0 +1,41 @@ +import { StyleSheet } from 'react-native'; +import { SLIDER_ARROW_SIZE, SLIDER_SIZE } from '../../utils/constants'; + +export const styles = StyleSheet.create({ + animatedView: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + alignSelf: 'center', + }, + slider: { + alignItems: 'center', + backgroundColor: '#f5f6fa', + borderRadius: SLIDER_SIZE / 2, + justifyContent: 'center', + }, + sliderArrow: { + width: SLIDER_ARROW_SIZE, + height: SLIDER_ARROW_SIZE, + position: 'absolute', + borderTopWidth: SLIDER_ARROW_SIZE, + borderTopColor: 'transparent', + borderBottomWidth: SLIDER_ARROW_SIZE, + borderBottomColor: 'transparent', + }, + sliderArrowRight: { + right: 8, + borderLeftWidth: SLIDER_ARROW_SIZE, + borderLeftColor: 'green', + }, + sliderArrowLeft: { + left: 8, + borderRightWidth: SLIDER_ARROW_SIZE, + borderRightColor: 'green', + }, + separationLine: { + backgroundColor: '#f5f6fa', + width: 5, + position: 'absolute', + }, +}); diff --git a/src/compare-slider/index.ts b/src/compare-slider/index.ts new file mode 100644 index 0000000..bd1f4ee --- /dev/null +++ b/src/compare-slider/index.ts @@ -0,0 +1,3 @@ +import { CompareSlider } from './components/CompareSlider'; + +export { CompareSlider }; diff --git a/src/compare-slider/types.ts b/src/compare-slider/types.ts new file mode 100644 index 0000000..514b2b6 --- /dev/null +++ b/src/compare-slider/types.ts @@ -0,0 +1,39 @@ +// All types for src/components/** goes here +// and some types can be inside component - not needed for external usage + +import React from 'react'; +import { ViewStyle } from 'react-native'; + +export interface ISize { + width: number; + height: number; +} + +export interface IDefaultSliderProps { + sliderSize?: ISize; + sliderStyles?: ViewStyle; +} + +export interface ISliderProps extends IDefaultSliderProps { + translateX: any; + updateTranslateX: any; + SliderComponent?: React.ReactNode; + containerSize: ISize; + showSeparationLine?: boolean; + separationLineStyles?: ViewStyle; +} + +export interface ICompareSlider { + before: React.ReactNode; + after: React.ReactNode; + containerSize: ISize; + + // Slider props + sliderSize?: ISize; + SliderComponent?: React.ReactNode; + sliderStyles?: ViewStyle; + + // Separation line + showSeparationLine?: boolean; + separationLineStyles?: ViewStyle; +} diff --git a/src/compare-slider/utils/constants.ts b/src/compare-slider/utils/constants.ts new file mode 100644 index 0000000..de274a1 --- /dev/null +++ b/src/compare-slider/utils/constants.ts @@ -0,0 +1,4 @@ +export const SLIDER_SIZE = 50; +export const DEFAULT_SLIDER_SIZE = { width: SLIDER_SIZE, height: SLIDER_SIZE }; + +export const SLIDER_ARROW_SIZE = 10; diff --git a/src/index.tsx b/src/index.tsx index 21b9f78..09ca0e7 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,23 +1,11 @@ -import React, { - useCallback, - useEffect, - useImperativeHandle, - useRef, - useState, -} from 'react'; -import { - I18nManager, - Image, - StyleSheet, - useWindowDimensions, - View, - ViewStyle, -} from 'react-native'; +import React, { useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react'; +import { I18nManager, Image, ImageEditor, StyleSheet, Text, useWindowDimensions, View, ViewStyle } from 'react-native'; import Animated, { useAnimatedStyle, useDerivedValue, useSharedValue, withTiming, + withDecay, useAnimatedReaction, runOnJS, withSpring, @@ -27,14 +15,13 @@ import { Gesture, GestureDetector } from 'react-native-gesture-handler'; import { useVector } from 'react-native-redash'; import { clamp, withDecaySpring, withRubberBandClamp } from './utils'; -import { - EventsCallbacks, - ItemRef, - Props, - RenderItem, - RenderItemInfo, -} from './types'; +import { EventsCallbacks, FaceRectType, ItemRef, Props, RenderItem, RenderItemInfo } from './types'; import { LANDSCAPE, POTRAIT } from './utils/constants'; +import { getFaceRects } from './utils/getFaceRects'; +import { getScaleToFit } from './utils/getScaleToFit'; +import { setImageTypeOnUseState } from './utils/setImageTypeOnUseState'; +import { CompareSlider } from './compare-slider'; +import { getCroppedImageURI } from './utils/getCroppedImages'; const rtl = I18nManager.isRTL; @@ -42,25 +29,18 @@ const DOUBLE_TAP_SCALE = 3; const MAX_SCALE = 6; const SPACE_BETWEEN_IMAGES = 40; -export const snapPoint = ( - value: number, - velocity: number, - points: ReadonlyArray -): number => { +export const snapPoint = (value: number, velocity: number, points: ReadonlyArray): number => { 'worklet'; const point = value + 0.25 * velocity; - const deltas = points.map((p) => Math.abs(point - p)); + const deltas = points.map(p => Math.abs(point - p)); const minDelta = Math.min.apply(null, deltas); - return points.filter((p) => Math.abs(point - p) === minDelta)[0]; + return points.filter(p => Math.abs(point - p) === minDelta)[0]; }; -const defaultRenderImage = ({ - item, - setImageDimensions, -}: RenderItemInfo) => { +const defaultRenderImage = ({ item, setImageDimensions }: RenderItemInfo) => { return ( { + onLoad={e => { const { height: h, width: w } = e.nativeEvent.source; setImageDimensions({ height: h, width: w }); }} @@ -70,16 +50,17 @@ const defaultRenderImage = ({ /> ); }; + const ResizableImage = React.memo( ({ - // setAllCroppedImageURI, - // sliderSize, - // SliderComponent, - // showSeparationLine, - // separationLineStyles, - // compareSlider, - // leftImage, - // rightImage, + setAllCroppedImageURI, + sliderSize, + SliderComponent, + showSeparationLine, + separationLineStyles, + compareSlider, + leftImage, + rightImage, shouldScaleToFit, // imageType, // scaleToFit, @@ -122,81 +103,59 @@ const ResizableImage = React.memo( const [imageType, setImageType] = useState(undefined); - // useEffect(() => { - // (async () => { - // if (!compareSlider) { - // try { - // let newWidth = 0; - // let newHeight = 0; - - // Image.getSize(leftImage.uri, async (width, height) => { - // newWidth = width; - // newHeight = height; - // await getFaceRects( - // item, - // newWidth, - // newHeight, - // width, - // setFaceRects - // ); // aka viewPortWidth - // if (shouldScaleToFit) - // await getScaleToFit(newWidth, newHeight, setScaleToFit); - // await setImageTypeOnUseState(newWidth, newHeight, setImageType); - // }); - // } catch (error) { - // console.warn(`[FaceDetect] error in useEffect === ${error}`); - // console.warn( - // `[FaceDetect] error in useEffect === ${JSON.stringify(error)}` - // ); - // } - // } - // })(); - // }, [ - // item, - // shouldScaleToFit, - // compareSlider, - // // setFaceRects, setScaleToFit, setImageType - // ]); - // useEffect(() => { - // (async () => { - // if (compareSlider && rightImage) { - // try { - // let newWidth = 0; - // let newHeight = 0; - - // // @ts-ignore - // Image.getSize(rightImage.uri, async (width, height) => { - // newWidth = width; - // newHeight = height; - - // // @ts-ignore - // const detectdeFaceRects = await getFaceRects( - // rightImage.uri, - // newWidth, - // newHeight, - // width - // ); // aka viewPortWidth - // const allCroppedImages = await getCroppedImageURI( - // rightImage.uri, - // detectdeFaceRects - // ); - // setAllCroppedImageURI(allCroppedImages); - - // if (shouldScaleToFit) - // getScaleToFit(newWidth, newHeight, setScaleToFit); - // setImageTypeOnUseState(newWidth, newHeight, setImageType); - // }); - // } catch (error) { - // console.warn(`[awesome-gallery] error in useEffect === ${error}`); - // console.warn( - // `[awesome-gallery] error in useEffect === ${JSON.stringify( - // error - // )}` - // ); - // } - // } - // })(); - // }, [rightImage, shouldScaleToFit, compareSlider]); + useEffect(() => { + (async () => { + if (!compareSlider) { + try { + let newWidth = 0; + let newHeight = 0; + + Image.getSize(leftImage.uri, async (width, height) => { + newWidth = width; + newHeight = height; + await getFaceRects(item, newWidth, newHeight, width, setFaceRects); // aka viewPortWidth + if (shouldScaleToFit) await getScaleToFit(newWidth, newHeight, setScaleToFit); + await setImageTypeOnUseState(newWidth, newHeight, setImageType); + }); + } catch (error) { + console.warn(`[FaceDetect] error in useEffect === ${error}`); + console.warn(`[FaceDetect] error in useEffect === ${JSON.stringify(error)}`); + } + } + })(); + }, [ + item, + shouldScaleToFit, + compareSlider, + // setFaceRects, setScaleToFit, setImageType + ]); + useEffect(() => { + (async () => { + if (compareSlider && rightImage) { + try { + let newWidth = 0; + let newHeight = 0; + + // @ts-ignore + Image.getSize(rightImage.uri, async (width, height) => { + newWidth = width; + newHeight = height; + + // @ts-ignore + const detectdeFaceRects = await getFaceRects(rightImage.uri, newWidth, newHeight, width); // aka viewPortWidth + const allCroppedImages = await getCroppedImageURI(rightImage.uri, detectdeFaceRects); + setAllCroppedImageURI(allCroppedImages); + + if (shouldScaleToFit) getScaleToFit(newWidth, newHeight, setScaleToFit); + setImageTypeOnUseState(newWidth, newHeight, setImageType); + }); + } catch (error) { + console.warn(`[awesome-gallery] error in useEffect === ${error}`); + console.warn(`[awesome-gallery] error in useEffect === ${JSON.stringify(error)}`); + } + } + })(); + }, [rightImage, shouldScaleToFit, compareSlider]); const CENTER = { x: width / 2, @@ -216,10 +175,7 @@ const ResizableImage = React.memo( const originalLayout = useVector(width, 0); const layout = useVector(width, 0); - const isActive = useDerivedValue( - () => currentIndex.value === index, - [currentIndex] - ); + const isActive = useDerivedValue(() => currentIndex.value === index, [currentIndex]); const [newFaceRects, setNewFaceRects] = useState(); useEffect(() => { @@ -260,7 +216,7 @@ const ResizableImage = React.memo( () => { return scale.value; }, - (scaleReaction) => { + scaleReaction => { if (!onScaleChange) { return; } @@ -270,19 +226,13 @@ const ResizableImage = React.memo( return; } - if ( - scaleReaction > onScaleChangeRange.start && - scaleReaction < onScaleChangeRange.end - ) { + if (scaleReaction > onScaleChangeRange.start && scaleReaction < onScaleChangeRange.end) { runOnJS(onScaleChange)(scaleReaction); } } ); - const setAdjustedFocal = ({ - focalX, - focalY, - }: Record<'focalX' | 'focalY', number>) => { + const setAdjustedFocal = ({ focalX, focalY }: Record<'focalX' | 'focalY', number>) => { 'worklet'; adjustedFocal.x.value = focalX - (CENTER.x + offset.x.value); @@ -360,9 +310,7 @@ const ResizableImage = React.memo( const getPosition = (i?: number) => { 'worklet'; - return ( - -(width + emptySpaceWidth) * (typeof i !== 'undefined' ? i : index) - ); + return -(width + emptySpaceWidth) * (typeof i !== 'undefined' ? i : index); }; const getIndexFromPosition = (position: number) => { @@ -413,18 +361,10 @@ const ResizableImage = React.memo( scale.value = withTiming(doubleTapScale); offset.x.value = withTiming( - clampX( - adjustedFocal.x.value + - -1 * doubleTapScale * adjustedFocal.x.value, - doubleTapScale - ) + clampX(adjustedFocal.x.value + -1 * doubleTapScale * adjustedFocal.x.value, doubleTapScale) ); offset.y.value = withTiming( - clampY( - adjustedFocal.y.value + - -1 * doubleTapScale * adjustedFocal.y.value, - doubleTapScale - ) + clampY(adjustedFocal.y.value + -1 * doubleTapScale * adjustedFocal.y.value, doubleTapScale) ); }, }); @@ -433,15 +373,8 @@ const ResizableImage = React.memo( const animatedStyle = useAnimatedStyle(() => { const isNextForLast = - loop && - isFirst && - currentIndex.value === length - 1 && - translateX.value < getPosition(length - 1); - const isPrevForFirst = - loop && - isLast && - currentIndex.value === 0 && - translateX.value > getPosition(0); + loop && isFirst && currentIndex.value === length - 1 && translateX.value < getPosition(length - 1); + const isPrevForFirst = loop && isLast && currentIndex.value === 0 && translateX.value > getPosition(0); return { transform: [ { @@ -457,10 +390,7 @@ const ResizableImage = React.memo( }; }); - const setImageDimensions: RenderItemInfo['setImageDimensions'] = ({ - width: w, - height: h, - }) => { + const setImageDimensions: RenderItemInfo['setImageDimensions'] = ({ width: w, height: h }) => { originalLayout.x.value = w; originalLayout.y.value = h; @@ -506,8 +436,7 @@ const ResizableImage = React.memo( const distanceY = useDerivedValue(() => { if (scale.value <= 1 && faceRects?.length > 0) { return newFaceRects ? newFaceRects[0].y : 0; - } else if (scale.value > 1 && faceRects?.length > 0) - return newFaceRects[0].y * scale.value; + } else if (scale.value > 1 && faceRects?.length > 0) return newFaceRects[0].y * scale.value; return newFaceRects; }, [scale.value, newFaceRects]); @@ -531,25 +460,14 @@ const ResizableImage = React.memo( const edgeY = getEdgeY(); const distanceFromViewPortX = distanceX.value - edgeX[1] + offsetXvalue; - if ( - distanceFromViewPortX <= width && - distanceY.value + offsetYvalue >= edgeY[1] - ) { + if (distanceFromViewPortX <= width && distanceY.value + offsetYvalue >= edgeY[1]) { console.log(`xxxxxxxxxxxxxxxxxxx face detected ------------`); if (setIsFaceDetected) runOnJS(setIsFaceDetected)(true); } else { if (setIsFaceDetected) runOnJS(setIsFaceDetected)(false); } }, - [ - offset.x.value, - width, - distanceX.value, - offset.y.value, - distanceY.value, - height, - setIsFaceDetected, - ] + [offset.x.value, width, distanceX.value, offset.y.value, distanceY.value, height, setIsFaceDetected] ); const pinchGesture = Gesture.Pinch() @@ -575,23 +493,14 @@ const ResizableImage = React.memo( if (!isActive.value) return; if (numberOfPointers !== 2) return; - const nextScale = withRubberBandClamp( - s * scaleOffset.value, - 0.55, - maxScale, - [1, maxScale] - ); + const nextScale = withRubberBandClamp(s * scaleOffset.value, 0.55, maxScale, [1, maxScale]); scale.value = nextScale; setAdjustedFocal({ focalX, focalY }); - translation.x.value = - adjustedFocal.x.value + - ((-1 * nextScale) / scaleOffset.value) * origin.x.value; - translation.y.value = - adjustedFocal.y.value + - ((-1 * nextScale) / scaleOffset.value) * origin.y.value; + translation.x.value = adjustedFocal.x.value + ((-1 * nextScale) / scaleOffset.value) * origin.x.value; + translation.y.value = adjustedFocal.y.value + ((-1 * nextScale) / scaleOffset.value) * origin.y.value; }) .onEnd(() => { 'worklet'; @@ -609,14 +518,12 @@ const ResizableImage = React.memo( const nextTransX = scale.value > maxScale - ? adjustedFocal.x.value + - ((-1 * maxScale) / scaleOffset.value) * origin.x.value + ? adjustedFocal.x.value + ((-1 * maxScale) / scaleOffset.value) * origin.x.value : translation.x.value; const nextTransY = scale.value > maxScale - ? adjustedFocal.y.value + - ((-1 * maxScale) / scaleOffset.value) * origin.y.value + ? adjustedFocal.y.value + ((-1 * maxScale) / scaleOffset.value) * origin.y.value : translation.y.value; if (scale.value > maxScale) { @@ -635,9 +542,7 @@ const ResizableImage = React.memo( } if (newWidth + diffX < width) { - translation.x.value = withTiming( - nextTransX + width - (newWidth + diffX) - ); + translation.x.value = withTiming(nextTransX + width - (newWidth + diffX)); moved = true; } if (!moved) { @@ -658,9 +563,7 @@ const ResizableImage = React.memo( } if (newHeight + diffY < height) { - translation.y.value = withTiming( - nextTransY + height - (newHeight + diffY) - ); + translation.y.value = withTiming(nextTransY + height - (newHeight + diffY)); moved = true; } if (!moved) { @@ -719,39 +622,27 @@ const ResizableImage = React.memo( // for x const x = getEdgeX(); if (!isVertical.value || scale.value > 1) { - const clampedX = clamp( - translationX, - x[0] - offset.x.value, - x[1] - offset.x.value - ); + const clampedX = clamp(translationX, x[0] - offset.x.value, x[1] - offset.x.value); const transX = rtl ? initialTranslateX.value - translationX + clampedX : initialTranslateX.value + translationX - clampedX; - if ( - hideAdjacentImagesOnScaledImage && - disableTransitionOnScaledImage - ) { - const disabledTransition = - disableTransitionOnScaledImage && scale.value > 1; + if (hideAdjacentImagesOnScaledImage && disableTransitionOnScaledImage) { + const disabledTransition = disableTransitionOnScaledImage && scale.value > 1; const moveX = withRubberBandClamp( transX, 0.55, width, - disabledTransition - ? [getPosition(index), getPosition(index + 1)] - : [getPosition(length - 1), 0] + disabledTransition ? [getPosition(index), getPosition(index + 1)] : [getPosition(length - 1), 0] ); if (!disabledTransition) { translateX.value = moveX; } if (disabledTransition) { - translation.x.value = rtl - ? clampedX - moveX + translateX.value - : clampedX + moveX - translateX.value; + translation.x.value = rtl ? clampedX - moveX + translateX.value : clampedX + moveX - translateX.value; } else { translation.x.value = clampedX; } @@ -776,12 +667,10 @@ const ResizableImage = React.memo( const edgeY = getEdgeY(); const newHeight = scale.value * layout.y.value; if (newHeight > height) { - translation.y.value = withRubberBandClamp( - translationY, - 0.55, - newHeight, - [edgeY[0] - offset.y.value, edgeY[1] - offset.y.value] - ); + translation.y.value = withRubberBandClamp(translationY, 0.55, newHeight, [ + edgeY[0] - offset.y.value, + edgeY[1] - offset.y.value, + ]); } else if ( !(scale.value === 1 && translateX.value !== getPosition()) && (!disableSwipeUp || translationY >= 0) @@ -791,9 +680,7 @@ const ResizableImage = React.memo( if (isVertical.value && newHeight <= height) { const destY = translationY + velocityY * 0.2; - shouldClose.value = disableSwipeUp - ? destY > 220 - : Math.abs(destY) > 220; + shouldClose.value = disableSwipeUp ? destY > 220 : Math.abs(destY) > 220; } }) .onEnd(({ velocityX, velocityY }) => { @@ -805,7 +692,7 @@ const ResizableImage = React.memo( const edgeX = getEdgeX(); if ( Math.abs(translateX.value - getPosition()) >= 0 && - edgeX.some((x) => x === translation.x.value + offset.x.value) + edgeX.some(x => x === translation.x.value + offset.x.value) ) { let snapPoints = [index - 1, index, index + 1] .filter((_, y) => { @@ -819,17 +706,13 @@ const ResizableImage = React.memo( } return true; }) - .map((i) => getPosition(i)); + .map(i => getPosition(i)); if (disableTransitionOnScaledImage && scale.value > 1) { snapPoints = [getPosition(index)]; } - let snapTo = snapPoint( - translateX.value, - rtl ? -velocityX : velocityX, - snapPoints - ); + let snapTo = snapPoint(translateX.value, rtl ? -velocityX : velocityX, snapPoints); const nextIndex = getIndexFromPosition(snapTo); @@ -865,12 +748,9 @@ const ResizableImage = React.memo( offset.x.value = withDecaySpring( { velocity: velocityX, - clamp: [ - -(newWidth - width) / 2 - translation.x.value, - (newWidth - width) / 2 - translation.x.value, - ], + clamp: [-(newWidth - width) / 2 - translation.x.value, (newWidth - width) / 2 - translation.x.value], }, - (edge) => { + edge => { 'worklet'; isMoving.x.value = 0; if (edge.isEdge) { @@ -879,9 +759,7 @@ const ResizableImage = React.memo( } ); } - console.log( - `[panOnEnd] offset.x_y === ${offset.x.value}_${offset.y.value}` - ); + console.log(`[panOnEnd] offset.x_y === ${offset.x.value}_${offset.y.value}`); // // no applicable for our use case // if (onSwipeToClose && shouldClose.value) { // offset.y.value = withDecay({ @@ -898,12 +776,9 @@ const ResizableImage = React.memo( offset.y.value = withDecaySpring( { velocity: velocityY, - clamp: [ - -(newHeight - height) / 2 - translation.y.value, - (newHeight - height) / 2 - translation.y.value, - ], + clamp: [-(newHeight - height) / 2 - translation.y.value, (newHeight - height) / 2 - translation.y.value], }, - (edge) => { + edge => { 'worklet'; isMoving.y.value = 0; if (edge.isEdge) { @@ -912,8 +787,7 @@ const ResizableImage = React.memo( } ); } else { - const diffY = - translation.y.value + offset.y.value - (newHeight - height) / 2; + const diffY = translation.y.value + offset.y.value - (newHeight - height) / 2; if (newHeight <= height && diffY !== height - diffY - newHeight) { const moveTo = diffY - (height - newHeight) / 2; @@ -970,18 +844,10 @@ const ResizableImage = React.memo( setAdjustedFocal({ focalX: x, focalY: y }); offset.x.value = withTiming( - clampX( - adjustedFocal.x.value + - -1 * doubleTapScale * adjustedFocal.x.value, - doubleTapScale - ) + clampX(adjustedFocal.x.value + -1 * doubleTapScale * adjustedFocal.x.value, doubleTapScale) ); offset.y.value = withTiming( - clampY( - adjustedFocal.y.value + - -1 * doubleTapScale * adjustedFocal.y.value, - doubleTapScale - ) + clampY(adjustedFocal.y.value + -1 * doubleTapScale * adjustedFocal.y.value, doubleTapScale) ); } else { resetValues(); @@ -1005,20 +871,16 @@ const ResizableImage = React.memo( return ( + )}> - {/* {compareSlider ? ( + {compareSlider ? ( { + onLoad={e => { const { height: h, width: w } = e.nativeEvent.source; setImageDimensions({ height: h, width: w }); }} @@ -1042,7 +904,7 @@ const ResizableImage = React.memo( after={ { + onLoad={e => { const { height: h, width: w } = e.nativeEvent.source; setImageDimensions({ height: h, width: w }); }} @@ -1069,22 +931,22 @@ const ResizableImage = React.memo( separationLineStyles={separationLineStyles} containerSize={{ width: width, height: height }} /> - ) : ( */} - - {renderItem(itemProps)} - - - {/* )} */} + ) : ( + + {renderItem(itemProps)} + + + )} ); @@ -1136,13 +998,13 @@ type GalleryProps = EventsCallbacks & { const GalleryComponent = ( { - // setAllCroppedImageURI, - // sliderSize, - // SliderComponent, - // showSeparationLine, - // separationLineStyles, - // leftImage, - // compareSlider, + setAllCroppedImageURI, + sliderSize, + SliderComponent, + showSeparationLine, + separationLineStyles, + leftImage, + compareSlider, shouldScaleToFit = true, setIsFaceDetected, // faceRects, @@ -1170,7 +1032,7 @@ const GalleryComponent = ( }: GalleryProps, ref: GalleryReactRef ) => { - const tempData = data; + const tempData = compareSlider ? [`a`] : data; const windowDimensions = useWindowDimensions(); const dimensions = containerDimensions || windowDimensions; @@ -1184,9 +1046,7 @@ const GalleryComponent = ( refs.current[index] = value; }, []); - const translateX = useSharedValue( - initialIndex * -(dimensions.width + emptySpaceWidth) - ); + const translateX = useSharedValue(initialIndex * -(dimensions.width + emptySpaceWidth)); const currentIndex = useSharedValue(initialIndex); @@ -1204,7 +1064,7 @@ const GalleryComponent = ( useAnimatedReaction( () => currentIndex.value, - (newIndex) => runOnJS(changeIndex)(newIndex), + newIndex => runOnJS(changeIndex)(newIndex), [currentIndex, changeIndex] ); @@ -1221,17 +1081,17 @@ const GalleryComponent = ( translateX.value = newIndex * -(dimensions.width + emptySpaceWidth); }, setFocal({ x, y }: any) { - refs.current?.forEach((itemRef) => { + refs.current?.forEach(itemRef => { itemRef.setFocal({ x, y }); }); }, zoomIn({ x, y }) { - refs.current?.forEach((itemRef) => { + refs.current?.forEach(itemRef => { itemRef.zoomIn({ x, y }); }); }, reset(animated = false) { - refs.current?.forEach((itemRef) => itemRef.reset(animated)); + refs.current?.forEach(itemRef => itemRef.reset(animated)); }, })); @@ -1256,33 +1116,23 @@ const GalleryComponent = ( (Math.abs(i - index) < tempData.length - (numToRender - 1) / 2 && Math.abs(i - index) > (numToRender - 1) / 2); - const hidden = - Math.abs(i - index) > (numToRender - 1) / 2 && outOfLoopRenderRange; + const hidden = Math.abs(i - index) > (numToRender - 1) / 2 && outOfLoopRenderRange; return ( + key={keyExtractor ? keyExtractor(item, i) : item.id || item.key || item._id || item} + style={[dimensions, isFirst ? {} : { marginLeft: emptySpaceWidth }, { zIndex: index === i ? 1 : 0 }]}> {hidden ? null : ( // @ts-ignore