Skip to content

Commit 716cbae

Browse files
zeyapfacebook-github-bot
authored andcommitted
support ObjectAnimatedNode (facebook#53517)
Summary: Pull Request resolved: facebook#53517 ## Changelog: [Internal] [Added] - support ObjectAnimatedNode Reviewed By: christophpurrer, fabriziocucci Differential Revision: D81260836 fbshipit-source-id: 82bdda59d54140189684003adfb1adf5c8e2904d
1 parent 5128d35 commit 716cbae

8 files changed

Lines changed: 230 additions & 0 deletions

File tree

packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <react/renderer/animated/nodes/InterpolationAnimatedNode.h>
2626
#include <react/renderer/animated/nodes/ModulusAnimatedNode.h>
2727
#include <react/renderer/animated/nodes/MultiplicationAnimatedNode.h>
28+
#include <react/renderer/animated/nodes/ObjectAnimatedNode.h>
2829
#include <react/renderer/animated/nodes/PropsAnimatedNode.h>
2930
#include <react/renderer/animated/nodes/RoundAnimatedNode.h>
3031
#include <react/renderer/animated/nodes/StyleAnimatedNode.h>
@@ -145,6 +146,8 @@ std::unique_ptr<AnimatedNode> NativeAnimatedNodesManager::animatedNode(
145146
return std::make_unique<DiffClampAnimatedNode>(tag, config, *this);
146147
case AnimatedNodeType::Round:
147148
return std::make_unique<RoundAnimatedNode>(tag, config, *this);
149+
case AnimatedNodeType::Object:
150+
return std::make_unique<ObjectAnimatedNode>(tag, config, *this);
148151
default:
149152
LOG(WARNING) << "Cannot create AnimatedNode of type " << typeName
150153
<< ", it's not implemented yet";

packages/react-native/ReactCommon/react/renderer/animated/nodes/AnimatedNode.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ std::optional<AnimatedNodeType> AnimatedNode::getNodeTypeByName(
7373
return AnimatedNodeType::Tracking;
7474
} else if (nodeTypeName == "round") {
7575
return AnimatedNodeType::Round;
76+
} else if (nodeTypeName == "object") {
77+
return AnimatedNodeType::Object;
7678
} else {
7779
return std::nullopt;
7880
}

packages/react-native/ReactCommon/react/renderer/animated/nodes/AnimatedNode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ enum class AnimatedNodeType {
3232
Tracking,
3333
Color,
3434
Round,
35+
Object
3536
};
3637

3738
class NativeAnimatedNodesManager;
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
/*
9+
* Adapted from react-native-windows under the MIT license.
10+
*/
11+
12+
#include "ObjectAnimatedNode.h"
13+
14+
#include <glog/logging.h>
15+
#include <react/renderer/animated/NativeAnimatedNodesManager.h>
16+
#include <react/renderer/animated/internal/NativeAnimatedAllowlist.h>
17+
#include <react/renderer/animated/nodes/ColorAnimatedNode.h>
18+
#include <react/renderer/animated/nodes/TransformAnimatedNode.h>
19+
#include <react/renderer/animated/nodes/ValueAnimatedNode.h>
20+
21+
namespace facebook::react {
22+
23+
ObjectAnimatedNode::ObjectAnimatedNode(
24+
Tag tag,
25+
const folly::dynamic& config,
26+
NativeAnimatedNodesManager& manager)
27+
: AnimatedNode(tag, config, manager, AnimatedNodeType::Object) {}
28+
29+
void ObjectAnimatedNode::collectViewUpdates(
30+
std::string propKey,
31+
folly::dynamic& props) {
32+
const auto& value = getConfig()["value"];
33+
switch (value.type()) {
34+
case folly::dynamic::OBJECT: {
35+
props.insert(propKey, collectViewUpdatesObjectHelper(value));
36+
} break;
37+
case folly::dynamic::ARRAY: {
38+
props.insert(propKey, collectViewUpdatesArrayHelper(value));
39+
} break;
40+
default: {
41+
LOG(ERROR) << "Invalid value type for ObjectAnimatedNode";
42+
} break;
43+
}
44+
}
45+
46+
folly::dynamic ObjectAnimatedNode::collectViewUpdatesObjectHelper(
47+
const folly::dynamic& value) const {
48+
folly::dynamic result = folly::dynamic::object();
49+
for (const auto& valueProp : value.items()) {
50+
result.insert(valueProp.first.asString(), getValueProp(valueProp.second));
51+
}
52+
return result;
53+
}
54+
55+
folly::dynamic ObjectAnimatedNode::collectViewUpdatesArrayHelper(
56+
const folly::dynamic& value) const {
57+
folly::dynamic result = folly::dynamic::array();
58+
for (const auto& valueProp : value) {
59+
result.push_back(getValueProp(valueProp));
60+
}
61+
return result;
62+
}
63+
64+
folly::dynamic ObjectAnimatedNode::getValueProp(
65+
const folly::dynamic& prop) const {
66+
switch (prop.type()) {
67+
case folly::dynamic::OBJECT: {
68+
if (auto itNodeTag = prop.find("nodeTag");
69+
itNodeTag != prop.items().end()) {
70+
auto nodeTag = static_cast<Tag>(itNodeTag->second.asInt());
71+
if (auto node = manager_->getAnimatedNode<AnimatedNode>(nodeTag)) {
72+
switch (node->type()) {
73+
case AnimatedNodeType::Value:
74+
case AnimatedNodeType::Interpolation:
75+
case AnimatedNodeType::Modulus:
76+
case AnimatedNodeType::Round:
77+
case AnimatedNodeType::Diffclamp:
78+
// Operators
79+
case AnimatedNodeType::Addition:
80+
case AnimatedNodeType::Subtraction:
81+
case AnimatedNodeType::Multiplication:
82+
case AnimatedNodeType::Division: {
83+
if (const auto valueNode =
84+
manager_->getAnimatedNode<ValueAnimatedNode>(nodeTag)) {
85+
if (valueNode->getIsColorValue()) {
86+
return static_cast<int32_t>(valueNode->getValue());
87+
} else {
88+
return valueNode->getValue();
89+
}
90+
}
91+
} break;
92+
case AnimatedNodeType::Color: {
93+
if (const auto colorAnimNode =
94+
manager_->getAnimatedNode<ColorAnimatedNode>(nodeTag)) {
95+
return static_cast<int32_t>(colorAnimNode->getColor());
96+
}
97+
} break;
98+
default:
99+
break;
100+
}
101+
}
102+
} else {
103+
return collectViewUpdatesObjectHelper(prop);
104+
}
105+
} break;
106+
case folly::dynamic::ARRAY: {
107+
return collectViewUpdatesArrayHelper(prop);
108+
};
109+
case folly::dynamic::NULLT:
110+
case folly::dynamic::BOOL:
111+
case folly::dynamic::DOUBLE:
112+
case folly::dynamic::INT64:
113+
case folly::dynamic::STRING: {
114+
return prop;
115+
};
116+
}
117+
LOG(ERROR) << "Invalid prop type for ObjectAnimatedNode";
118+
return nullptr;
119+
}
120+
121+
} // namespace facebook::react
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
/*
9+
* Adapted from react-native-windows under the MIT license.
10+
*/
11+
12+
#pragma once
13+
14+
#include "AnimatedNode.h"
15+
16+
#include <folly/dynamic.h>
17+
18+
namespace facebook::react {
19+
20+
class ObjectAnimatedNode final : public AnimatedNode {
21+
public:
22+
ObjectAnimatedNode(
23+
Tag tag,
24+
const folly::dynamic& config,
25+
NativeAnimatedNodesManager& manager);
26+
void collectViewUpdates(std::string propKey, folly::dynamic& props);
27+
28+
private:
29+
folly::dynamic collectViewUpdatesObjectHelper(
30+
const folly::dynamic& value) const;
31+
32+
folly::dynamic collectViewUpdatesArrayHelper(
33+
const folly::dynamic& value) const;
34+
35+
folly::dynamic getValueProp(const folly::dynamic& prop) const;
36+
};
37+
38+
} // namespace facebook::react

packages/react-native/ReactCommon/react/renderer/animated/nodes/PropsAnimatedNode.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <react/debug/react_native_assert.h>
1515
#include <react/renderer/animated/NativeAnimatedNodesManager.h>
1616
#include <react/renderer/animated/nodes/ColorAnimatedNode.h>
17+
#include <react/renderer/animated/nodes/ObjectAnimatedNode.h>
1718
#include <react/renderer/animated/nodes/StyleAnimatedNode.h>
1819
#include <react/renderer/animated/nodes/ValueAnimatedNode.h>
1920

@@ -126,6 +127,12 @@ void PropsAnimatedNode::update(bool forceFabricCommit) {
126127
styleNode->collectViewUpdates(props_);
127128
}
128129
} break;
130+
case AnimatedNodeType::Object: {
131+
if (const auto objectNode =
132+
manager_->getAnimatedNode<ObjectAnimatedNode>(nodeTag)) {
133+
objectNode->collectViewUpdates(propName, props_);
134+
}
135+
} break;
129136
case AnimatedNodeType::Props:
130137
case AnimatedNodeType::Tracking:
131138
case AnimatedNodeType::Transform:

packages/react-native/ReactCommon/react/renderer/animated/nodes/StyleAnimatedNode.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <react/renderer/animated/NativeAnimatedNodesManager.h>
1515
#include <react/renderer/animated/internal/NativeAnimatedAllowlist.h>
1616
#include <react/renderer/animated/nodes/ColorAnimatedNode.h>
17+
#include <react/renderer/animated/nodes/ObjectAnimatedNode.h>
1718
#include <react/renderer/animated/nodes/TransformAnimatedNode.h>
1819
#include <react/renderer/animated/nodes/ValueAnimatedNode.h>
1920

@@ -82,6 +83,12 @@ void StyleAnimatedNode::collectViewUpdates(folly::dynamic& props) {
8283
static_cast<int32_t>(colorAnimNode->getColor()));
8384
}
8485
} break;
86+
case AnimatedNodeType::Object: {
87+
if (const auto objectNode =
88+
manager_->getAnimatedNode<ObjectAnimatedNode>(nodeTag)) {
89+
objectNode->collectViewUpdates(propName, props);
90+
}
91+
} break;
8592
case AnimatedNodeType::Tracking:
8693
case AnimatedNodeType::Style:
8794
case AnimatedNodeType::Props:

