Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Focal and anchor points are not in the coordinate space of the view on web #2929

Open
j-piasecki opened this issue Jun 3, 2024 · 0 comments · May be fixed by #2932
Open

Focal and anchor points are not in the coordinate space of the view on web #2929

j-piasecki opened this issue Jun 3, 2024 · 0 comments · May be fixed by #2932

Comments

@j-piasecki
Copy link
Member

Description

On Android and iOS the focal (for pinch) and anchor (for rotation) points are always in the coordinate space of the view, while on web they are not. It looks like they are in the window coordinate space, though I didn't investigate it that thoroughly.

Untitled.mov

Steps to reproduce

import React from 'react';
import { StyleSheet, View } from 'react-native';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, {
  useAnimatedStyle,
  useSharedValue,
} from 'react-native-reanimated';

function Pointer(props: { x: number; y: number }) {
  return (
    <View
      style={{
        position: 'absolute',
        left: props.x,
        top: props.y,
        width: 16,
        height: 16,
        borderRadius: 8,
        backgroundColor: 'red',
        transform: [{ translateX: -8 }, { translateY: -8 }],
      }}
    />
  );
}

export default function EmptyExample() {
  const translation = useSharedValue({ x: 0, y: 0 });

  const style = useAnimatedStyle(() => {
    return {
      transform: [
        { translateX: translation.value.x },
        { translateY: translation.value.y },
      ],
    };
  });

  const [pointerPos, setPointerPos] = React.useState({ x: 100, y: 100 });
  const [pointerVisible, setPointerVisible] = React.useState(false);

  const pan = Gesture.Pan()
    .averageTouches(true)
    .onChange((e) => {
      translation.value = {
        x: translation.value.x + e.changeX,
        y: translation.value.y + e.changeY,
      };
    });

  const pinch = Gesture.Pinch()
    .onStart((e) => {
      setPointerVisible(true);
      setPointerPos({ x: e.focalX, y: e.focalY });
    })
    .onEnd(() => {
      setPointerVisible(false);
    })
    .runOnJS(true);

  const rotation = Gesture.Rotation()
    .onStart((e) => {
      setPointerVisible(true);
      setPointerPos({ x: e.anchorX, y: e.anchorY });
    })
    .onEnd(() => {
      setPointerVisible(false);
    })
    .runOnJS(true);

  return (
    <View style={styles.container}>
      <GestureDetector gesture={Gesture.Simultaneous(pan, rotation)}>
        <Animated.View
          style={[style, { width: 200, height: 200, backgroundColor: 'blue' }]}>
          {pointerVisible && <Pointer x={pointerPos.x} y={pointerPos.y} />}
        </Animated.View>
      </GestureDetector>
    </View>
  );
}

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

The above snippet will render a red point at the relevant point (replace pinch/rotation in detector prop to see the other gesture). It should only change based on the position of the pointer relevant to the blue square, but it's also dependent on its position on the screen and that causes it to move outside the view.

Snack or a link to a repository

https://github.com/software-mansion/react-native-gesture-handler ❤️

Gesture Handler version

main branch

React Native version

0.74.1

Platforms

Web

JavaScript runtime

None

Workflow

Expo managed workflow

Architecture

Paper (Old Architecture)

Build type

Debug mode

Device

None

Device model

No response

Acknowledgements

Yes

m-bert added a commit that referenced this issue Jun 4, 2024
## Description

Fixing #2929 required adding additional information to `TrackerElement`. If we were to leave current structure of `PointerTracker`, we would have to add few more methods. After refactoring, there are only 2 that were not present before:

- `getLastViewRelativeCoords`
- `getViewRelativeCoordsSum`

I'd like to make similar changes to our handlers in the future (i.e. use `coords` object instead of `lastX` and `lastY` variables).

## Test plan

Tested on example app.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant