import React, { Component } from 'react'; import { Dimensions, Image, View, StyleSheet } from 'react-native'; import Animated from 'react-native-reanimated'; import { PanGestureHandler, State } from 'react-native-gesture-handler'; const { width } = Dimensions.get('window'); const { set, neq, cond, eq, add, multiply, lessThan, spring, block, startClock, stopClock, clockRunning, sub, defined, Value, Clock, event, } = Animated; function follow(value) { const config = { damping: 28, mass: 0.3, stiffness: 188.296, overshootClamping: false, toValue: value, restSpeedThreshold: 0.001, restDisplacementThreshold: 0.001, }; const clock = new Clock(); const state = { finished: new Value(0), velocity: new Value(0), position: new Value(0), time: new Value(0), }; return block([ cond(clockRunning(clock), 0, startClock(clock)), spring(clock, state, config), state.position, ]); } class Tracking extends Component { constructor(props) { super(props); const TOSS_SEC = 0.2; const dragX = new Value(0); const dragY = new Value(0); const gestureState = new Value(-1); const dragVX = new Value(0); const dragVY = new Value(0); this._onGestureEvent = event([ { nativeEvent: { translationX: dragX, velocityX: dragVX, velocityY: dragVY, state: gestureState, translationY: dragY, }, }, ]); const transX = new Value(0); const transY = new Value(0); const clock = new Clock(); const prevDragX = new Value(0); const prevDragY = new Value(0); const snapPoint = cond( lessThan(add(transX, multiply(TOSS_SEC, dragVX)), 0), -(width / 2), width / 2 ); const config = { damping: 12, mass: 1, stiffness: 150, overshootClamping: false, restSpeedThreshold: 0.001, restDisplacementThreshold: 0.001, toValue: snapPoint, }; const state = { finished: new Value(0), velocity: dragVX, position: new Value(0), time: new Value(0), }; this._transX = cond( eq(gestureState, State.ACTIVE), [ stopClock(clock), set(transX, add(transX, sub(dragX, prevDragX))), set(prevDragX, dragX), transX, ], cond(neq(gestureState, -1), [ set(prevDragX, 0), set( transX, cond( defined(transX), [ cond(clockRunning(clock), 0, [ set(state.finished, 0), set(state.velocity, dragVX), set(state.position, transX), startClock(clock), ]), spring(clock, state, config), cond(state.finished, stopClock(clock)), state.position, ], 0 ) ), ]) ); this._transY = block([ cond( eq(gestureState, State.ACTIVE), [ set(transY, add(transY, sub(dragY, prevDragY))), set(prevDragY, dragY), ], set(prevDragY, 0) ), transY, ]); this.follow1x = follow(this._transX); this.follow1y = follow(this._transY); this.follow2x = follow(this.follow1x); this.follow2y = follow(this.follow1y); this.follow3x = follow(this.follow2x); this.follow3y = follow(this.follow2y); } render() { return ( ); } } export default class Example extends Component { render() { return ( ); } } const BOX_SIZE = 80; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#F5FCFF', }, box: { position: 'absolute', width: BOX_SIZE, height: BOX_SIZE, alignSelf: 'center', borderColor: '#F5FCFF', borderRadius: BOX_SIZE / 2, margin: BOX_SIZE / 2, }, });