gpt4 book ai didi

react-native - 如何使用动画在 React Native 中制作循环图像背景

转载 作者:行者123 更新时间:2023-12-01 16:35:10 26 4
gpt4 key购买 nike

我最初使用 setInterval() 制作一个循环图像背景,方法是让两张图像开始于 x:0,另一张开始于 x: imageWidth ,然后按以下方式更新它们:

  _updateBackgroundImage = () => {
this.setState({
background1Left: this.state.background1Left > (-this.backgroundImageWidth) ? this.state.background1Left-3 : this.backgroundImageWidth,
background2Left: this.state.background2Left > (-this.backgroundImageWidth) ? this.state.background2Left-3 : this.backgroundImageWidth,
})
}

它工作得很好,但是 setInterval() 导致与在线库中的另一个组件发生冲突,所以我改用 Animated API 并使用以下代码:

this.translateValue = new Animated.Value(0)

translate() {
this.translateValue.setValue(0)
Animated.timing(
this.translateValue,
{
toValue: 1,
duration: 14000,
easing: Easing.linear
}
).start(()=>this.translate())
}
const translateBackgroundImage1 = this.translateValue.interpolate({
inputRange: [0, 1],
outputRange: [0, -this.backgroundImageWidth]
})
const translateBackgroundImage2 = this.translateValue.interpolate({
inputRange: [0, 1],
outputRange: [this.backgroundImageWidth, -this.backgroundImageWidth]
})


return (
<View style={{flex:1}}>

<Animated.Image
style={{
flex: 1,
position: 'absolute',
left: translateBackgroundImage1,
}}
resizeMode={Image.resizeMode.cover}
source={this.backgroundImage}
/>
<Animated.Image
style={{
flex: 1,
position: 'absolute',
left: translateBackgroundImage2,
}}
resizeMode={Image.resizeMode.cover}
source={this.backgroundImage}
/>

要应用我在 setInterval() 中使用的相同逻辑,我会让 translateBackgroundImage1 在第一个循环中从 x:0 开始,然后然后从 x: ImageWidth

开始

我不确定如何使用 Animated 实现它

最佳答案

我最终找到了解决方案。它不是很干净,但可以用。

我基本上有两个 Animated.image 从同一图像加载。然后我有一个 translateValue1,它控制第一张图片的左侧位置。然后基于 translateValue1,我们有 translateValue2,它具有 imagewidthoffsettranslateValue2 控制第二张图片的左侧位置。

当第一张图片即将退出屏幕时,它会走到屏幕的最右边,同时第二张图片会被移到第一张图片的前面,所以我们需要改变偏移-imagewidth。因此在这两个动画函数中各有一个setState方法。

在构造函数中我有这些变量:

constructor(props) {
super(props);

this.backgroundImage = require('../assets/images/graidenttPastel.jpg');
this.backgroundImageWidth = resolveAssetSource(this.backgroundImage).width;
this.translateXValue1 = new Animated.Value(-1);
this.translateXValue2 = new Animated.Value(0);
this.animationLength = 20000;

this.state = {
translateXValue2Offset: this.backgroundImageWidth,
stopAnimation: false,
}

然后我有这两个函数,每个函数控制一半的循环:

  translateXFirstHalfLoop() {
this.translateXValue1.setValue(-1);
this.setState({translateXValue2Offset: this.backgroundImageWidth});
this.firstHalfLoop = Animated.timing(
this.translateXValue1,
{
toValue: -this.backgroundImageWidth,
duration: this.animationLength/2,
easing: Easing.linear
}
).start(() => {
if(this.state.stopAnimation === false) {
this.translateXSecondHalfLoop()
}
})
}


translateXSecondHalfLoop() {
this.translateXValue1.setValue(this.backgroundImageWidth);
this.setState({translateXValue2Offset: -this.backgroundImageWidth});
this.secondHalfLoop = Animated.timing(
this.translateXValue1,
{
toValue: 0,
duration: this.animationLength/2,
easing: Easing.linear
}
).start(() => {
if(this.state.stopAnimation === false) {
this.translateXFirstHalfLoop()
}
})
}

最后在 render() 方法中,我有两个 Animated.Image,如下所示:

  render() {
this.translateXValue2 = Animated.add(this.translateXValue1, this.state.translateXValue2Offset);

return (
<SafeAreaView
style={[{backgroundColor: THEME_COLOR, flex: 1}]}
forceInset={{ bottom: 'never' }}>
<Animated.Image
style={{
position: 'absolute',
left: this.translateXValue1,
}}
resizestate={Image.resizeMode.cover}
source={this.backgroundImage}
/>
<Animated.Image
style={{
position: 'absolute',
left: this.translateXValue2,
}}
resizestate={Image.resizeMode.cover}
source={this.backgroundImage}
/>
<View style={{flex:1}}>

{this._renderScreenContent()}

</View>
</SafeAreaView>
);
}

由于每个半循环函数调用另一个,我们需要在这个组件卸载之前停止它们,所以我们在下面有这个额外的步骤:

//clean up animation first
this.setState({stopAnimation: true}, () => {
this.props.navigation.goBack()
})

关于react-native - 如何使用动画在 React Native 中制作循环图像背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47065303/

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