Want to restrict the panResponder icon to move out of the screen

13 Views Asked by At

I am using panResponder to do the live dragging animation but currently unable to restrict the icon to remain in the screen.

const panResponder = useRef( PanResponder.create({ onMoveShouldSetPanRe onPanResponderMove: Animated.event([null, {dx: pan.x, dy: pan.y}]), onPanResponderRelease: () => { pan.extractOffset(); }, }), ).current;

1

There are 1 best solutions below

1
Akash Kumar On

Here's a refined solution incorporating the best aspects of previous responses and addressing potential shortcomings:

  import React, { useRef, useState } from 'react';
import { Animated, PanResponder, View, StyleSheet } from 'react-native';

const App = () => {
  const [pan, setPan] = useState(new Animated.ValueXY(0, 0));
  const [dimensions, setDimensions] = useState({ width: 0, height: 0 });

  const panResponder = useRef(
    PanResponder.create({
      onMoveShouldSetPanResponder: () => true,
      onPanResponderMove: (event, gestureState) => {
        const { dx, dy } = gestureState;
        const newX = pan.x.value + dx;
        const newY = pan.y.value + dy;

        // Clamp values within screen boundaries
        const clampedX = Math.min(Math.max(newX, 0), dimensions.width - ICON_SIZE); // Account for icon size
        const clampedY = Math.min(Math.max(newY, 0), dimensions.height - ICON_SIZE);

        setPan({ x: clampedX, y: clampedY });
      },
      onPanResponderRelease: () => {
        pan.extractOffset();
      },
    })
  ).current;

  const handleLayout = (event) => {
    const { width, height } = event.nativeEvent.layout;
    setDimensions({ width, height });
  };

  return (
    <View style={styles.container} onLayout={handleLayout}>
      <Animated.View
        style={{ transform: [{ translateX: pan.x }, { translateY: pan.y }] }}
        {...panResponder.panHandlers}
      >
        {ICON_COMPONENT} // Replace with your icon component
      </Animated.View>
    </View>
  );
};

const ICON_SIZE = 50; // Adjust based on your icon size

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

export default App;