mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
implement Value.extractOffset in C++ Animated (#52049)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/52049 changelog: [internal] As title says, add implementation of [Value.extractOffset](https://reactnative.dev/docs/animatedvalue#extractoffset) Reviewed By: zeyap Differential Revision: D76735003 fbshipit-source-id: db09e2ed1c8b540d911970d2268fcd0374717e96
This commit is contained in:
committed by
Facebook GitHub Bot
parent
cb24596c33
commit
2528e48e93
@@ -355,3 +355,91 @@ describe('Value.flattenOffset', () => {
|
||||
Fantom.runWorkLoop();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Value.extractOffset', () => {
|
||||
it('sets the offset value to the base value and resets the base value to zero', () => {
|
||||
const scrollViewRef = createRef<HostInstance>();
|
||||
const viewRef = createRef<HostInstance>();
|
||||
let _onScroll;
|
||||
|
||||
function PressableWithNativeDriver() {
|
||||
_onScroll = useAnimatedValue(0);
|
||||
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<Animated.View
|
||||
ref={viewRef}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
width: 10,
|
||||
height: 10,
|
||||
transform: [{translateY: _onScroll}],
|
||||
}}
|
||||
/>
|
||||
<Animated.ScrollView
|
||||
ref={scrollViewRef}
|
||||
onScroll={Animated.event(
|
||||
[
|
||||
{
|
||||
nativeEvent: {
|
||||
contentOffset: {
|
||||
y: _onScroll,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
{useNativeDriver: true},
|
||||
)}>
|
||||
<View style={{height: 1000, width: 100}} />
|
||||
</Animated.ScrollView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const root = Fantom.createRoot();
|
||||
Fantom.runTask(() => {
|
||||
root.render(<PressableWithNativeDriver />);
|
||||
});
|
||||
|
||||
const scrollViewelement = ensureInstance(
|
||||
scrollViewRef.current,
|
||||
ReactNativeElement,
|
||||
);
|
||||
const viewElement = ensureInstance(viewRef.current, ReactNativeElement);
|
||||
|
||||
Fantom.scrollTo(scrollViewelement, {
|
||||
x: 0,
|
||||
y: 10,
|
||||
});
|
||||
|
||||
Fantom.runTask(() => {
|
||||
_onScroll.setOffset(15);
|
||||
// Sets offset to be 15 + 10 = 25 (this is not observable from JS).
|
||||
_onScroll.extractOffset();
|
||||
});
|
||||
|
||||
let transform =
|
||||
// $FlowFixMe[incompatible-use]
|
||||
Fantom.unstable_getDirectManipulationProps(viewElement).transform[0];
|
||||
|
||||
// Animated value is now 0 but offset is 25. The final value is 25.
|
||||
expect(transform.translateY).toBeCloseTo(25, 0.001);
|
||||
|
||||
Fantom.runTask(() => {
|
||||
// Sets offset 35, overriding the previous `setOffset`.
|
||||
// Due to `extractOffset`, base value was restarted to 0.
|
||||
_onScroll.setOffset(35);
|
||||
});
|
||||
|
||||
transform =
|
||||
// $FlowFixMe[incompatible-use]
|
||||
Fantom.unstable_getDirectManipulationProps(viewElement).transform[0];
|
||||
|
||||
// `extractOffset` resets value back to 0.
|
||||
// Previously we set offset to 35. The final value is 35.
|
||||
expect(transform.translateY).toBeCloseTo(35, 0.001);
|
||||
|
||||
// TODO: this shouldn't be neccessary.
|
||||
Fantom.runWorkLoop();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -137,8 +137,8 @@ void AnimatedModule::flattenAnimatedNodeOffset(
|
||||
|
||||
void AnimatedModule::extractAnimatedNodeOffset(
|
||||
jsi::Runtime& /*rt*/,
|
||||
Tag /*nodeTag*/) {
|
||||
// TODO(T196513004): missing implementation
|
||||
Tag nodeTag) {
|
||||
operations_.push_back(ExtractAnimatedNodeOffsetOp({.nodeTag = nodeTag}));
|
||||
}
|
||||
|
||||
void AnimatedModule::connectAnimatedNodeToView(
|
||||
@@ -253,6 +253,8 @@ void AnimatedModule::executeOperation(const Operation& operation) {
|
||||
nodesManager_->setAnimatedNodeOffset(op.nodeTag, op.offset);
|
||||
} else if constexpr (std::is_same_v<T, FlattenAnimatedNodeOffsetOp>) {
|
||||
nodesManager_->flattenAnimatedNodeOffset(op.nodeTag);
|
||||
} else if constexpr (std::is_same_v<T, ExtractAnimatedNodeOffsetOp>) {
|
||||
nodesManager_->extractAnimatedNodeOffsetOp(op.nodeTag);
|
||||
} else if constexpr (std::is_same_v<T, ConnectAnimatedNodeToViewOp>) {
|
||||
nodesManager_->connectAnimatedNodeToView(op.nodeTag, op.viewTag);
|
||||
} else if constexpr (std::is_same_v<
|
||||
|
||||
@@ -75,6 +75,10 @@ class AnimatedModule : public NativeAnimatedModuleCxxSpec<AnimatedModule>,
|
||||
Tag nodeTag{};
|
||||
};
|
||||
|
||||
struct ExtractAnimatedNodeOffsetOp {
|
||||
Tag nodeTag{};
|
||||
};
|
||||
|
||||
struct ConnectAnimatedNodeToViewOp {
|
||||
Tag nodeTag{};
|
||||
Tag viewTag{};
|
||||
@@ -120,6 +124,7 @@ class AnimatedModule : public NativeAnimatedModuleCxxSpec<AnimatedModule>,
|
||||
DisconnectAnimatedNodeFromViewOp,
|
||||
RestoreDefaultValuesOp,
|
||||
FlattenAnimatedNodeOffsetOp,
|
||||
ExtractAnimatedNodeOffsetOp,
|
||||
DropAnimatedNodeOp,
|
||||
AddAnimatedEventToViewOp,
|
||||
RemoveAnimatedEventFromViewOp>;
|
||||
|
||||
+6
@@ -260,6 +260,12 @@ void NativeAnimatedNodesManager::flattenAnimatedNodeOffset(Tag tag) {
|
||||
}
|
||||
}
|
||||
|
||||
void NativeAnimatedNodesManager::extractAnimatedNodeOffsetOp(Tag tag) {
|
||||
if (auto node = getAnimatedNode<ValueAnimatedNode>(tag)) {
|
||||
node->extractOffset();
|
||||
}
|
||||
}
|
||||
|
||||
void NativeAnimatedNodesManager::stopAnimationsForNode(Tag nodeTag) {
|
||||
std::vector<int> discardedAnimIds{};
|
||||
|
||||
|
||||
+2
@@ -98,6 +98,8 @@ class NativeAnimatedNodesManager {
|
||||
|
||||
void flattenAnimatedNodeOffset(Tag tag);
|
||||
|
||||
void extractAnimatedNodeOffsetOp(Tag tag);
|
||||
|
||||
void setAnimatedNodeOffset(Tag tag, double offset);
|
||||
|
||||
// drivers
|
||||
|
||||
+3
-2
@@ -71,8 +71,9 @@ void ValueAnimatedNode::flattenOffset() noexcept {
|
||||
}
|
||||
|
||||
void ValueAnimatedNode::extractOffset() noexcept {
|
||||
setOffset(value_ + getOffset());
|
||||
setRawValue(0.0f);
|
||||
offset_ += value_;
|
||||
value_ = 0;
|
||||
onValueUpdate();
|
||||
}
|
||||
|
||||
void ValueAnimatedNode::onValueUpdate() noexcept {
|
||||
|
||||
Reference in New Issue
Block a user