fix: change interpolated style when idle to avoid messing up reanimated

This commit is contained in:
satyajit.happy
2019-08-29 19:52:34 +02:00
parent 435b8dbbc8
commit 58c723e2ae

View File

@@ -208,7 +208,11 @@ export default class Card extends React.Component<Props> {
}
if (closing !== prevProps.closing) {
this.isClosing.setValue(closing ? TRUE : FALSE);
// If the style updates during render, setting the value here doesn't work
// We need to defer it a bit so the animation starts properly
requestAnimationFrame(() =>
this.isClosing.setValue(closing ? TRUE : FALSE)
);
}
}
@@ -264,6 +268,17 @@ export default class Card extends React.Component<Props> {
finished: new Value(FALSE),
};
private handleTransitionEnd = () => {
this.isRunningAnimation = false;
this.interpolatedStyle = this.getInterpolatedStyle(
this.props.styleInterpolator,
this.props.index,
this.props.current,
this.props.next,
this.props.layout
);
};
private runTransition = (isVisible: Binary | Animated.Node<number>) => {
const { open: openingSpec, close: closingSpec } = this.props.transitionSpec;
@@ -328,7 +343,9 @@ export default class Card extends React.Component<Props> {
call([this.isVisible], ([value]: ReadonlyArray<Binary>) => {
const isOpen = Boolean(value);
const { onOpen, onClose } = this.props;
this.isRunningAnimation = false;
this.handleTransitionEnd();
if (isOpen) {
onOpen(true);
} else {
@@ -354,7 +371,7 @@ export default class Card extends React.Component<Props> {
cond(neq(this.nextIsVisible, UNSET), [
// Stop any running animations
cond(clockRunning(this.clock), [
call([], () => (this.isRunningAnimation = false)),
call([], this.handleTransitionEnd),
stopClock(this.clock),
]),
set(this.gesture, 0),
@@ -523,6 +540,18 @@ export default class Card extends React.Component<Props> {
})
);
// Keep track of the style in a property to avoid changing the animated node when deps change
// The style shouldn't change in the middle of the animation and should refer to what was there at the start of it
// Which will be the last value when just before the render which started the animation
// We need to make sure to update this when the running animation ends
private interpolatedStyle = this.getInterpolatedStyle(
this.props.styleInterpolator,
this.props.index,
this.props.current,
this.props.next,
this.props.layout
);
private gestureActivationCriteria() {
const { layout, gestureDirection, gestureResponseDistance } = this.props;
@@ -587,18 +616,22 @@ export default class Card extends React.Component<Props> {
...rest
} = this.props;
if (!this.isRunningAnimation) {
this.interpolatedStyle = this.getInterpolatedStyle(
styleInterpolator,
index,
current,
next,
layout
);
}
const {
containerStyle,
cardStyle,
overlayStyle,
shadowStyle,
} = this.getInterpolatedStyle(
styleInterpolator,
index,
current,
next,
layout
);
} = this.interpolatedStyle;
const handleGestureEvent = gestureEnabled
? gestureDirection === 'vertical' ||