Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
gorhom committed Sep 5, 2020
1 parent 5a594ad commit e998ca3
Show file tree
Hide file tree
Showing 18 changed files with 602 additions and 431 deletions.
6 changes: 5 additions & 1 deletion example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ const Stack = createStackNavigator<AppStackParamsList>();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Root">
<Stack.Navigator initialRouteName="BasicExample">
<Stack.Screen
name="Root"
getComponent={() => require('./screens/Root').default}
options={{ headerShown: false }}
/>
<Stack.Screen
name="BasicExample"
getComponent={() => require('./screens/BasicExample').default}
/>
{/* basic examples */}
<Stack.Screen
name="FlatListExample"
Expand Down
119 changes: 76 additions & 43 deletions example/src/components/handle/Handle.tsx
Original file line number Diff line number Diff line change
@@ -1,87 +1,120 @@
import React, { useMemo } from 'react';
import { StyleProp, StyleSheet, ViewStyle } from 'react-native';
import { BottomSheetHandleProps } from '@gorhom/bottom-sheet';
import Animated, { interpolate, Extrapolate } from 'react-native-reanimated';
import { transformOrigin, toRad } from 'react-native-redash';
import Animated, {
interpolate,
Extrapolate,
useAnimatedStyle,
useDerivedValue,
} from 'react-native-reanimated';

interface HandleProps extends BottomSheetHandleProps {
style?: StyleProp<ViewStyle>;
}

const toRad = (degrees: number) => {
'worklet';
return degrees * (Math.PI / 180);
};

export const transformOrigin = ({ x, y }, ...transformations) => {
'worklet';
return [
{ translateX: x },
{ translateY: y },
...transformations,
{ translateX: x * -1 },
{ translateY: y * -1 },
];
};

const Handle: React.FC<HandleProps> = ({ style, animatedPositionIndex }) => {
//#region animations
const borderTopRadius = interpolate(animatedPositionIndex, {
inputRange: [1, 2],
outputRange: [20, 0],
extrapolate: Extrapolate.CLAMP,
});
const indicatorTransformOriginY = interpolate(animatedPositionIndex, {
inputRange: [0, 1, 2],
outputRange: [-1, 0, 1],
extrapolate: Extrapolate.CLAMP,
});
const leftIndicatorRotate = interpolate(animatedPositionIndex, {
inputRange: [0, 1, 2],
outputRange: [toRad(-30), 0, toRad(30)],
extrapolate: Extrapolate.CLAMP,
});
const rightIndicatorRotate = interpolate(animatedPositionIndex, {
inputRange: [0, 1, 2],
outputRange: [toRad(30), 0, toRad(-30)],
extrapolate: Extrapolate.CLAMP,
});

const indicatorTransformOriginY = useDerivedValue(() =>
interpolate(animatedPositionIndex.value, [0, 1, 2], [-1, 0, 1])
);
//#endregion

//#region styles
const containerStyle = useMemo(
() => [
styles.header,
style,
{
borderTopLeftRadius: borderTopRadius,
borderTopRightRadius: borderTopRadius,
},
],
() => [styles.header, style],
// eslint-disable-next-line react-hooks/exhaustive-deps
[style]
);
const containerAnimatedStyle = useAnimatedStyle(() => {
const borderTopRadius = interpolate(
animatedPositionIndex.value,
[1, 2],
[20, 0]
);
return {
borderTopLeftRadius: borderTopRadius,
borderTopRightRadius: borderTopRadius,
};
});
const leftIndicatorStyle = useMemo(
() => ({
...styles.indicator,
...styles.leftIndicator,
}),
[]
);
const leftIndicatorAnimatedStyle = useAnimatedStyle(() => {
const leftIndicatorRotate = interpolate(
animatedPositionIndex.value,
[0, 1, 2],
[toRad(-30), 0, toRad(30)]
);
return {
transform: transformOrigin(
{ x: 0, y: indicatorTransformOriginY },
{ x: 0, y: indicatorTransformOriginY.value },
{
rotate: leftIndicatorRotate,
},
{
translateX: -5,
}
),
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[]
);
};
});
const rightIndicatorStyle = useMemo(
() => ({
...styles.indicator,
...styles.rightIndicator,
}),
[]
);
const rightIndicatorAnimatedStyle = useAnimatedStyle(() => {
const rightIndicatorRotate = interpolate(
animatedPositionIndex.value,
[0, 1, 2],
[toRad(30), 0, toRad(-30)]
);
return {
transform: transformOrigin(
{ x: 0, y: indicatorTransformOriginY },
{ x: 0, y: indicatorTransformOriginY.value },
{
rotate: rightIndicatorRotate,
},
{
translateX: 5,
}
),
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[]
);
};
});
//#endregion

// render
return (
<Animated.View style={containerStyle} renderToHardwareTextureAndroid={true}>
<Animated.View style={leftIndicatorStyle} />
<Animated.View style={rightIndicatorStyle} />
<Animated.View
style={[containerStyle, containerAnimatedStyle]}
renderToHardwareTextureAndroid={true}
>
<Animated.View style={[leftIndicatorStyle, leftIndicatorAnimatedStyle]} />
<Animated.View
style={[rightIndicatorStyle, rightIndicatorAnimatedStyle]}
/>
</Animated.View>
);
};
Expand Down
23 changes: 2 additions & 21 deletions example/src/screens/BasicExample.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import React, { useCallback, useMemo, useRef } from 'react';
import { View, StyleSheet, Text } from 'react-native';
import { useHeaderHeight } from '@react-navigation/stack';
import Animated, {
useValue,
interpolate,
concat,
Extrapolate,
} from 'react-native-reanimated';
import { useValue, concat } from 'react-native-reanimated';
import BottomSheet from '@gorhom/bottom-sheet';
import Handle from '../components/handle';
import Button from '../components/button';
Expand All @@ -23,19 +18,6 @@ const BasicExample = () => {
const position = useValue<number>(0);

// styles
const shadowOverlayStyle = useMemo(
() => ({
...styles.shadowOverlay,
opacity: interpolate(position, {
inputRange: [300, 450],
outputRange: [0, 1],
extrapolate: Extrapolate.CLAMP,
}),
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[]
);

// callbacks
const handleSheetChanges = useCallback((index: number) => {
console.log('handleSheetChanges', index);
Expand Down Expand Up @@ -80,7 +62,6 @@ const BasicExample = () => {
onPress={() => handleClosePress()}
/>
<ReText text={concat('Position from bottom: ', position)} />
<Animated.View pointerEvents="none" style={shadowOverlayStyle} />
<BottomSheet
ref={bottomSheetRef}
snapPoints={snapPoints}
Expand Down Expand Up @@ -153,7 +134,7 @@ const BasicExample = () => {
style={styles.buttonContainer}
onPress={() => handleSnapPress(1)}
/> */}
<ContactList type="ScrollView" header={renderHeader} />
<ContactList type="View" count={50} header={renderHeader} />
</BottomSheet>
</View>
);
Expand Down
Loading

0 comments on commit e998ca3

Please sign in to comment.