gpt4 book ai didi

reactjs - react native : How to animate a particular component?

转载 作者:行者123 更新时间:2023-12-03 14:08:51 25 4
gpt4 key购买 nike

我正在做一个测验。所有选项都将在 for 循环中呈现。

预期行为:

当我点击一个选项时,如果它是错误的答案,那么它应该将背景颜色更改为红色并且它应该摇动。

下面是我正在尝试的代码。

import React, { Component } from "react";
import {
View,
Text,
TouchableWithoutFeedback,
Animated,
Easing
} from "react-native";

class MCQOptions extends Component {
state = {
optionSelectedStatus: 0 // 0: unselected, 1: correct, -1: wrong
};
constructor() {
super();
this.animatedValue = new Animated.Value(0);
this.shakeAnimValue = new Animated.Value(0);
}

onOptionSelected(i) {

// this.props.showNextQuestion();

var answer = this.props.answer;
if (answer == i) {
this.setState({ optionSelectedStatus: 1 });
this.showCorrectAnimation();
} else {
this.setState({ optionSelectedStatus: -1 });
this.showErrorAnimation();
}
}

showErrorAnimation() {
this.shakeAnimValue.setValue(0);
Animated.timing(this.shakeAnimValue, {
toValue: 1,
duration: 300,
easing: Easing.linear
}).start();
}
showCorrectAnimation() {}

getOptions() {
var options = [];
var optionSelectedStyle = styles.optionUnselected;
var optionShadowStyle = styles.optionShadow;
if (this.state.optionSelectedStatus == 1) {
optionSelectedStyle = styles.optionCorrect;
optionShadowStyle = null;
} else if (this.state.optionSelectedStatus == -1) {
optionSelectedStyle = styles.optionWrong;
optionShadowStyle = null;
}

const marginLeft = this.shakeAnimValue.interpolate({
inputRange: [0, 0.2, 0.4, 0.6, 0.8, 0.9, 1],
outputRange: [0, -10, 10, -10, 10, -10, 0]
});

for (var i = 0; i < this.props.options.length; i++) {
options.push(
<TouchableWithoutFeedback
onPress={this.onOptionSelected.bind(this, this.props.indexes[i])}
key={"options_" + i}
>
<View style={styles.optionBox}>
<View style={optionShadowStyle} />
<Animated.Text
style={[
styles.option,
optionSelectedStyle,
{ marginLeft: marginLeft }
]}
key={"option" + i}
>
{this.props.options[i]}
</Animated.Text>
</View>
</TouchableWithoutFeedback>
);
}
return options;
}

render() {
const marginTop = this.animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [100, 0]
});
const opacity = this.animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [0, 1]
});

return (
<Animated.View style={{ marginTop: marginTop, opacity: opacity }}>
{this.getOptions()}
</Animated.View>
);
}

// Animations
componentDidMount() {
this.slideUpOptionsContainer();
}
componentWillReceiveProps() {
this.slideUpOptionsContainer();
this.setState({ optionSelectedStatus: 0 });
}
slideUpOptionsContainer() {
this.animatedValue.setValue(0);
Animated.timing(this.animatedValue, {
toValue: 1,
duration: 300,
easing: Easing.linear
}).start();
}
}

const styles = {
optionBox: {
margin: 5
},
optionsContainer: {
marginTop: 100
},
option: {
padding: 10,
textAlign: "center",
borderRadius: 10,
overflow: "hidden",
width: "100%"
},
optionUnselected: {
backgroundColor: "#FFF"
},
optionWrong: {
backgroundColor: "red"
},
optionCorrect: {
backgroundColor: "green"
},
optionShadow: {
backgroundColor: "rgba(255,255,255,0.85)",
position: "absolute",
width: "100%",
height: "100%",
left: -5,
top: 5,
borderRadius: 10
}
};

export default MCQOptions;

上面的代码对所有选项进行动画(摇动)(根据编写的登录信息,这是正确的),但我陷入了如何仅使单击的选项变得动画而不是全部的情况?

已编辑:

带有 Prop 提要的父组件:

