React native 反应本机无限重复图像动画不同步
我正在尝试使用一组图像在React Native中创建一个无限视差背景动画。我已经成功地创建了一个动画。然而,看起来动画运行的时间越长,它们就越不同步 总的来说,我编写的代码按照以下顺序创建了三个动画:React native 反应本机无限重复图像动画不同步,react-native,expo,React Native,Expo,我正在尝试使用一组图像在React Native中创建一个无限视差背景动画。我已经成功地创建了一个动画。然而,看起来动画运行的时间越长,它们就越不同步 总的来说,我编写的代码按照以下顺序创建了三个动画: 将图像组件y偏移从其初始位置移动到0 将图像组件y偏移从0移动到-image.height 将图像分量y偏移立即移动到所有图像分量的原始和 将图像组件y偏移再次移动到0 再次将图像组件y偏移移动到-image.height 我将动画序列3-5放在一个循环中,以便它们无限期地重复 我也有同样的问题
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { Constants } from 'expo';
// You can import from local files
import ScrollingBackground from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<ScrollingBackground style={styles.scrollingBackground} images={[require('./assets/chess.png'),require('./assets/chess.png'),require('./assets/chess.png')]}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#ecf0f1',
},
scrollingBackground: {
width: '100%',
height: '100%',
backgroundColor: 'blue',
},
});
import*as React from'React';
从“react native”导入{Text,View,StyleSheet};
从“expo”导入{Constants};
//可以从本地文件导入
从“/components/AssetExample”导入ScrollingBackground;
//或npm中可用的任何纯javascript模块
从“react native paper”导入{Card};
导出默认类App扩展React.Component{
render(){
返回(
);
}
}
const styles=StyleSheet.create({
容器:{
弹性:1,
为内容辩护:“中心”,
背景颜色:“#ecf0f1”,
},
滚动背景:{
宽度:“100%”,
高度:“100%”,
背景颜色:“蓝色”,
},
});
AssetExample.js
import React, { Component } from "react";
import {
StyleSheet,
View,
Animated,
Image,
Dimensions,
Easing
} from "react-native";
export default class ScrollingBackground extends Component {
constructor(props) {
super(props);
}
componentWillMount() {
let imageComponents = [];
let lastImageYOffset = 0;
let counter = 0;
let deviceWidth = Dimensions.get("window").width;
this.props.images.forEach(image => {
const { width, height } = Image.resolveAssetSource(image);
let localElement = {};
let currentKey = "image" + counter.toString();
localElement.width = width;
localElement.height = (height * deviceWidth) / width;
localElement.initialOffset = lastImageYOffset;
localElement.topPositionAnimated = new Animated.Value(lastImageYOffset);
localElement.image = image;
localElement.currentKey = currentKey;
imageComponents.push(localElement);
lastImageYOffset = lastImageYOffset + localElement.height;
counter++;
});
lastImageYOffset = lastImageYOffset - imageComponents[imageComponents.length-1].height
this.setState({
imageComponents: imageComponents,
lastImageYOffset: lastImageYOffset
});
}
componentDidMount() {
let animations = [];
let arrayLength = this.state.imageComponents.length;
for (let i = 0; i < arrayLength; i++) {
// let height = -1 * this.state.imageComponents[i].height
// this.state.imageComponents[i].topPositionAnimated.addListener(({value}) => value == height ? console.log(this.state) : "");
animations.push(
Animated.sequence([
Animated.timing(this.state.imageComponents[i].topPositionAnimated, {
toValue: 0,
duration:
10 *
(this.state.imageComponents[i].initialOffset),
delay: 0,
easing: Easing.linear,
useNativeDriver: true
}),
Animated.timing(this.state.imageComponents[i].topPositionAnimated, {
toValue: -1 * this.state.imageComponents[i].height,
duration:
10 *
(this.state.imageComponents[i].height),
delay: 0,
easing: Easing.linear,
useNativeDriver: true
}),
Animated.loop(
Animated.sequence([
Animated.timing(this.state.imageComponents[i].topPositionAnimated, {
toValue: this.state.lastImageYOffset,
duration: 0,
delay: 0,
useNativeDriver: true
}),
Animated.timing(this.state.imageComponents[i].topPositionAnimated, {
toValue: 0,
duration:
10 *
(this.state.lastImageYOffset),
delay: 0,
easing: Easing.linear,
useNativeDriver: true
}),
Animated.timing(this.state.imageComponents[i].topPositionAnimated, {
toValue: -1 * this.state.imageComponents[i].height,
duration:
10 *
(this.state.imageComponents[i].height),
delay: 0,
easing: Easing.linear,
useNativeDriver: true
}),
])
)
])
);
}
Animated.parallel(animations).start();
}
render() {
let elements = [];
for (imageComponent of this.state.imageComponents) {
elements.push(
<Animated.Image
key={imageComponent.currentKey}
source={imageComponent.image}
style={{
position: "absolute",
width: "100%",
height: imageComponent.height,
transform: [
{
translateY: imageComponent.topPositionAnimated
}
],
backgroundColor: "white"
}}
/>
);
}
return (
<View
style={[
styles.container,
{ backgroundColor: this.props.style.backgroundColor }
]}
>
{elements}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
width: "100%",
height: "100%"
}
});
import React,{Component}来自“React”;
进口{
样式表,
看法
有生气的
形象,,
尺寸,
缓和
}从“反应本族语”;
导出默认类ScrollingBackground扩展组件{
建造师(道具){
超级(道具);
}
组件willmount(){
设imageComponents=[];
设lastImageYOffset=0;
设计数器=0;
设deviceWidth=Dimensions.get(“窗口”).width;
this.props.images.forEach(image=>{
const{width,height}=Image.resolveAssetSource(Image);
让localElement={};
让currentKey=“image”+counter.toString();
localElement.width=宽度;
localElement.height=(高度*设备宽度)/宽度;
localElement.initialOffset=lastImageYOffset;
localElement.TopPositionAnimate=新的动画.Value(lastImageYOffset);
localElement.image=image;
localElement.currentKey=currentKey;
push(localElement);
lastImageYOffset=lastImageYOffset+localElement.height;
计数器++;
});
lastImageYOffset=lastImageYOffset-imageComponents[imageComponents.length-1]。高度
这是我的国家({
imageComponents:imageComponents,
lastImageYOffset:lastImageYOffset
});
}
componentDidMount(){
让动画=[];
设arrayLength=this.state.imageComponents.length;
for(设i=0;ivalue==height?console.log(this.state):“”);
动画.推送(
动画序列([
动画.timing(this.state.imageComponents[i].topPositionAnimated{
toValue:0,
持续时间:
10 *
(this.state.imageComponents[i].initialOffset),
延迟:0,
放松:放松,线性,
useNativeDriver:真的吗
}),
动画.timing(this.state.imageComponents[i].topPositionAnimated{
toValue:-1*this.state.imageComponents[i]。高度,
持续时间:
10 *
(this.state.imageComponents[i].height),
延迟:0,
放松:放松,线性,
useNativeDriver:真的吗
}),
动画循环(
动画序列([
动画.timing(this.state.imageComponents[i].topPositionAnimated{
toValue:this.state.lastImageYOffset,
持续时间:0,
延迟:0,
useNativeDriver:真的吗
}),
动画.timing(this.state.imageComponents[i].topPositionAnimated{
toValue:0,
持续时间:
10 *
(此.state.lastImageYOffset),
延迟:0,
放松:放松,线性,
useNativeDriver:真的吗
}),
动画.timing(this.state.imageComponents[i].topPositionAnimated{
toValue:-1*this.state.imageComponents[i]。高度,
持续时间:
10 *
(this.state.imageComponents[i].height),
延迟:0,
放松:放松,线性,
useNativeDriver:真的吗
}),
])
)
])
);
}
动画.parallel(动画).start();
}
render(){
让元素=[];
for(此.state.imageComponents的imageComponent){
元素。推(
);
}
返回(
{elements}
);
}
}
const styles=StyleSheet.create({
容器:{
弹性:1,
宽度:“100%”,
身高:“100%”
}
});
由于设置多个视图动画的延迟问题,设置包含所有单个图像视图的容器视图动画是更好的选择。我最终为此创建了一个react本机库: