Melukis teks dan imej adalah satu perkara tetapi ujian sebenar rangka kerja UI adalah sejauh mana ia bagus dengan kandungan animasi.
Dan ujian saya untuk animasi ialah MoveMe klasik berdasarkan kod sampel Apple.
Ideanya ialah untuk melukis tiga kotak pada skrin. Apabila dipilih, kotak bertukar warna dan naik skala dan kemudian boleh dialihkan dengan gerak isyarat seret dan akhirnya dipulihkan kembali kepada warna dan saiz asal apabila dilepaskan.
Mari bina sampel itu menggunakan perpustakaan Reanimated React Native.
Saya mengikuti dokumen rasmi tetapi tidak menggunakan templatnya. Jadi saya mempunyai projek asas yang dibuat dengan templat kosong dan memasang kebergantungan
npx create-expo-app playground --template blank npx expo install react-native-reanimated npx expo install react-native-gesture-handler
Seterusnya, saya menambah pemalam
module.exports = function (api) { api.cache(true); return { presets: ["babel-preset-expo"], plugins: ["react-native-reanimated/plugin"], }; };
Dan kemudian lukis 3 petak pada skrin:
import { StatusBar } from "expo-status-bar"; import { StyleSheet, View } from "react-native"; import Animated from "react-native-reanimated"; function Square() { return <Animated.View style={styles.square}></Animated.View>; } export default function App() { return ( <View style={styles.container}> <StatusBar style="auto" /> <Square /> <Square /> <Square /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#fff", alignItems: "center", justifyContent: "space-evenly", }, square: { width: 100, height: 100, backgroundColor: "blue", }, });
Untuk menambah sokongan bagi pengendali gerak isyarat, pertama sekali kita perlu membungkus kandungan dalam GestureHandlerRootView
<GestureHandlerRootView style={styles.container}> <Square /> <Square /> <Square /> </GestureHandlerRootView>
Dan kemudian balut setiap Petak dalam GestureDetector
function Square() { const gesture = Gesture.Pan(); return ( <GestureDetector gesture={gesture}> <Animated.View style={styles.square} /> </GestureDetector> ); }
Untuk mengendalikan gerak isyarat kita perlu mencipta SharedValue yang seperti Negeri tetapi untuk keadaan animasi. Contohnya, untuk menukar warna latar belakang apabila dipilih, kita perlu mendengar acara onBegin dan onFinalize serta mengemas kini gaya:
function Square() { const isPressed = useSharedValue(false); const animStyle = useAnimatedStyle(() => { return { backgroundColor: isPressed.value ? "red" : "blue", }; }); const gesture = Gesture.Pan() .onBegin(() => { isPressed.value = true; }) .onFinalize(() => { isPressed.value = false; }); return ( <GestureDetector gesture={gesture}> <Animated.View style={[styles.square, animStyle]} /> </GestureDetector> ); }
Seretan sokongan adalah serupa. Kita perlu menyimpan kedudukan mula dan semasa dan kemudian mengemas kini kedudukan semasa pada acara onChange. OnChange menyediakan perubahan delta yang kemudiannya perlu kita tambahkan pada kedudukan permulaan untuk mengira kedudukan semasa akhir. Dan kemudian, akhirnya pada acara onFinalize kita boleh menyegerakkan kedudukan mula dan semasa.
function Square() { const isPressed = useSharedValue(false); const startPos = useSharedValue({ x: 0, y: 0 }); const pos = useSharedValue({ x: 0, y: 0 }); const animStyle = useAnimatedStyle(() => { return { backgroundColor: isPressed.value ? "red" : "blue", transform: [ { translateX: pos.value.x }, { translateY: pos.value.y }, { scale: withSpring(isPressed.value ? 1.2 : 1) }, ], }; }); const gesture = Gesture.Pan() .onBegin(() => { isPressed.value = true; }) .onChange((e) => { pos.value = { x: startPos.value.x + e.translationX, y: startPos.value.y + e.translationY, }; }) .onFinalize(() => { isPressed.value = false; startPos.value = { x: pos.value.x, y: pos.value.y, }; }); return ( <GestureDetector gesture={gesture}> <Animated.View style={[styles.square, animStyle]} /> </GestureDetector> ); }
Dan begitulah
Atas ialah kandungan terperinci Mari hidupkan semula. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!