gpt4 book ai didi

reactjs - 在 View 列表上 react native 无限循环的弹跳动画?

转载 作者:行者123 更新时间:2023-12-05 04:23:06 26 4
gpt4 key购买 nike

假设我有一个数据数组,在此上下文中是商店名称。我需要以一种方式为它们设置动画,就像第一个商店从上方进入大约 10px 到比例为 0.5 的框,并在短暂的延迟后继续获得一点中心并假装(平行)变得更大,然后再延迟一次倒下的盒子和绝望。如下所示:

enter image description here

到目前为止,我做到了这一点。我需要的是这家之后的下一家商店,等待它变大,如下所示:

enter image description here

上面的小等待大的掉落然后开始相同的动画。

到目前为止,这是我的代码:

const TrackOrder = () => {
const [listData, setListData] = useState([
{
id: 1,
storeName: 'papa jones besiktas',
},
{
id: 2,
storeName: 'levent store',
},
{
id: 3,
storeName: 'sariyer store',
},
]);
const {colors} = useTheme();
// let fadeAni = useRef(new Animated.Value(0.2)).current;
let bounceLittleItem = useRef(new Animated.Value(-80)).current;
let bounceBigItem = useRef(new Animated.Value(-100)).current;

let scaleUp = useRef(new Animated.Value(0.5)).current;

const styles = useMemo(
() =>
StyleSheet.create({
mainContainer: {
backgroundColor: colors.CONTRAST_PRIMARY,
height: 100,
borderRadius: 30,
marginHorizontal: `${(100 - GUTTERS.SCREEN_WIDTH_IN_NUMBER) / 2}%`,
flexDirection: 'column',
alignItems: 'flex-start',
justifyContent: 'center',
paddingHorizontal: 15,
marginTop: 25,
overflow: 'hidden',
},
orderContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-start',
},
storeImage: {
width: 45,
height: 45,
backgroundColor: 'yellow',
borderRadius: 40,
marginRight: 20,
},
orderStatusText: {
color: '#fff',
fontFamily: 'BalooPaaji2-SemiBold',
},
storeContainer: {
backgroundColor: '#fff',
paddingHorizontal: 10,
paddingVertical: 5,
borderRadius: 20,
},
storeOneBeforeLastImage: {
width: 25,
height: 25,
backgroundColor: 'yellow',
borderRadius: 40,
// marginRight: 20,
opacity: 0.5,
},
}),
[colors],
);


useEffect(() => {
const inter = setInterval(() => {
let copyArr = [...listData];
let last = copyArr.pop();
copyArr.unshift(last);
setListData(copyArr);
}, 6000);

return () => clearInterval(inter);
}, [listData]);

useEffect(() => {
Animated.timing(bounceBigItem, {
toValue: -30,
duration: 2000,
useNativeDriver: true,
});
}, [bounceBigItem]);

const runAnimation = useCallback(() => {
Animated.sequence([
Animated.timing(bounceLittleItem, {
toValue: -30,
duration: 2000,
useNativeDriver: true,
}),
Animated.parallel([
Animated.timing(bounceLittleItem, {
toValue: 20,
duration: 1000,
useNativeDriver: true,
}),
Animated.timing(scaleUp, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}),
]),
Animated.delay(2000),
Animated.timing(bounceLittleItem, {
toValue: 100,
duration: 1000,
useNativeDriver: true,
}),
]).start(() => {
bounceLittleItem.setValue(-80);
scaleUp.setValue(0.5);
runAnimation();
});
}, [bounceLittleItem, scaleUp]);

useEffect(() => runAnimation(), [runAnimation]);

const renderViewItem = useMemo(() => {
if (listData?.length === 0) return;
return listData.map((el, i) => {
return (
<Animated.View
key={el.id}
style={[
styles.orderContainer,
i === 0
? {
transform: [{translateY: bounceLittleItem}, {scale: scaleUp}],
}
: {
transform: [{translateY: bounceBigItem}, {scale: 0.5}],
},
]}
>
<View style={[styles.storeImage]} />
<Text style={styles.orderStatusText}>{el.storeName}</Text>
</Animated.View>
);
});
}, [bounceBigItem, bounceLittleItem, listData, scaleUp, styles.orderContainer, styles.orderStatusText, styles.storeImage]);