packages/react-native/ReactCommon/react/renderer/animated/tests/AnimatedNodeTests.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "AnimationTestsBase.h"
99

1010
#include <react/renderer/animated/nodes/ColorAnimatedNode.h>
11+
#include <react/renderer/animated/nodes/ObjectAnimatedNode.h>
1112
#include <react/renderer/core/ReactRootViewTagGenerator.h>
1213
#include <react/renderer/graphics/Color.h>
1314

@@ -214,4 +215,54 @@ TEST_F(AnimatedNodeTests, DiffClampAnimatedNode) {
214215
EXPECT_EQ(nodesManager_->getValue(diffClampTag), 1);
215216
}
216217

218+
TEST_F(AnimatedNodeTests, ObjectAnimatedNode) {
219+
initNodesManager();
220+
221+
auto rootTag = getNextRootViewTag();
222+
223+
auto valueTag = ++rootTag;
224+
auto objectTag = ++rootTag;
225+
nodesManager_->createAnimatedNode(
226+
valueTag,
227+
folly::dynamic::object("type", "value")("value", 4)("offset", 0));
228+
229+
nodesManager_->createAnimatedNode(
230+
objectTag,
231+
folly::dynamic::object("type", "object")(
232+
"value",
233+
folly::dynamic::array(
234+
folly::dynamic::object(
235+
"translate3d",
236+
folly::dynamic::object("x", 1)("y", 0)("z", 0)),
237+
folly::dynamic::object(
238+
"rotate3d",
239+
folly::dynamic::object("x", 1)("y", 0)("z", 0)(
240+
"angle", "180deg")),
241+
folly::dynamic::object(
242+
"scale3d", folly::dynamic::object("nodeTag", valueTag)))));
243+
244+
nodesManager_->connectAnimatedNodes(valueTag, objectTag);
245+
246+
const auto objectNode =
247+
nodesManager_->getAnimatedNode<ObjectAnimatedNode>(objectTag);
248+
folly::dynamic collectedProps = folly::dynamic::object();
249+
objectNode->collectViewUpdates("test", collectedProps);
250+
251+
const auto expected = folly::dynamic::object(
252+
"test",
253+
folly::dynamic::array(
254+
folly::dynamic::object(
255+
"translate3d", folly::dynamic::object("x", 1)("y", 0)("z", 0)),
256+
folly::dynamic::object(
257+
"rotate3d",
258+
folly::dynamic::object("x", 1)("y", 0)("z", 0)(
259+
"angle", "180deg")),
260+
folly::dynamic::object("scale3d", 4)));
261+
EXPECT_EQ(collectedProps["test"].size(), 3);
262+
EXPECT_EQ(collectedProps["test"][0]["translate3d"]["x"], 1);
263+
EXPECT_EQ(collectedProps["test"][1]["rotate3d"]["y"], 0);
264+
EXPECT_EQ(collectedProps["test"][1]["rotate3d"]["angle"], "180deg");
265+
EXPECT_EQ(collectedProps["test"][2]["scale3d"], 4);
266+
}
267+
217268
} // namespace facebook::react

0 commit comments

Comments
 (0)