Reactjs 反应本机背景循环动画

Reactjs 反应本机背景循环动画,reactjs,react-native,animation,frontend,Reactjs,React Native,Animation,Frontend,我试图在react native中制作背景视差效果。我在谷歌上搜索到的大多数东西都只是滑动视差效果,所以我决定自己用动画API实现它。问题是,我似乎找不到如何使背景图像在内部重复。因此,当图像的最后一部分移出屏幕时,它会从相反的部分出来。我也尝试过使用一个复制的图像,在第一个图像离开屏幕(使用监听器)后对其进行动画制作,但不知何故,它的速度不同,两个图像重叠,而不是线性移动。(我已经检查了位置/速度/放松和所有匹配)有什么想法吗 export default function App() {

我试图在react native中制作背景视差效果。我在谷歌上搜索到的大多数东西都只是滑动视差效果,所以我决定自己用动画API实现它。问题是,我似乎找不到如何使背景图像在内部重复。因此,当图像的最后一部分移出屏幕时,它会从相反的部分出来。我也尝试过使用一个复制的图像,在第一个图像离开屏幕(使用监听器)后对其进行动画制作,但不知何故,它的速度不同,两个图像重叠,而不是线性移动。(我已经检查了位置/速度/放松和所有匹配)有什么想法吗

export default function App() {
  const windowWidth = Dimensions.get('window').width;
  const hill3Width = Image.resolveAssetSource(hill3Pic).width;

  const hill3LeftPos = new Animated.Value((hill3Width - windowWidth) * -1)
  const hill3LeftPos2 = new Animated.Value((hill3Width * -1) - 1)

  let looped = false

  hill3LeftPos.addListener(({ value }) => {
    //make sure first pics' leftmost part is on the screen and animate next image only once
    if (value > 0 && !looped) {
      looped = true
      Animated.sequence([
        Animated.timing(
          hill3LeftPos2,
          {
            toValue: windowWidth,
            duration: 6000,
            easing: Easing.linear,
            useNativeDriver: false
          }
        )]).start()
    }
  });

  useEffect(() => {
    cycleHill3Animation()
  }, []);


  const cycleHill3Animation = () => {
    Animated.sequence([
      Animated.timing(
        hill3LeftPos,
        {
          toValue: windowWidth,
          duration: 6000,
          easing: Easing.linear,
          useNativeDriver: false
        }
      )
    ]).start(() => {
      // hill3LeftPos.setValue((hill3Width - windowWidth) * -1)
      // cycleHill3Animation()
    })
  }
  return (
    <View style={{ backgroundColor: 'black', flex: 1 }}>

      <Animated.View style={{ position: 'absolute', bottom: 0, left: hill3LeftPos }}>
        <Animated.Image
          style={styles.hill3}
          source={require('./assets/examplebackground.png')}
        />
      </Animated.View>
      <Animated.View style={{ position: 'absolute', bottom: 0, left: hill3LeftPos2 }}>
        <Animated.Image
          style={styles.hill3}
          source={require('./assets/examplebackground.png')}
        />
      </Animated.View>
    </View >


  );

}

const styles = StyleSheet.create({
  hill3: {
    bottom: 0
  }
});

导出默认函数App(){
const windowWidth=Dimensions.get('window').width;
const hill3Width=Image.resolveAssetSource(hill3Pic).width;
const hill3LeftPos=新的动画.Value((hill3Width-windowWidth)*-1)
const hill3LeftPos2=新的动画.Value((hill3Width*-1)-1)
让循环=假
hill3LeftPos.addListener(({value})=>{
//确保第一张图片最左边的部分在屏幕上,并且只为下一张图片设置一次动画
如果(值>0&&!循环){
循环=真
动画序列([
时间(
山丘2,
{
toValue:windowWidth,
持续时间:6000,
放松:放松,线性,
useNativeDriver:错误
}
)]).start()
}
});
useffect(()=>{
循环HILL3animation()
}, []);
const cycleHill3Animation=()=>{
动画序列([
时间(
山丘,
{
toValue:windowWidth,
持续时间:6000,
放松:放松,线性,
useNativeDriver:错误
}
)
]).start(()=>{
//hill3LeftPos.setValue((hill3Width-windowWidth)*-1)
//循环HILL3animation()
})
}
返回(

第二个:


您的代码有几个限制,尤其是无法使用本机动画,因为您正在为视图的左值设置动画。 我已经为您创建了这个工作示例。 确保放置自己的图像,并在imageWidth下的代码中正确设置其宽度

import React, { Component } from 'react';
import {
    Animated,
    Easing,
    Image,
    View,
} from 'react-native';

export default class App extends Component {
    animatedValue;

    constructor() {
        super();

        this.animatedValue = new Animated.Value(0);

        Animated.loop(
            Animated.sequence([
                Animated.timing(this.animatedValue, {
                    toValue: 1,
                    duration: 2000,
                    easing: Easing.linear,
                    useNativeDriver: true,
                }),
                Animated.timing(this.animatedValue, {
                    toValue: 0,
                    duration: 0,
                    easing: Easing.linear,
                    useNativeDriver: true,
                }),
            ]),
        ).start();
    }

    render() {
        const imageWidth = 205;
        const translateX = this.animatedValue.interpolate({
            inputRange: [0, 1],
            outputRange: [-imageWidth, 0],
        });

        return (
            <View style={{
                flex: 1,
                alignItems: 'center',
                justifyContent: 'center',
            }}>
                <View style={{
                    width: imageWidth,
                    overflow: 'hidden',
                }}>
                    <Animated.View style={{
                        width: 2 * imageWidth,
                        flexDirection: 'row',
                        overflow: 'hidden',
                        transform: [{
                            translateX: translateX,
                        }],
                    }}>
                        <Image source={require('./image.png')} />
                        <Image source={require('./image.png')} />
                    </Animated.View>
                </View>
            </View>
        );
    }
}
import React,{Component}来自'React';
进口{
有生气的
缓和,,
形象,,
看法
}从“反应本机”;
导出默认类应用程序扩展组件{
动画价值;
构造函数(){
超级();
this.animatedValue=新的Animated.Value(0);
动画循环(
动画序列([
动画.计时(此.animatedValue{
toValue:1,
期限:2000年,
放松:放松,线性,
useNativeDriver:没错,
}),
动画.计时(此.animatedValue{
toValue:0,
持续时间:0,
放松:放松,线性,
useNativeDriver:没错,
}),
]),
).start();
}
render(){
常数imageWidth=205;
const translateX=this.animatedValue.interpolate({
输入范围:[0,1],
outputRange:[-imageWidth,0],
});
返回(

您的代码有几个限制,尤其是无法使用本机动画,因为您正在为视图的左值设置动画。 我已经为您创建了这个工作示例。 确保放置自己的图像,并在imageWidth下的代码中正确设置其宽度

import React, { Component } from 'react';
import {
    Animated,
    Easing,
    Image,
    View,
} from 'react-native';

export default class App extends Component {
    animatedValue;

    constructor() {
        super();

        this.animatedValue = new Animated.Value(0);

        Animated.loop(
            Animated.sequence([
                Animated.timing(this.animatedValue, {
                    toValue: 1,
                    duration: 2000,
                    easing: Easing.linear,
                    useNativeDriver: true,
                }),
                Animated.timing(this.animatedValue, {
                    toValue: 0,
                    duration: 0,
                    easing: Easing.linear,
                    useNativeDriver: true,
                }),
            ]),
        ).start();
    }

    render() {
        const imageWidth = 205;
        const translateX = this.animatedValue.interpolate({
            inputRange: [0, 1],
            outputRange: [-imageWidth, 0],
        });

        return (
            <View style={{
                flex: 1,
                alignItems: 'center',
                justifyContent: 'center',
            }}>
                <View style={{
                    width: imageWidth,
                    overflow: 'hidden',
                }}>
                    <Animated.View style={{
                        width: 2 * imageWidth,
                        flexDirection: 'row',
                        overflow: 'hidden',
                        transform: [{
                            translateX: translateX,
                        }],
                    }}>
                        <Image source={require('./image.png')} />
                        <Image source={require('./image.png')} />
                    </Animated.View>
                </View>
            </View>
        );
    }
}
import React,{Component}来自'React';
进口{
有生气的
缓和,,
形象,,
看法
}从“反应本机”;
导出默认类应用程序扩展组件{
动画价值;
构造函数(){
超级();
this.animatedValue=新的Animated.Value(0);
动画循环(
动画序列([
动画.计时(此.animatedValue{
toValue:1,
期限:2000年,
放松:放松,线性,
useNativeDriver:没错,
}),
动画.计时(此.animatedValue{
toValue:0,
持续时间:0,
放松:放松,线性,
useNativeDriver:没错,
}),
]),
).start();
}
render(){
常数imageWidth=205;
const translateX=this.animatedValue.interpolate({
输入范围:[0,1],
outputRange:[-imageWidth,0],
});
返回(