Skip to content

Instantly share code, notes, and snippets.

@kmagiera
Created March 27, 2020 10:42
Show Gist options
  • Save kmagiera/f52c7ca028460d7f32fb6dcd3b249abc to your computer and use it in GitHub Desktop.
Save kmagiera/f52c7ca028460d7f32fb6dcd3b249abc to your computer and use it in GitHub Desktop.
import React, { Component } from 'react';
import { StyleSheet, View } from 'react-native';
import { PanGestureHandler, State } from 'react-native-gesture-handler';
import Animated from 'react-native-reanimated';
function Snappable() {
const boxStyle = useAnimatedStyle(
context => {
return {
transform: [{ translateX: context.translateX }],
};
},
{ translateX }
);
const gestureEventHandler = useEventWorklet(
(event, context) => {
if (event.state === State.ACTIVE) {
if (event.oldState !== State.ACTIVE) {
// start drag
context.dragStartX = context.translateX;
}
// dragging
context.translateX = context.dragStartX + event.translationX;
} else if (event.state === State.END) {
// end drag
const snapPoint =
context.translateX + event.velocityX * 0.2 < 0 ? -100 : 100;
context.translateX = withSpring(snapPoint);
}
},
{ translateX, dragStartX }
);
return (
<PanGestureHandler
maxPointers={1}
minDist={10}
onGestureEvent={gestureEventHandler}
onHandlerStateChange={gestureEventHandler}>
<Animated.View style={boxStyle}>{children}</Animated.View>
</PanGestureHandler>
);
}
function Example() {
return (
<View style={styles.container}>
<Snappable>
<View style={styles.box} />
</Snappable>
</View>
);
}
const BOX_SIZE = 100;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
box: {
width: BOX_SIZE,
height: BOX_SIZE,
borderColor: '#F5FCFF',
alignSelf: 'center',
backgroundColor: 'plum',
margin: BOX_SIZE / 2,
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment