diff --git a/example/App.tsx b/example/App.tsx index f8e04ad2d2..0dbb64d2e1 100644 --- a/example/App.tsx +++ b/example/App.tsx @@ -55,11 +55,9 @@ import Fling from './src/basic/fling'; import WebStylesResetExample from './src/release_tests/webStylesReset'; import StylusData from './src/release_tests/StylusData'; -import ReanimatedSimple from './src/new_api/reanimated'; import Camera from './src/new_api/camera'; import Transformations from './src/new_api/transformations'; -import OverlapParents from './src/new_api/overlap_parent'; -import OverlapSiblings from './src/new_api/overlap_siblings'; +import Overlap from './src/new_api/overlap'; import Calculator from './src/new_api/calculator'; import BottomSheetNewApi from './src/new_api/bottom_sheet'; import ChatHeadsNewApi from './src/new_api/chat_heads'; @@ -75,6 +73,7 @@ import Pressable from 'src/new_api/pressable'; import EmptyExample from './src/empty/EmptyExample'; import RectButtonBorders from './src/release_tests/rectButton'; import { ListWithHeader } from './src/ListWithHeader'; +import { COLORS } from './src/common'; import { Icon } from '@swmansion/icons'; @@ -92,6 +91,32 @@ const EXAMPLES: ExamplesSection[] = [ sectionTitle: 'Empty', data: [{ name: 'Empty Example', component: EmptyExample }], }, + { + sectionTitle: 'New api', + data: [ + { name: 'Ball with velocity', component: VelocityTest }, + { name: 'Camera', component: Camera }, + { name: 'Transformations', component: Transformations }, + { name: 'Overlap', component: Overlap }, + { name: 'Bottom Sheet', component: BottomSheetNewApi }, + { name: 'Calculator', component: Calculator }, + { name: 'Chat Heads', component: ChatHeadsNewApi }, + { name: 'Drag and drop', component: DragNDrop }, + { name: 'New Swipeable', component: Swipeable }, + { name: 'New Pressable', component: Pressable }, + { name: 'Hover', component: Hover }, + { name: 'Hoverable icons', component: HoverableIcons }, + { + name: 'Horizontal Drawer (Reanimated 2 & RNGH 2)', + component: BetterHorizontalDrawer, + }, + { + name: 'Manual gestures', + component: ManualGestures, + }, + { name: 'Pressable', component: Pressable }, + ], + }, { sectionTitle: 'Basic examples', data: [ @@ -159,36 +184,6 @@ const EXAMPLES: ExamplesSection[] = [ { name: 'Stylus data', component: StylusData }, ], }, - { - sectionTitle: 'New api', - data: [ - { - name: 'Simple interaction with Reanimated', - component: ReanimatedSimple, - }, - { name: 'Hover', component: Hover }, - { name: 'Hoverable icons', component: HoverableIcons }, - { name: 'Camera', component: Camera }, - { name: 'Velocity test', component: VelocityTest }, - { name: 'Transformations', component: Transformations }, - { name: 'Overlap parents', component: OverlapParents }, - { name: 'Overlap siblings', component: OverlapSiblings }, - { name: 'Calculator', component: Calculator }, - { name: 'Bottom Sheet', component: BottomSheetNewApi }, - { name: 'Chat Heads', component: ChatHeadsNewApi }, - { name: 'Drag and drop', component: DragNDrop }, - { name: 'Swipeable', component: Swipeable }, - { name: 'Pressable', component: Pressable }, - { - name: 'Horizontal Drawer (Reanimated 2 & RNGH 2)', - component: BetterHorizontalDrawer, - }, - { - name: 'Manual gestures', - component: ManualGestures, - }, - ], - }, ]; const OPEN_LAST_EXAMPLE_KEY = 'openLastExample'; @@ -213,9 +208,12 @@ export default function App() { cardStyle: { // It's important to set height for the screen, without it scroll doesn't work on web platform. height: Dimensions.get('window').height, + backgroundColor: COLORS.offWhite, }, headerStyle: { - backgroundColor: '#f8f9ff', + backgroundColor: COLORS.offWhite, + borderBottomColor: COLORS.headerSeparator, + borderBottomWidth: 1, }, }}> { private panResponder: { panHandlers?: GestureResponderHandlers } = {}; private previousLeft = 0; private previousTop = 0; - private circleStyles: { style: CircleStyles } = { - style: { left: 0, top: 0, backgroundColor: '#000' }, - }; - private circle: React.ElementRef | null = null; constructor(props: Record) { super(props); @@ -42,45 +38,56 @@ class PanResponderExample extends Component { onPanResponderRelease: this.handlePanResponderEnd, onPanResponderTerminate: this.handlePanResponderEnd, }); + this.previousLeft = 20; this.previousTop = 84; - this.circleStyles = { + + this.state = { style: { + backgroundColor: 'green', left: this.previousLeft, top: this.previousTop, - backgroundColor: 'green', }, }; } - componentDidMount() { - this.updateNativeStyles(); - } - render() { return ( { - this.circle = circle; - }} - style={styles.circle} + style={[styles.circle, this.state.style]} {...this.panResponder.panHandlers} /> ); } private highlight = () => { - this.circleStyles.style.backgroundColor = 'blue'; - this.updateNativeStyles(); + this.setState({ + style: { + backgroundColor: 'blue', + left: this.previousLeft, + top: this.previousTop, + }, + }); }; private unHighlight = () => { - this.circleStyles.style.backgroundColor = 'green'; - this.updateNativeStyles(); + this.setState({ + style: { + backgroundColor: 'green', + left: this.previousLeft, + top: this.previousTop, + }, + }); }; - private updateNativeStyles = () => { - this.circle?.setNativeProps(this.circleStyles); + private setPosition = (x: number, y: number) => { + this.setState({ + style: { + backgroundColor: 'blue', + left: x, + top: y, + }, + }); }; private handleStartShouldSetPanResponder = ( @@ -110,19 +117,19 @@ class PanResponderExample extends Component { _e: GestureResponderEvent, gestureState: PanResponderGestureState ) => { - this.circleStyles.style.left = - this.previousLeft + gestureState.dx * (I18nManager.isRTL ? -1 : 1); - this.circleStyles.style.top = this.previousTop + gestureState.dy; - this.updateNativeStyles(); + this.setPosition( + this.previousLeft + gestureState.dx * (I18nManager.isRTL ? -1 : 1), + this.previousTop + gestureState.dy + ); }; private handlePanResponderEnd = ( _e: GestureResponderEvent, gestureState: PanResponderGestureState ) => { - this.unHighlight(); this.previousLeft += gestureState.dx * (I18nManager.isRTL ? -1 : 1); this.previousTop += gestureState.dy; + this.unHighlight(); }; } @@ -146,7 +153,6 @@ export default class Example extends Component { const styles = StyleSheet.create({ scrollView: { flex: 1, - backgroundColor: '#F5FCFF', }, circle: { width: CIRCLE_SIZE, diff --git a/example/src/common.tsx b/example/src/common.tsx index df96741ea5..0a7436e840 100644 --- a/example/src/common.tsx +++ b/example/src/common.tsx @@ -25,6 +25,11 @@ export class LoremIpsum extends React.Component { } } +export const COLORS = { + offWhite: '#f8f9ff', + headerSeparator: '#eef0ff', +}; + const LOREM_IPSUM = ` Curabitur accumsan sit amet massa quis cursus. Fusce sollicitudin nunc nisl, quis efficitur quam tristique eget. Ut non erat molestie, ullamcorper turpis nec, euismod neque. Praesent aliquam risus ultricies, cursus mi consectetur, bibendum lorem. Nunc eleifend consectetur metus quis pulvinar. In vitae lacus eu nibh tincidunt sagittis ut id lorem. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque sagittis mauris rhoncus, maximus justo in, consequat dolor. Pellentesque ornare laoreet est vulputate vestibulum. Aliquam sit amet metus lorem. diff --git a/example/src/empty/EmptyExample.tsx b/example/src/empty/EmptyExample.tsx index 28aa248fab..900460d6a6 100644 --- a/example/src/empty/EmptyExample.tsx +++ b/example/src/empty/EmptyExample.tsx @@ -4,7 +4,8 @@ import { StyleSheet, Text, View } from 'react-native'; export default function EmptyExample() { return ( - Hello World! + 😞 + It's so empty here ); } @@ -14,6 +15,5 @@ const styles = StyleSheet.create({ flex: 1, justifyContent: 'center', alignItems: 'center', - backgroundColor: '#F5FCFF', }, }); diff --git a/example/src/new_api/bottom_sheet/index.tsx b/example/src/new_api/bottom_sheet/index.tsx index a6ed9062ff..1218963588 100644 --- a/example/src/new_api/bottom_sheet/index.tsx +++ b/example/src/new_api/bottom_sheet/index.tsx @@ -142,7 +142,6 @@ function Example() { const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: '#eef', }, header: { height: HEADER_HEIGTH, diff --git a/example/src/new_api/camera/AnimatedCameraView.tsx b/example/src/new_api/camera/AnimatedCameraView.tsx new file mode 100644 index 0000000000..4e0450c834 --- /dev/null +++ b/example/src/new_api/camera/AnimatedCameraView.tsx @@ -0,0 +1,80 @@ +import React from 'react'; +import { CameraView, useCameraPermissions } from 'expo-camera'; +import { Button, StyleSheet, Text, View } from 'react-native'; +import Animated, { + SharedValue, + useAnimatedProps, +} from 'react-native-reanimated'; + +const AnimatedCameraView = Animated.createAnimatedComponent(CameraView); + +interface CameraProps { + facing: 'front' | 'back'; + zoom: SharedValue; +} + +const Camera = React.forwardRef( + (props: CameraProps, ref: React.Ref) => { + const [permission, requestPermission] = useCameraPermissions(); + + const animatedProps = useAnimatedProps(() => { + return { + zoom: props.zoom.value - 1, + }; + }); + + if (!permission) { + return ; + } + + if (!permission.granted) { + return ( + + + We need your permission to show the camera + +