├── .watchmanconfig ├── assets ├── icon.png └── splash.png ├── babel.config.js ├── .gitignore ├── package.json ├── app.json └── App.js /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benawad/reanimated-dnd-example/HEAD/assets/icon.png -------------------------------------------------------------------------------- /assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benawad/reanimated-dnd-example/HEAD/assets/splash.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/**/* 2 | .expo/* 3 | npm-debug.* 4 | *.jks 5 | *.p12 6 | *.key 7 | *.mobileprovision 8 | *.orig.* 9 | web-build/ 10 | web-report/ 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "node_modules/expo/AppEntry.js", 3 | "scripts": { 4 | "start": "expo start", 5 | "android": "expo start --android", 6 | "ios": "expo start --ios", 7 | "web": "expo start --web", 8 | "eject": "expo eject" 9 | }, 10 | "dependencies": { 11 | "expo": "^33.0.0", 12 | "react": "16.8.3", 13 | "react-dom": "^16.8.6", 14 | "react-native": "https://github.com/expo/react-native/archive/sdk-33.0.0.tar.gz", 15 | "react-native-web": "^0.11.4" 16 | }, 17 | "devDependencies": { 18 | "babel-preset-expo": "^5.1.1" 19 | }, 20 | "private": true 21 | } -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "reanimated-example", 4 | "slug": "reanimated-example", 5 | "privacy": "public", 6 | "sdkVersion": "33.0.0", 7 | "platforms": [ 8 | "ios", 9 | "android", 10 | "web" 11 | ], 12 | "version": "1.0.0", 13 | "orientation": "portrait", 14 | "icon": "./assets/icon.png", 15 | "splash": { 16 | "image": "./assets/splash.png", 17 | "resizeMode": "contain", 18 | "backgroundColor": "#ffffff" 19 | }, 20 | "updates": { 21 | "fallbackToCacheTimeout": 0 22 | }, 23 | "assetBundlePatterns": [ 24 | "**/*" 25 | ], 26 | "ios": { 27 | "supportsTablet": true 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /App.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyleSheet, View, Dimensions, Text, SafeAreaView } from "react-native"; 3 | import Animated from "react-native-reanimated"; 4 | import { PanGestureHandler, State } from "react-native-gesture-handler"; 5 | const { width } = Dimensions.get("window"); 6 | 7 | const { cond, eq, add, call, set, Value, event, or } = Animated; 8 | 9 | export default class Example extends React.Component { 10 | constructor(props) { 11 | super(props); 12 | this.dragX = new Value(0); 13 | this.dragY = new Value(0); 14 | this.absoluteY = new Value(100); 15 | this.offsetX = new Value(width / 2); 16 | this.offsetY = new Value(100); 17 | this.gestureState = new Value(-1); 18 | this.onGestureEvent = event([ 19 | { 20 | nativeEvent: { 21 | // translationX: this.dragX, 22 | // translationY: this.dragY, 23 | state: this.gestureState, 24 | absoluteY: this.absoluteY 25 | } 26 | } 27 | ]); 28 | 29 | // this.addY = add(this.offsetY, this.dragY); 30 | // this.addX = add(this.offsetX, this.dragX); 31 | this.circleY = add(this.absoluteY, new Value(200)); 32 | 33 | // this.transX = cond( 34 | // eq(this.gestureState, State.ACTIVE), 35 | // this.addX, 36 | // set(this.offsetX, this.addX) 37 | // ); 38 | 39 | // this.transY = cond(eq(this.gestureState, State.ACTIVE), this.addY, [ 40 | // set(this.offsetY, this.addY) 41 | // ]); 42 | 43 | this.state = { dragging: false, y: 0 }; 44 | } 45 | 46 | start = ([]) => { 47 | this.setState({ dragging: true }); 48 | }; 49 | 50 | moving = ([y, circleY]) => { 51 | this.setState({ y }); 52 | }; 53 | 54 | done = ([]) => { 55 | this.setState({ dragging: false }); 56 | }; 57 | 58 | render() { 59 | return ( 60 | 61 | y: {this.state.y} 62 | 63 | {() => cond(eq(this.gestureState, State.BEGAN), call([], this.start))} 64 | 65 | 66 | {() => 67 | cond( 68 | eq(this.gestureState, State.ACTIVE), 69 | call([this.absoluteY, this.circleY], this.moving) 70 | ) 71 | } 72 | 73 | 74 | {() => 75 | cond( 76 | or( 77 | eq(this.gestureState, State.END), 78 | eq(this.gestureState, State.FAILED), 79 | eq(this.gestureState, State.CANCELLED) 80 | ), 81 | call([], this.done) 82 | ) 83 | } 84 | 85 | {this.state.dragging && ( 86 | 87 | )} 88 | 93 | 101 | hello 102 | 103 | 104 | 105 | ); 106 | } 107 | } 108 | 109 | const CIRCLE_SIZE = 70; 110 | 111 | const styles = StyleSheet.create({ 112 | container: { 113 | flex: 1 114 | }, 115 | box: { 116 | backgroundColor: "tomato", 117 | position: "absolute", 118 | marginLeft: -(CIRCLE_SIZE / 2), 119 | marginTop: -(CIRCLE_SIZE / 2), 120 | width: CIRCLE_SIZE, 121 | height: CIRCLE_SIZE, 122 | borderRadius: CIRCLE_SIZE / 2, 123 | borderColor: "#000" 124 | } 125 | }); 126 | --------------------------------------------------------------------------------