mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Set final value via direct manipulation to fix animation glitches (#52012)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/52012 changelog: [internal] On iOS, once a prop on a view is controlled by animated, the control is never released to Fabric or React. That's why it is important to use direct manipulation to commit even final value. Reviewed By: lenaic Differential Revision: D76601913 fbshipit-source-id: ea02219e158f28977018b34ac7152b899723b35a
This commit is contained in:
committed by
Facebook GitHub Bot
parent
0e42d33cbc
commit
eecd07c58b
@@ -32,11 +32,9 @@ test('moving box by 100 points', () => {
|
||||
{
|
||||
width: 100,
|
||||
height: 100,
|
||||
backgroundColor: 'red',
|
||||
},
|
||||
{transform: [{translateX}]},
|
||||
]}
|
||||
testID="box"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -146,3 +144,56 @@ test('animation driven by onScroll event', () => {
|
||||
// TODO(T226364699): this should `toBe(100)` but we are not syncing shadow tree yet.
|
||||
expect(viewElement.getBoundingClientRect().y).toBe(0);
|
||||
});
|
||||
|
||||
test('animated opacity', () => {
|
||||
let _opacity;
|
||||
const viewRef = createRef<HostInstance>();
|
||||
|
||||
function MyApp() {
|
||||
const opacity = useAnimatedValue(1);
|
||||
_opacity = opacity;
|
||||
return (
|
||||
<Animated.View
|
||||
ref={viewRef}
|
||||
style={[
|
||||
{
|
||||
width: 100,
|
||||
height: 100,
|
||||
opacity: opacity,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const root = Fantom.createRoot();
|
||||
|
||||
Fantom.runTask(() => {
|
||||
root.render(<MyApp />);
|
||||
});
|
||||
|
||||
const viewElement = ensureInstance(viewRef.current, ReactNativeElement);
|
||||
|
||||
expect(viewElement.getBoundingClientRect().x).toBe(0);
|
||||
|
||||
Fantom.runTask(() => {
|
||||
Animated.timing(_opacity, {
|
||||
toValue: 0,
|
||||
duration: 30,
|
||||
useNativeDriver: true,
|
||||
}).start();
|
||||
});
|
||||
|
||||
Fantom.unstable_produceFramesForDuration(30);
|
||||
// $FlowFixMe[incompatible-use]
|
||||
expect(Fantom.unstable_getDirectManipulationProps(viewElement).opacity).toBe(
|
||||
0,
|
||||
);
|
||||
|
||||
// TODO: this shouldn't be neccessary but C++ Animated still schedules a React state update.
|
||||
Fantom.runWorkLoop();
|
||||
|
||||
expect(root.getRenderedOutput({props: ['opacity']}).toJSX()).toEqual(
|
||||
<rn-view opacity="0" />,
|
||||
);
|
||||
});
|
||||
|
||||
+6
@@ -756,6 +756,12 @@ bool NativeAnimatedNodesManager::commitProps() {
|
||||
|
||||
if (fabricCommitCallback_ != nullptr) {
|
||||
if (!updateViewProps_.empty()) {
|
||||
// Must call direct manipulation to set final values on components.
|
||||
if (directManipulationCallback_ != nullptr) {
|
||||
for (const auto& [viewTag, props] : updateViewProps_) {
|
||||
directManipulationCallback_(viewTag, folly::dynamic(props));
|
||||
}
|
||||
}
|
||||
fabricCommitCallback_(updateViewProps_);
|
||||
updateViewProps_.clear();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user