return <View style={styles.mainContainer}>{renderViewItem}</View>;
};

那么,我怎样才能实现我想要的动画,它再次首先下降,一旦变大,下一家商店就会下降并踩到第一家商店的足迹?如果您有任何想法,我将不胜感激。

最佳答案

我设计了一个解决方案,通过为每个项目触发动画并根据项目在列表(索引)中的位置应用延迟来工作。更改包括将所有项目堆积在顶部 position: absolute ,每一个都有延迟。此外,我使用了 Animated.loop功能,因为它似乎更一致地工作。

import React, {useRef, useEffect, useCallback} from 'react';
import {StyleSheet, View, Text, Animated} from 'react-native';

const Item = ({children, index, len}) => {
let bounceLittleItem = useRef(new Animated.Value(-80)).current;
let scaleUp = useRef(new Animated.Value(0.5)).current;

const runAnimation = useCallback(
delay => {
Animated.sequence([
Animated.delay(delay),
Animated.loop(
Animated.sequence([
Animated.timing(bounceLittleItem, {
toValue: -30,
duration: 2000,
useNativeDriver: true,
}),
Animated.parallel([
Animated.timing(bounceLittleItem, {
toValue: 20,
duration: 1000,
useNativeDriver: true,
}),
Animated.timing(scaleUp, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}),
]),
Animated.delay(1000),
Animated.timing(bounceLittleItem, {
toValue: 100,
duration: 1000,
useNativeDriver: true,
}),
Animated.delay((2 * len - 5) * 1000),
]),
),
]).start();
},
[bounceLittleItem, scaleUp, len],
);

useEffect(() => {
console.log(`running animation ${index}`);
runAnimation(index * 2000);
}, [index, runAnimation]);

return (
<Animated.View
style={[
styles.orderContainer,
{
transform: [{translateY: bounceLittleItem}, {scale: scaleUp}],
},
]}>
{children}
</Animated.View>
);
};

const App = () => {
const listData = [
{
id: 1,
storeName: 'papa jones besiktas',
},
{
id: 2,
storeName: 'levent store',
},
{
id: 3,
storeName: 'sariyer store',
},
];

return (
<View style={styles.mainContainer}>
{listData.map(({id, storeName}, index) => (
<Item key={id} index={index} len={listData.length}>
<View style={[styles.storeImage]} />
<Text style={styles.orderStatusText}>{storeName}</Text>
</Item>
))}
</View>
);
};

const styles = StyleSheet.create({
mainContainer: {
backgroundColor: 'black',
height: 100,
borderRadius: 30,
flexDirection: 'column',
alignItems: 'flex-start',
justifyContent: 'center',
paddingHorizontal: 15,
marginTop: 25,
overflow: 'hidden',
},
orderContainer: {
width: '100%',
position: 'absolute',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-start',
},
storeImage: {
width: 45,
height: 45,
backgroundColor: 'yellow',
borderRadius: 40,
marginRight: 20,
},
orderStatusText: {
color: '#fff',
fontFamily: 'BalooPaaji2-SemiBold',
},
storeContainer: {
backgroundColor: '#fff',
paddingHorizontal: 10,
paddingVertical: 5,
borderRadius: 20,
},
storeOneBeforeLastImage: {
width: 25,
height: 25,
backgroundColor: 'yellow',
borderRadius: 40,
// marginRight: 20,
opacity: 0.5,
},
});
export default App;

https://snack.expo.dev/@diedu89/animation-loop

请注意,值是根据动画的持续时间以及您希望“并行”运行它们的距离而定制的。我通过将一组点制成表格并使用 online tool 得出了下一个循环延迟的公式 (2 * len - 5)得到它

例如,对于 5000 毫秒内的动画,时间轴看起来像这样,每个动画都以 2000 的差异触发

<表类="s-表"><头>开始完成<正文>050002000700040009000600011000800013000

我可以确定对于长度为 3 的数组,我需要 1000 的延迟,对于 4 3000,对于 5 5000,等等

<表类="s-表"><头>长度延迟<正文>3100043000550006700079000

关于reactjs - 在 View 列表上 react native 无限循环的弹跳动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73791202/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com