📅  最后修改于: 2023-12-03 14:50:34.034000             🧑  作者: Mango
在现代Web应用程序中,页面导航过渡动画已成为很普遍的需求。但是,一些页面导航之间可能存在共享的元素,比如页面标题、主题颜色等,我们希望这些元素能够顺利的过渡到新的页面中,这就是共享元素。
在React Native中实现共享元素的过渡动画非常方便,我们可以使用react-navigation-shared-element
库,它提供了一个SharedElement
组件来定义需要共享的元素。
npm install react-navigation-shared-element
我们可以在需要共享元素的页面中使用SharedElement
组件来定义,例如,我们想要在两个页面之间共享一个标题:
import { SharedElement } from 'react-navigation-shared-element';
function Page1() {
return (
<SharedElement id="title">
<Text>Page 1</Text>
</SharedElement>
);
}
function Page2() {
return (
<SharedElement id="title">
<Text>Page 2</Text>
</SharedElement>
);
}
我们定义了一个id
属性值为"title"的SharedElement
组件,并在两个页面中使用了相同的id
来共享这个标题元素。
在使用react-navigation
库进行导航时,我们需要使用transitionSpec
配置来指定导航过渡动画的设置。在这里,我们需要加上sharedElement
的timing
方法来使共享元素过渡动画生效。
import { createStackNavigator } from '@react-navigation/stack';
import { createSharedElementStackNavigator } from 'react-navigation-shared-element';
const Stack = createSharedElementStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Page1" component={Page1} />
<Stack.Screen
name="Page2"
component={Page2}
options={{
headerBackTitleVisible: false,
headerTransparent: true,
headerTintColor: '#fff',
headerTitle: () => null,
tabBarVisible: false,
transitionSpec: {
open: { animation: 'timing', config: { duration: 500 }, sharedElements: true },
close: { animation: 'timing', config: { duration: 350 }, sharedElements: true },
},
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
在transitionSpec
配置中,我们加上了sharedElements
属性,来开启共享元素的过渡动画。我们也可以指定不同的animation
和config
值来定制过渡动画的效果。
如果我们想要实现更复杂的过渡动画效果,可以通过使用useSharedValue
和useDerivedValue
来自定义过渡动画。
import React, { useRef } from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity } from 'react-native';
import { SharedElement } from 'react-navigation-shared-element';
import { useNavigation } from '@react-navigation/native';
import Animated, { useAnimatedGestureHandler, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import { PanGestureHandler } from 'react-native-gesture-handler';
function Page2() {
const navigation = useNavigation();
const ref = useRef();
const translateX = useSharedValue(0);
const translateY = useSharedValue(0);
const onGestureEvent = useAnimatedGestureHandler({
onStart: (_, ctx) => {
ctx.x = translateX.value;
ctx.y = translateY.value;
},
onActive: (event, ctx) => {
translateX.value = event.translationX + ctx.x;
translateY.value = event.translationY + ctx.y;
},
onEnd: () => {
const distance = Math.sqrt(Math.pow(translateX.value, 2) + Math.pow(translateY.value, 2));
if (distance > 200) {
navigation.goBack();
} else {
translateX.value = withTiming(0);
translateY.value = withTiming(0);
}
},
});
const animatedStyle = useAnimatedStyle(() => {
return {
transform: [{ translateX: translateX.value }, { translateY: translateY.value }],
};
});
return (
<View style={styles.container}>
<SharedElement id="title">
<Text style={styles.title}>Page 2</Text>
</SharedElement>
<PanGestureHandler onGestureEvent={onGestureEvent}>
<Animated.View style={[styles.box, animatedStyle]}>
<SharedElement id="image">
<Image ref={ref as any} source={{ uri: 'https://picsum.photos/id/100/200/300' }} style={styles.image} />
</SharedElement>
</Animated.View>
</PanGestureHandler>
</View>
);
}
在这个例子中,我们自定义了一个手势响应函数onGestureEvent
,当用户拖动图片时,动态更新其translateX
和translateY
的值,从而实现手势过渡动画。
我们还使用了useAnimatedStyle
钩子,将这些动态值应用到Animated.View
组件上,实现了自定义的过渡动画。
这就是React Native共享元素的基本用法和自定义过渡动画的实现方法了。
React Native中的共享元素过渡动画,让我们可以轻松的实现页面之间元素的共享。通过上文的介绍和实践,你可以学会如何使用react-navigation-shared-element
库,定义共享元素,导航到新页面,并实现自定义的过渡动画。
# 反应原生导航共享元素 - Javascript
在现代Web应用程序中,页面导航过渡动画已成为很普遍的需求。但是,一些页面导航之间可能存在共享的元素,比如页面标题、主题颜色等,我们希望这些元素能够顺利的过渡到新的页面中,这就是共享元素。
在React Native中实现共享元素的过渡动画非常方便,我们可以使用`react-navigation-shared-element`库,它提供了一个`SharedElement`组件来定义需要共享的元素。
## 安装
npm install react-navigation-shared-element
## 使用
### 定义共享元素
我们可以在需要共享元素的页面中使用`SharedElement`组件来定义,例如,我们想要在两个页面之间共享一个标题:
```jsx
import { SharedElement } from 'react-navigation-shared-element';
function Page1() {
return (
<SharedElement id="title">
<Text>Page 1</Text>
</SharedElement>
);
}
function Page2() {
return (
<SharedElement id="title">
<Text>Page 2</Text>
</SharedElement>
);
}
我们定义了一个id
属性值为"title"的SharedElement
组件,并在两个页面中使用了相同的id
来共享这个标题元素。
在使用react-navigation
库进行导航时,我们需要使用transitionSpec
配置来指定导航过渡动画的设置。在这里,我们需要加上sharedElement
的timing
方法来使共享元素过渡动画生效。
import { createStackNavigator } from '@react-navigation/stack';
import { createSharedElementStackNavigator } from 'react-navigation-shared-element';
const Stack = createSharedElementStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Page1" component={Page1} />
<Stack.Screen
name="Page2"
component={Page2}
options={{
headerBackTitleVisible: false,
headerTransparent: true,
headerTintColor: '#fff',
headerTitle: () => null,
tabBarVisible: false,
transitionSpec: {
open: { animation: 'timing', config: { duration: 500 }, sharedElements: true },
close: { animation: 'timing', config: { duration: 350 }, sharedElements: true },
},
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
在transitionSpec
配置中,我们加上了sharedElements
属性,来开启共享元素的过渡动画。我们也可以指定不同的animation
和config
值来定制过渡动画的效果。
如果我们想要实现更复杂的过渡动画效果,可以通过使用useSharedValue
和useDerivedValue
来自定义过渡动画。
import React, { useRef } from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity } from 'react-native';
import { SharedElement } from 'react-navigation-shared-element';
import { useNavigation } from '@react-navigation/native';
import Animated, { useAnimatedGestureHandler, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import { PanGestureHandler } from 'react-native-gesture-handler';
function Page2() {
const navigation = useNavigation();
const ref = useRef();
const translateX = useSharedValue(0);
const translateY = useSharedValue(0);
const onGestureEvent = useAnimatedGestureHandler({
onStart: (_, ctx) => {
ctx.x = translateX.value;
ctx.y = translateY.value;
},
onActive: (event, ctx) => {
translateX.value = event.translationX + ctx.x;
translateY.value = event.translationY + ctx.y;
},
onEnd: () => {
const distance = Math.sqrt(Math.pow(translateX.value, 2) + Math.pow(translateY.value, 2));
if (distance > 200) {
navigation.goBack();
} else {
translateX.value = withTiming(0);
translateY.value = withTiming(0);
}
},
});
const animatedStyle = useAnimatedStyle(() => {
return {
transform: [{ translateX: translateX.value }, { translateY: translateY.value }],
};
});
return (
<View style={styles.container}>
<SharedElement id="title">
<Text style={styles.title}>Page 2</Text>
</SharedElement>
<PanGestureHandler onGestureEvent={onGestureEvent}>
<Animated.View style={[styles.box, animatedStyle]}>
<SharedElement id="image">
<Image ref={ref as any} source={{ uri: 'https://picsum.photos/id/100/200/300' }} style={styles.image} />
</SharedElement>
</Animated.View>
</PanGestureHandler>
</View>
);
}
在这个例子中,我们自定义了一个手势响应函数onGestureEvent
,当用户拖动图片时,动态更新其translateX
和translateY
的值,从而实现手势过渡动画。
我们还使用了useAnimatedStyle
钩子,将这些动态值应用到Animated.View
组件上,实现了自定义的过渡动画。
这就是React Native共享元素的基本用法和自定义过渡动画的实现方法了。
React Native中的共享元素过渡动画,让我们可以轻松的实现页面之间元素的共享。通过上文的介绍和实践,你可以学会如何使用react-navigation-shared-element
库,定义共享元素,导航到新页面,并实现自定义的过渡动画。