class MCQ extends Component<{}> {

render() {
var options = ["yes", "no", "can't define"];
var indexes = [1,2,3];
var answer = 1;

optionsObj = <MCQOptions
options={options}
indexes={indexes}
answer={answer}/>;

return (
<View style={styles.container} >
<View style={styles.optionsContainer}>
{optionsObj}
</View>
</View>
);
}
}
const styles = {
container: {
flex: 1,
backgroundColor: "blue",
paddingTop: 20,
justifyContent: 'flex-start',
padding: 20
},

};

export default MCQ;

第二次编辑:尝试简化问题。

下面是带有零 Prop 的简化代码。我只想为点击的元素设置动画。

import React, { Component } from "react";
import {
View,
Text,
TouchableWithoutFeedback,
Animated,
Easing
} from "react-native";

class MCQOptions extends Component {
constructor() {
super();
this.shakeAnimValue = new Animated.Value(0);
}
showErrorAnimation() {
this.shakeAnimValue.setValue(0);
Animated.timing(this.shakeAnimValue, {
toValue: 1,
duration: 300,
easing: Easing.linear
}).start();
}

getOptions() {

const marginLeft = this.shakeAnimValue.interpolate({
inputRange: [0, 0.2, 0.4, 0.6, 0.8, 0.9, 1],
outputRange: [0, -10, 10, -10, 10, -10, 0]
});
var options = [];
for (var i = 0; i < 4; i++) {
options.push(
<TouchableWithoutFeedback
onPress={this.showErrorAnimation.bind(this)}
key={"options_" + i}
>
<View style={styles.optionBox}>
<Animated.Text style={[
styles.option,
{ marginLeft: marginLeft }
]}
key={"option" + i}
>
{"Option "+i}
</Animated.Text>
</View>
</TouchableWithoutFeedback>
);
}
return options;
}

render() {
return (
<View style={{ marginTop: 100}}>
{this.getOptions()}
</View>
);
}

}

const styles = {
optionBox: {
margin: 5
},
optionsContainer: {
marginTop: 100
},
option: {
padding: 10,
textAlign: "center",
borderRadius: 10,
overflow: "hidden",
width: "100%"
},
optionUnselected: {
backgroundColor: "#FFF"
},
optionWrong: {
backgroundColor: "red"
},
};

export default MCQOptions;

最佳答案

由于您想单独为它们设置动画,因此它们无法绑定(bind)到同一个 Animated 对象。您必须将它们设置为多个,例如:

示例:

export class App extends Component {
constructor() {
super();
this.getOptions = this.getOptions.bind(this);
this.originalOptions = [0,1,2,3];
this.shakeAnimations = this.originalOptions.map( (i) => new Animated.Value(0) );
}
showErrorAnimation(i) {
this.shakeAnimations[i].setValue(0);
Animated.timing(this.shakeAnimations[i], {
toValue: 1,
duration: 300,
easing: Easing.linear
}).start();
}

getOptions() {

var options = this.originalOptions.map( (i) => {
const marginLeft = this.shakeAnimations[i].interpolate({
inputRange: [0, 0.2, 0.4, 0.6, 0.8, 0.9, 1],
outputRange: [0, -10, 10, -10, 10, -10, 0]
});
return (
<TouchableWithoutFeedback
onPress={() => this.showErrorAnimation(i)}
key={"options_" + i}
>
<View style={styles.optionBox}>
<Animated.Text style={[
styles.option,
{ marginLeft: marginLeft }
]}
key={"option" + i}
>
{"Option "+i}
</Animated.Text>
</View>
</TouchableWithoutFeedback>
)
});
return options;
}

render() {
return (
<View style={{ marginTop: 100}}>
{this.getOptions()}
</View>
);
}

}

const styles = {
optionBox: {
margin: 5
},
optionsContainer: {
marginTop: 100
},
option: {
padding: 10,
textAlign: "center",
borderRadius: 10,
overflow: "hidden",
width: "100%"
},
optionUnselected: {
backgroundColor: "#FFF"
},
optionWrong: {
backgroundColor: "red"
},
};

结果:

enter image description here

关于reactjs - react native : How to animate a particular component?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47921658/

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