從 '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.值, }, ], }; }); 返回 (> <動畫影像 來源={貼紙來源} 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> ); }