我目前正在使用 Expo 开发一个 React Native 应用程序,我面临着在我的一个屏幕上实现动画能量流线的挑战。目标是对房屋图像上的线条进行动画处理以模拟能量流动,如以下概念所示:
我目前拥有的:
应该是什么样子:
我探索了各种选项,但还没有找到合适的库或方法来在 React Native 中实现这种效果。虽然我预计动画本身不会过于复杂,但我对 React Native 中的动画相对较新,并且可以使用一些关于如何有效完成此任务的指导。
这是我迄今为止尝试过的:
搜索提供类似动画功能的现有库。 在React Native中尝试了基本的动画技术,但没有达到预期的效果。 如果有人有在 React Native 中创建这样的动画效果的经验或见解,我将非常感谢您对如何继续进行的帮助或指导。
提前感谢您的帮助!
所以我做了一个组件:
import React, { useState, useEffect } from 'react';
import { View, Animated, Easing, StyleSheet } from 'react-native';
const EnergyFlowAnimation = ({ duration = 1000, direction = 'left', style = null, value = 1, nrOfMarks = 5 }) => {
const [arrowPosition] = useState(new Animated.Value(0));
const animation = Animated.timing(arrowPosition, {
toValue: value,
duration: duration,
easing: Easing.linear,
// easing: Easing.back(),
useNativeDriver: true,
});
const startAnimation = () => {
animation.start(() => {
animation.reset();
startAnimation();
});
};
useEffect(() => {
startAnimation();
}, []);
const Mark = () => {
return (
<View style={{
width: 7,
height: 5,
backgroundColor: '#FF6B00',
marginLeft: 3,
borderRadius: 5
}} />
);
}
let arrowTranslateX = 0;
let arrowTranslateY = 0;
let arrowRotation = '0deg';
switch (direction) {
case 'left':
arrowTranslateX = arrowPosition.interpolate({
inputRange: [0, 1],
outputRange: [40, -10],
});
arrowRotation = '180deg';
break;
case 'right':
arrowTranslateX = arrowPosition.interpolate({
inputRange: [0, 1],
outputRange: [-10, 40],
});
arrowRotation = '0deg';
break;
case 'top':
arrowTranslateY = arrowPosition.interpolate({
inputRange: [0, 1],
outputRange: [40, -10],
});
arrowRotation = '-90deg';
break;
case 'down':
arrowTranslateY = arrowPosition.interpolate({
inputRange: [0, 1],
outputRange: [-10, 40],
});
arrowRotation = '90deg';
break;
default:
arrowTranslateX = arrowPosition.interpolate({
inputRange: [0, 1],
outputRange: [40, -10],
});
}
return (
<View>
<Animated.View
style={[
styles.roadLine, style,
{
transform: [{ translateX: arrowTranslateX }, { translateY: arrowTranslateY }, { rotate: arrowRotation }],
// position: 'absolute',
justifyContent: 'center',
alignItems: 'center',
alignSelf: 'center',
}]}>
{[...new Array(nrOfMarks)].map((_, index) => <View key={index}><Mark /></View>)}
</Animated.View>
</View>
);
};
const styles = StyleSheet.create({
roadLine: {
height: 10,
flexDirection: 'row',
},
});
export default EnergyFlowAnimation;
我将该组件称为如下:
<View style={[styles.bottom, { top: 20, flexDirection: 'row' }]} >
<View
style={{
backgroundColor: 'blue',
width: 20,
height: 20,
zIndex: 1,
right: -10
}}
/>
<EnergyFlowAnimation
duration={500}
direction='right'
value={0.6}
nrOfMarks={15}
/>
<View
style={{
backgroundColor: 'yellow',
width: 20,
height: 20,
right: 2
}}
/>
</View>
这给了我以下内容: