从 'react-native' 导入 { View, Image }; 导入动画,{ 使用动画样式, 使用共享值, 使用AnimatedGestureHandler, 随着春天, 来自“react-native-reanimated”; 从 'react-native-gesture-handler' 导入 { PanGestureHandler, TapGestureHandler }; const AnimatedImage = Animated.createAnimatedComponent(Image); const AnimatedView = Animated.createAnimatedComponent(View); 导出默认函数 EmojiSticker ({ imageSize, StickerSource }) { const scaleImage = useSharedValue(imageSize); const translateX = useSharedValue(0); consttranslateY = useSharedValue(0); const onDoubleTap = useAnimatedGestureHandler({ onActive: () =>; { if (scaleImage.value !== imageSize * 2) { 缩放图像.值 = 缩放图像.值 * 2; } 别的 { 缩放图像.值 = 缩放图像.值 / 2; } }, }); const onDrag = useAnimatedGestureHandler({ onStart: (事件, 上下文) => { context.translateX = translateX.value; context.translateY = translateY.value; }, onActive: (事件, 上下文) => { translateX.value = event.translationX + context.translateX; translateY.value = event.translationY + context.translateY; }, }); const imageStyle = useAnimatedStyle(() => { 返回 { 宽度:withSpring(scaleImage.value), 高度:withSpring(scaleImage.value), }; }); const containerStyle = useAnimatedStyle(() => { 返回 { 转换: [ { 翻译X:翻译X.值, }, { 翻译Y:翻译Y.值, }, ], }; }); 返回 (<AnimatedView style={[containerStyle, { top: -350 }]}> <动画图像 来源={贴纸源} resizeMode='包含' 样式={[imageStyle, { 宽度: imageSize, 高度: imageSize }]} >> </TapGestureHandler> </动画视图> </PanGestureHandler> ); }</pre> <p><strong>顺便说一下,晚餐在 Web 和 iOS 上都完美工作。</strong> 我感到很困惑,因为拖动在 iOS 上完美工作,但在 Web 上却行得通。transform 样式的弃用使我尝试找出一种创建特定于 Web 的样式的方法,但我很难找到其他人遇到这个问题的情况。我相信有一个真正的解决方案,只是我可能遗漏了。我只是真的很困惑,因为它在 iOS 上完美工作,但在 Web 上却不行。</p> <p>我尝试查看是否有其他人遇到类似的问题,但实际上没有找到任何相关的内容。我还尝试在控制台上搜索我看到的警告。</p> <p><code>"transform" 样式数组值已弃用。请使用以空格分隔的字符串函数,例如 "scaleX(2) rotateX(15deg)"。</code></p> <p>至少在我搜索与 React-Native 相关的内容时,我没有找到任何相关的内容。</p> <p>我希望能找到一个在 Web 上可拖动的解决方案。</p>
P粉2935505752023-08-17 11:02:56
我通过查阅react-native-reanimated
的文档来解决了这个问题。显然,useAnimatedGestureHandler
并没有被弃用,因为它在onDoubleTap
中起作用,更不用说onDrag
在iOS上也正常工作。
但是在处理平移手势的文档中,我找到了这个:
const pan = Gesture.Pan() .onBegin(() => { pressed.value = true; }) .onChange((event) => { offset.value = event.translationX; }) .onFinalize(() => { offset.value = withSpring(0); pressed.value = false; });
所以,不需要从'react-native-gesture-handler'中导入PanGestureHandler
和TapGestureHandler
,也不需要从'react-native-reanimated'中导入useAnimatedGestureHandler
,只需要从'react-native-gesture-handler'中导入Gesture
和GestureDetector
。
Gesture
取代了useAnimatedGestureHandler
,而GestureDetector
取代了PanGestureHandler
和TapGestureHandler
等组件。
我还需要使用useSharedValue()
创建自己的contextX
和contextY
变量,因为据我所知,onBegin()
和onChange()
回调函数没有可设置的上下文。
无论如何,这是修复后的代码,现在在Web和iOS上都完美运行:
import { View, Image } from 'react-native'; import Animated, { useAnimatedStyle, useSharedValue, withSpring, } from 'react-native-reanimated'; import { Gesture, GestureDetector } 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 contextX = useSharedValue(0); const contextY = useSharedValue(0); const onDoubleTap = Gesture.Tap().numberOfTaps(2) .onEnd(() => { if (scaleImage.value !== imageSize * 2) { scaleImage.value = scaleImage.value * 2; } else { scaleImage.value = scaleImage.value / 2; } }); const onDrag = Gesture.Pan() .onBegin(() => { contextX.value = translateX.value; contextY.value = translateY.value; }) .onChange((event) => { translateX.value = event.translationX + contextX.value; translateY.value = event.translationY + contextY.value; }); const imageStyle = useAnimatedStyle(() => { return { width: withSpring(scaleImage.value), height: withSpring(scaleImage.value), }; }); const containerStyle = useAnimatedStyle(() => { return { transform: [ { translateX: translateX.value, }, { translateY: translateY.value, }, ], }; }); return ( <GestureDetector gesture={onDrag}> <AnimatedView style={[containerStyle, { top: -350 }]}> <GestureDetector gesture={onDoubleTap}> <AnimatedImage source={stickerSource} resizeMode="contain" style={[imageStyle, { width: imageSize, height: imageSize }]} /> </GestureDetector> </AnimatedView> </GestureDetector> ); }