This was before I realized onStart() wasn't being called
Using PanGestureHandler and attempting to "drag" an AnimatedView is not working on the web. There are no obvious bugs, the app builds just fine, no warnings in the console when inspecting.
There is one warning that is leading me to believe this could be the source of the problem. I get a warning in the console saying this:
"transform" style array value is deprecated. Use space-separated string functions, e.g., "scaleX(2) rotateX(15deg)".
I am using an AnimatedView with styling from containerStyle to transform the object and move it around when it is being dragged.
The Root of the Problem
So I've been looking into it further, trying to debug it and I've come to realize the onStart() callback is not being called. Since the onStart() callback isn't being called the context values never end up getting set and the context object overall remains empty. Leading to my initial problem of not being able to drag the object.
This still does work on iOS though. For some reason, on iOS the onStart() callback is called. This leads to the context being filled and it working.
This is my code so far, keep in mind this is just a component. In the root, I do have a GestureHandlerRootView component wrapping the whole app.
import { View, Image } from 'react-native';
import Animated, {
useAnimatedStyle,
useSharedValue,
useAnimatedGestureHandler,
withSpring,
} from 'react-native-reanimated';
import { PanGestureHandler, TapGestureHandler } from 'react-native-gesture-handler';
const AnimatedImage = Animated.createAnimatedComponent(Image);
const AnimatedView = Animated.createAnimatedComponent(View);
export default function EmojiSticker ({ imageSize, stickerSource }) {
const scaleImage = useSharedValue(imageSize);
const translateX = useSharedValue(0);
const translateY = useSharedValue(0);
const onDoubleTap = useAnimatedGestureHandler({
onActive: () => {
if (scaleImage.value !== imageSize * 2) {
scaleImage.value = scaleImage.value * 2;
} else {
scaleImage.value = scaleImage.value / 2;
}
},
});
const onDrag = useAnimatedGestureHandler({
onStart: (event, context) => {
context.translateX = translateX.value;
context.translateY = translateY.value;
},
onActive: (event, context) => {
translateX.value = event.translationX + context.translateX;
translateY.value = event.translationY + context.translateY;
},
});
const imageStyle = useAnimatedStyle(() => {
return {
width: withSpring(scaleImage.value),
height: withSpring(scaleImage.value),
};
});
const containerStyle = useAnimatedStyle(() => {
return {
transform: [
{
translateX: translateX.value,
},
{
translateY: translateY.value,
},
],
};
});
return (
<PanGestureHandler onGestureEvent={onDrag}>
<AnimatedView style={[containerStyle, { top: -350 }]}>
<TapGestureHandler onGestureEvent={onDoubleTap} numberOfTaps={2}>
<AnimatedImage
source={stickerSource}
resizeMode='contain'
style={[imageStyle, { width: imageSize, height: imageSize }]}
/>
</TapGestureHandler>
</AnimatedView>
</PanGestureHandler>
);
}
By the way the double tap gesture works perfectly both on the web and iOS. I am stumped because the dragging works perfectly in iOS just not on the Web. The transform style depreciation has led me to try and figure out a way to create web-specific styling but I'm having a hard time finding anyone else having this issue. I'm sure there's a real solution to this that I'm just missing. I'm just really confused since it works perfectly on iOS but not on the Web.
I tried to see if anybody else had any issues relating to this and couldn't really find anything. I also tried looking up the warning I saw in the console.
"transform" style array value is deprecated. Use space-separated string functions, e.g., "scaleX(2) rotateX(15deg)".
I didn't find anything relating to this either at least when I searched relating it to React-Native
I'm hoping for a solution that makes it draggable on the web.
I actually solved this by looking through the documentation for
react-native-reanimated. ObviouslyuseAnimatedGestureHandlerisn't deprecated because it worked withonDoubleTap, not to mentiononDragworked just fine on iOS.But going through the documentation on how to handle pan gestures I found this:
So instead of importing
PanGestureHandlerandTapGestureHandlerfrom 'react-native-gesture-handler' anduseAnimatedGestureHandlerfrom 'react-native-reanimated' -- one only has to importGestureandGestureDetectorfrom 'react-native-gesture-handler'.Gestureends up taking the place ofuseAnimatedGestureHandlerwhileGestureDetectortakes the place of components likePanGestureHandlerandTapGestureHandler.I also ended up having to make my own
contextXandcontextYvariables usinguseSharedValue()because as far as I could tell, theonBegin()andonChange()callbacks didn't have a settable context.Anyways, here is the fixed code that is now working perfectly on both Web and iOS: