🤔
我们的组件必须要经过处理才可以生成动画
React Native
中,有四个组件是可以直接使用的动画组件
-
Animated.View
-
Animated.Text
-
Animated.ScrollView
-
Animated.Image
如何创建动画(步骤)
- 创建初始值
Animated.Value()
--- 单个值
Animated.ValueXY()
--- 向量值
将初始值绑定到动画组件上(一般是将其绑定到某个样式属性下。例如:opacity
、translate
)
通过动画类型API
,一帧一帧地更改初始值.
在 RN 中,提供了最常见的3种动画类型的API
Animated.decay() --- 加速效果
Animated.Spring() --- 弹跳效果
Animated.timing() --- 时间渐变效果 用的是最多的
官网体验
Fade in. Fade out. 体验代码
js
// 直接复制粘贴的体验代码
import React, {useRef} from 'react';
import {
Animated,
Text,
View,
StyleSheet,
Button,
SafeAreaView,
} from 'react-native';
const App = () => {
// fadeAnim will be used as the value for opacity. Initial Value: 0
const fadeAnim = useRef(new Animated.Value(0)).current;
const fadeIn = () => {
// Will change fadeAnim value to 1 in 5 seconds
Animated.timing(fadeAnim, {
toValue: 1,
duration: 5000,
useNativeDriver: true,
}).start();
};
const fadeOut = () => {
// Will change fadeAnim value to 0 in 3 seconds
Animated.timing(fadeAnim, {
toValue: 0,
duration: 3000,
useNativeDriver: true,
}).start();
};
return (
<SafeAreaView style={styles.container}>
<Animated.View
style={[
styles.fadingContainer,
{
// Bind opacity to animated value
opacity: fadeAnim,
},
]}>
<Text style={styles.fadingText}>Fading View!</Text>
</Animated.View>
<View style={styles.buttonRow}>
<Button title="Fade In View" onPress={fadeIn} />
<Button title="Fade Out View" onPress={fadeOut} />
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
fadingContainer: {
padding: 20,
backgroundColor: 'powderblue',
},
fadingText: {
fontSize: 28,
},
buttonRow: {
flexBasis: 100,
justifyContent: 'space-evenly',
marginVertical: 16,
},
});
export default App;
默认初始化透明度为 0
js
// fadeAnim will be used as the value for opacity. Initial Value: 0
const fadeAnim = useRef(new Animated.Value(0)).current;
入场属性
js
const fadeIn = () => {
// Will change fadeAnim value to 1 in 5 seconds
Animated.timing(fadeAnim, {
toValue: 1,
duration: 5000,
useNativeDriver: true,
}).start();
};
出场属性
js
const fadeOut = () => {
// Will change fadeAnim value to 0 in 3 seconds
Animated.timing(fadeAnim, {
toValue: 0,
duration: 3000,
useNativeDriver: true,
}).start();
};
注意看,这里有两个属性词: toValue
. duration
。一个是决定淡入还是淡出。另外一个觉得市场。
添加 回调函数
js
//添加回调函数
const fadeIn = () => {
// Will change fadeAnim value to 1 in 5 seconds
Animated.timing(fadeAnim, {
toValue: 1,
duration: 5000,
useNativeDriver: true,
}).start(()=>{
alert('我来了')
});
};
const fadeOut = () => {
// Will change fadeAnim value to 0 in 3 seconds
Animated.timing(fadeAnim, {
toValue: 0,
duration: 3000,
useNativeDriver: true,
}).start(()=>{
alert('我走了')
});
};
js
start(()=>{
alert('我走了')
})
扫描框 暂存
完整代码
js
import React, { useEffect, useRef } from 'react';
import { Animated, AppRegistry, StyleSheet, View } from 'react-native';
const App = () => {
const animation = useRef(new Animated.Value(0)).current; // 动画值
useEffect(() => {
Animated.loop(
Animated.sequence([
Animated.timing(animation, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}),
Animated.timing(animation, {
toValue: 0,
duration: 1000,
useNativeDriver: true,
}),
]),
).start();
}, [animation]);
const movingMargin = animation.interpolate({
inputRange: [0, 1],
outputRange: [0, 150], // 根据容器高度调整
});
return (
<View style={styles.container}>
<Animated.View
style={[
styles.scannerLine,
{
transform: [{ translateY: movingMargin }],
},
]}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
height: 200, // 容器的高度
width: 200, // 容器的宽度
borderColor: '#00FF00', // 边框颜色
borderWidth: 4,
backgroundColor: 'black',
justifyContent: 'center',
alignItems: 'center',
overflow: 'hidden',
},
scannerLine: {
position: 'absolute',
height: 2,
width: '100%',
backgroundColor: '#00FF00', // 扫描线颜色
},
});
export default App;
样式