我有一个组件父级,它有一个 Animated.value “this.progress”,它采用 [1, 3] 中的值。
Parent 渲染一个 Component Child并将进度作为 props 传递给它:
// File Parent.js
import React from "react";
import { Animated } from "react-native";
import Child from "./Child.js"
class Parent extends React.Component {
constructor(props) {
super(props);
this.progress = new Animated.Value(1)
}
render() {
return (
<Child
progress = {this.progress}
/>
);
}
}
Child 位置取决于进度:
- 如果progress = 1,则子位置为[1, 3]
- 如果progress = 2,则子位置为[2, 2]
- 如果progress = 3,则子位置为[1, 1]
如果动画改变了progress的值,Child必须相应地移动(例如,如果progress是从1到2的动画,用户必须看到Child从[1, 3]平滑地移动到[2, 2] )。
为此,我使用了两个插值:
// In the constructor of Child.js
this.interpolateX = this.props.progress.interpolate({
inputRange: [1, 2, 3],
outputRange: [1, 2, 1],
});
this.interpolateY = this.props.progress.interpolate({
inputRange: [1, 2, 3],
outputRange: [3, 2, 1],
});
我用它们使用“变换”来固定孩子的位置:
// Render method of Child.js
render() {
return (
<Animated.View
style={[
{
transform: [
{
translateX: this.interpolateX,
},
{
translateY: this.interpolateY,
},
],
},
{ position: 'absolute' },
{ left: 0 },
{ top: 0 },
]}
/>
);
}
它运作良好,但现在我还想使用用户手指使 Child 可移动。为此,我定义了一个 panResponder。问题是 panResponder 也使用了转换。我现在有 2 个转换:
- 用于从 this.props.progress 插入 Child 的位置;
- panResponder 用来用用户手指移动 Child 的一种。
我不知道如何结合这两个变换。这是我尝试过的:
// File Child.js
import React from "react";
import { Animated, PanResponder } from "react-native";
class Child extends React.Component {
constructor(props) {
super(props);
this.interpolateX = this.props.progress.interpolate({
inputRange: [1, 2, 3],
outputRange: [1, 2, 1],
});
this.interpolateY = this.props.progress.interpolate({
inputRange: [1, 2, 3],
outputRange: [3, 2, 1],
});
this.offset = new Animated.ValueXY({ x: 0, y: 0 });
this._val = { x: 0, y: 0 };
this.offset.addListener((value) => (this._val = value));
// Initiate the panResponder
this.panResponder = PanResponder.create({
// Ask to be the responder
onStartShouldSetPanResponder: () => true,
// Called when the gesture starts
onPanResponderGrant: () => {
this.offset.setOffset({
x: this._val.x,
y: this._val.y,
});
this.offset.setValue({ x: 0, y: 0 });
},
// Called when a move is made
onPanResponderMove: Animated.event([
null,
{ dx: this.offset.x, dy: this.offset.y },
]),
onPanResponderRelease: (evt, gesturestate) => {
console.log(
"released with offsetX: " +
this.offset.x._value +
"/" +
this.offset.y._value
);
},
});
}
render() {
const panStyle = {
transform: this.offset.getTranslateTransform(),
};
return (
<Animated.View
{...this.panResponder.panHandlers}
style={[
panStyle,
{
transform: [
{
translateX: this.interpolateX,
},
{
translateY: this.interpolateY,
},
],
},
{ position: "absolute" },
{ left: 0 },
{ top: 0 },
]}
/>
);
}
}
export default Child;
这没用。panStyle 似乎被忽略了。我想你不能同时进行两个变换。
我还尝试在转换中“添加”这两个表达式,但没有成功(也许可行)。
我的最后一个想法是在用户移动 Child 时让布尔值“isMoving”等于 true。如果 isMoving 为假,我使用第一个转换,否则,我使用第二个。这似乎很有希望,但我没有成功地让它发挥作用。
你能告诉我我该怎么做吗?