我有两张图像,它们之间几乎没有什么区别,每张图像都对应一个特定的状态。更改状态时,我需要从一个平滑过渡到另一个,以使效果感觉像只有两个图像中不同的部分都经过了动画处理,其余图像保持原样。
我希望它能正常工作,以便在stateChange上渲染第二张图像时,只有第二张图像中的杆状部分看起来会淡入,其余部分保持静止。
我认为无需使用react-transition-group
这样的动画库就可以实现这一点,这可能是通过使用React中的某些生命周期方法以及很明显的AnimatedAPI实现的。我面临的主要问题是,当我更新状态时,我无法控制先前渲染的图像。我希望以某种方式保留先前渲染的图像,直到出现新渲染的Component并对其进行动画处理为止。这是我尝试做的。我有这个ImageLoader组件,它可以在提供淡入淡出动画的同时渲染图像。
class ImageLoader extends React.Component {
constructor(){
super()
this.opacity= new Animated.Value(0)
}
componentDidUpdate(){
{this.onLoad()}
}
onLoad = () => {
this.opacity.setValue(0);
Animated.timing(this.opacity, {
toValue: 1,
duration: 500,
useNativeDriver: true,
}).start();
}
render() {
return (
<Animated.Image onLoad={this.onLoad}{...this.props}style={[
{opacity: this.opacity,}, this.props.style,
]}
/>
);
}
}
export default class App extends React.Component {
state={
no:1,
}
render() {
let Dun=()=>{return this.state.no==1?
<ImageLoader source={require('./assets/img1.PNG')}/>: <ImageLoader
source={require('./assets/img2.PNG')}/>
}
const calc=()=>{
this.setState((state)=>({no:Math.abs(state.no-1)}));
}
return (
<View style={styles.container}>
<View style={{height:100,marginLeft:50}}>
{Dun()}
<Button onPress={()=>{calc()}}> Press</Button>
</View>
</View>
);
}
}
答案 0 :(得分:0)
您可以使用2张动画图像来给人一种印象,即它们正在逐渐淡入另一幅。这是根据您的示例提供的解决方案:
import React from 'react';
import { Animated, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import images from 'src/images';
const styles = StyleSheet.create({
image: {
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0
}
});
class ImageSwitcher extends React.Component {
fadeInOpacity = new Animated.Value(0);
fadeOutOpacity = new Animated.Value(1);
state = {
prevSource: null
};
componentDidMount() {
this.onLoad();
}
componentDidUpdate() {
this.onLoad();
}
componentWillReceiveProps({ source: newSource }) {
const { source } = this.props;
if (newSource !== source) {
this.setState({ prevSource: source });
}
}
onLoad = () => {
this.fadeInOpacity.setValue(0);
this.fadeOutOpacity.setValue(1);
Animated.timing(this.fadeInOpacity, {
toValue: 1,
duration: 500,
useNativeDriver: true
}).start();
Animated.timing(this.fadeOutOpacity, {
toValue: 0,
duration: 500,
useNativeDriver: true
}).start();
};
render() {
const { prevSource } = this.state;
return (
<View
style={{
width: 200,
height: 200
}}
>
<Animated.Image {...this.props} style={[styles.image, { opacity: this.fadeInOpacity }]} resizeMode="cover" />
{prevSource && (
<Animated.Image {...this.props} style={[styles.image, { opacity: this.fadeOutOpacity }]} resizeMode="cover" source={prevSource} />
)}
</View>
);
}
}
export default class App extends React.Component {
state = {
source: images.first
};
handleToggle = () => this.setState(({ source }) => ({ source: source === images.first ? images.second : images.first }));
render() {
const { source } = this.state;
return (
<View style={{ flex: 1 }}>
<ImageSwitcher source={source} />
<TouchableOpacity onPress={this.handleToggle}>
<Text>Toggle Image</Text>
</TouchableOpacity>
</View>
);
}
}