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

manualActivation doesn't work in the Web. #2868

Closed
pedrogarciyalopez opened this issue Apr 18, 2024 · 6 comments · Fixed by #2869
Closed

manualActivation doesn't work in the Web. #2868

pedrogarciyalopez opened this issue Apr 18, 2024 · 6 comments · Fixed by #2869
Labels
Platform: Web Repro provided A reproduction with a snack or repo is provided

Comments

@pedrogarciyalopez
Copy link

Description

Please, take a look at the code below. When savedLeft.value reaches 100 or more, stateManager.fail() is called, but onUpdate and onEnd callbacks continue to trigger. This happens on the web, everything works fine in native.

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

export default function App() {
  const left = useSharedValue(0);
	
  const savedLeft = useSharedValue(0);
	
  const panGesture = Gesture.Pan()
    .manualActivation(true)
    .onTouchesDown((e, stateManager) => {
      if (savedLeft.value >= 100) {
        stateManager.fail();
      } else {
        stateManager.activate();
      }
    })
    .onUpdate(({ translationX }) => {
      left.value = savedLeft.value + translationX;
    })
    .onEnd(() => {
      savedLeft.value = left.value;
    });
	
  const animatedStyle = useAnimatedStyle(() => {
    return {
      transform: [ { translateX: left.value } ]
    }
  })
	
  return (
    <GestureHandlerRootView>
      <GestureDetector gesture={panGesture}>
        <View style={styles.container}>
          <Animated.View style={[ styles.square, animatedStyle ]}/>
        </View>
      </GestureDetector>
    </GestureHandlerRootView>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'white'
  },
  square: {
    height: 100,
    width: 100,
    backgroundColor: 'red'
  }
})

Steps to reproduce

try it on Snack

Snack or a link to a repository

https://snack.expo.dev/3EoUbugC3qzcu1iXk4-QW

Gesture Handler version

2.15.0

React Native version

0.71.9

Platforms

Web

JavaScript runtime

None

Workflow

None

Architecture

None

Build type

None

Device

None

Device model

No response

Acknowledgements

Yes

@github-actions github-actions bot added Platform: Web Repro provided A reproduction with a snack or repo is provided labels Apr 18, 2024
@m-bert
Copy link
Contributor

m-bert commented Apr 18, 2024

Hi @pedrogarciyalopez! I've just created this PR, could you please check if it helps?

@pedrogarciyalopez
Copy link
Author

@m-bert Yes, that helped, thank you!
I have another question. The translateX property is being assigned incorrect values in the onUpdate callback, they differ between web and native. Try to place your finger on the screen and swipe left, in native you immediately get negative values for translateX, and the square starts moving left. However, in web, translateX always starts from some positive value, and the square jumps right before starting to move left. This happens only when you use manualActivation. Try comment out lines 10-13, and everything will work the same in both web and native.

Try it on snack: https://snack.expo.dev/7-qYLGoKZ4SRdr4wpfj0Q

@m-bert
Copy link
Contributor

m-bert commented Apr 19, 2024

Hi @pedrogarciyalopez! Thanks for confirming that the fix work! I will merge it and close this issue.

Regarding second problem, could you please open new issue and put your repro there?

m-bert added a commit that referenced this issue Apr 19, 2024
## Description

This PR adds support for `manualActivation` on web. Right now logic responsible for manual activation with state manager is not implemented on web - state manager is able to interact with handlers, but `activate` method doesn't check for `manualActivation` property.

Fixes #2868.

## Test plan

Tested on example from #2868 

<details>
<summary> Test code </summary>

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

export default function App() {
  const left = useSharedValue(0);

  const savedLeft = useSharedValue(0);

  const panGesture = Gesture.Pan()
    .manualActivation(true)
    .onTouchesDown((e, stateManager) => {
      if (savedLeft.value >= 100) {
        stateManager.fail();
      } else {
        stateManager.activate();
      }
    })
    .onUpdate(({ translationX }) => {
      left.value = savedLeft.value + translationX;
    })
    .onEnd(() => {
      savedLeft.value = left.value;
    });

  const animatedStyle = useAnimatedStyle(() => {
    return {
      transform: [{ translateX: left.value }],
    };
  });

  return (
    <GestureHandlerRootView>
      <GestureDetector gesture={panGesture}>
        <View style={styles.container}>
          <Animated.View style={[styles.square, animatedStyle]} />
        </View>
      </GestureDetector>
    </GestureHandlerRootView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'white',
  },
  square: {
    height: 100,
    width: 100,
    backgroundColor: 'red',
  },
});

```

</details>
@m-bert
Copy link
Contributor

m-bert commented Apr 19, 2024

Hi again, @pedrogarciyalopez! I think I've found out what causes translation problems. Could you please check if #2871 works? If so, we don't have to open another issue 😅

m-bert added a commit that referenced this issue Apr 19, 2024
## Description

After solving #2868 it was found out that `manualActivation` may result in wrong translation values. The problem here is that `onPointerDown` method doesn't set `startX` and `startY` value. What is important, these values are also assigned in `resetProgress` method. 

Without manual activation, handler first calls `onPointerDown`, and then `resetProgress`, therefore values of `startX` and `startY` are correct. On the other hand, in the snippet below handler first calls `resetProgress` and then `onPointerDown`, that's why both `startX` and `startY` are still `0`.

## Test plan

Tested on the following code mentioned in #2868 

<details>
<summary> Test code </summary>

```jsx
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';

export default function App() {
  const left = useSharedValue(0);

  const panGesture = Gesture.Pan()
    .manualActivation(true)
    .onTouchesDown((e, stateManager) => {
      stateManager.activate();
    })
    .onUpdate((e) => {
      console.log(e.translationX);
      left.value = e.translationX;
    });

  const animatedStyle = useAnimatedStyle(() => {
    return {
      transform: [{ translateX: left.value }],
    };
  });

  return (
    <View style={styles.container}>
      <GestureDetector gesture={panGesture}>
        <Animated.View style={[styles.square, animatedStyle]} />
      </GestureDetector>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'yellow',
  },
  square: {
    top: 150,
    height: 100,
    width: 100,
    backgroundColor: 'red',
  },
});

```

</details>
@pedrogarciyalopez
Copy link
Author

@m-bert thank you for the quick help! Now it works as expected. When will it be merged? Which version should I use?

@m-bert
Copy link
Contributor

m-bert commented Apr 19, 2024

It is already merged 😅 I'm not 100% sure about release date, but we have plans to do it next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Platform: Web Repro provided A reproduction with a snack or repo is provided
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants