Skip to content

Commit 4e57c34

Browse files
coadofacebook-github-bot
authored andcommitted
Implementation of transform and border radius props on animation backend (#54698)
Summary: Adds support for transform and border radius props to be handled by shared animation backend. ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [INTERNAL] Test Plan: Checked on reanimated example app. Differential Revision: D87922886 Pulled By: coado
1 parent b37023c commit 4e57c34

File tree

5 files changed

+161
-22
lines changed

5 files changed

+161
-22
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
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+
#include "AnimatedPropsSerializer.h"
9+
10+
namespace facebook::react {
11+
12+
void AnimatedPropsSerializer::packBorderRadiusCorner(
13+
folly::dynamic& dyn,
14+
const std::string& propName,
15+
const std::optional<ValueUnit>& cornerValue) {
16+
if (cornerValue.has_value()) {
17+
dyn.insert(propName, cornerValue.value().value);
18+
}
19+
}
20+
21+
void AnimatedPropsSerializer::packBorderRadii(
22+
folly::dynamic& dyn,
23+
const AnimatedPropBase& animatedProp) {
24+
const auto& borderRadii = get<CascadedBorderRadii>(animatedProp);
25+
26+
packBorderRadiusCorner(dyn, "borderTopRightRadius", borderRadii.topRight);
27+
packBorderRadiusCorner(dyn, "borderTopLeftRadius", borderRadii.topLeft);
28+
packBorderRadiusCorner(
29+
dyn, "borderBottomRightRadius", borderRadii.bottomRight);
30+
packBorderRadiusCorner(dyn, "borderBottomLeftRadius", borderRadii.bottomLeft);
31+
packBorderRadiusCorner(dyn, "borderTopStartRadius", borderRadii.topStart);
32+
packBorderRadiusCorner(dyn, "borderTopEndRadius", borderRadii.topEnd);
33+
packBorderRadiusCorner(
34+
dyn, "borderBottomStartRadius", borderRadii.bottomStart);
35+
packBorderRadiusCorner(dyn, "borderBottomEndRadius", borderRadii.bottomEnd);
36+
packBorderRadiusCorner(dyn, "borderStartStartRadius", borderRadii.startStart);
37+
packBorderRadiusCorner(dyn, "borderStartEndRadius", borderRadii.startEnd);
38+
packBorderRadiusCorner(dyn, "borderEndStartRadius", borderRadii.endStart);
39+
packBorderRadiusCorner(dyn, "borderEndEndRadius", borderRadii.endEnd);
40+
41+
if (borderRadii.all.has_value()) {
42+
dyn.insert("borderRadius", borderRadii.all.value().value);
43+
}
44+
}
45+
46+
void AnimatedPropsSerializer::packOpacity(
47+
folly::dynamic& dyn,
48+
const AnimatedPropBase& animatedProp) {
49+
dyn.insert("opacity", get<Float>(animatedProp));
50+
}
51+
52+
void AnimatedPropsSerializer::packTransform(
53+
folly::dynamic& dyn,
54+
const AnimatedPropBase& animatedProp) {
55+
const auto transform = get<Transform>(animatedProp);
56+
const auto matrixArray = folly::dynamic::array(
57+
transform.matrix[0],
58+
transform.matrix[1],
59+
transform.matrix[2],
60+
transform.matrix[3],
61+
transform.matrix[4],
62+
transform.matrix[5],
63+
transform.matrix[6],
64+
transform.matrix[7],
65+
transform.matrix[8],
66+
transform.matrix[9],
67+
transform.matrix[10],
68+
transform.matrix[11],
69+
transform.matrix[12],
70+
transform.matrix[13],
71+
transform.matrix[14],
72+
transform.matrix[15]);
73+
dyn.insert(
74+
"transform",
75+
folly::dynamic::array(
76+
folly::dynamic::object("matrix", std::move(matrixArray))));
77+
}
78+
79+
void AnimatedPropsSerializer::packBackgroundColor(
80+
folly::dynamic& dyn,
81+
const AnimatedPropBase& animatedProp) {
82+
const auto& backgroundColor = get<SharedColor>(animatedProp);
83+
if (backgroundColor) {
84+
dyn.insert("backgroundColor", static_cast<int32_t>(*backgroundColor));
85+
}
86+
}
87+
88+
void AnimatedPropsSerializer::packAnimatedProp(
89+
folly::dynamic& dyn,
90+
const std::unique_ptr<AnimatedPropBase>& animatedProp) {
91+
switch (animatedProp->propName) {
92+
case OPACITY:
93+
packOpacity(dyn, *animatedProp);
94+
break;
95+
96+
case TRANSFORM:
97+
packTransform(dyn, *animatedProp);
98+
break;
99+
100+
case BACKGROUND_COLOR:
101+
packBackgroundColor(dyn, *animatedProp);
102+
break;
103+
104+
case BORDER_RADII:
105+
packBorderRadii(dyn, *animatedProp);
106+
break;
107+
108+
case WIDTH:
109+
case HEIGHT:
110+
case FLEX:
111+
throw "Tried to synchronously update layout props";
112+
}
113+
}
114+
115+
folly::dynamic AnimatedPropsSerializer::packAnimatedProps(
116+
const AnimatedProps& animatedProps) {
117+
auto dyn = animatedProps.rawProps ? animatedProps.rawProps->toDynamic()
118+
: folly::dynamic::object();
119+
120+
for (auto& animatedProp : animatedProps.props) {
121+
packAnimatedProp(dyn, animatedProp);
122+
}
123+
124+
return dyn;
125+
}
126+
} // namespace facebook::react

packages/react-native/ReactCommon/react/renderer/animationbackend/AnimatedProps.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
namespace facebook::react {
1414

15-
enum PropName { OPACITY, WIDTH, HEIGHT, BORDER_RADII, FLEX, TRANSFORM };
15+
enum PropName { OPACITY, WIDTH, HEIGHT, BORDER_RADII, FLEX, TRANSFORM, BACKGROUND_COLOR };
1616

1717
struct AnimatedPropBase {
1818
PropName propName;

packages/react-native/ReactCommon/react/renderer/animationbackend/AnimatedPropsBuilder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ struct AnimatedPropsBuilder {
3535
{
3636
props.push_back(std::make_unique<AnimatedProp<Transform>>(TRANSFORM, std::move(t)));
3737
}
38+
void setBackgroundColor(SharedColor value)
39+
{
40+
props.push_back(std::make_unique<AnimatedProp<SharedColor>>(BACKGROUND_COLOR, value));
41+
}
3842
void storeDynamic(folly::dynamic &d)
3943
{
4044
rawProps = std::make_unique<RawProps>(std::move(d));
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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+
#pragma once
9+
10+
#include <folly/dynamic.h>
11+
#include "AnimatedProps.h"
12+
13+
namespace facebook::react {
14+
class AnimatedPropsSerializer {
15+
public:
16+
static folly::dynamic packAnimatedProps(const AnimatedProps &animatedProps);
17+
static void packAnimatedProp(folly::dynamic &dyn, const std::unique_ptr<AnimatedPropBase> &animatedProp);
18+
19+
private:
20+
static void packOpacity(folly::dynamic &dyn, const AnimatedPropBase &animatedProp);
21+
static void packBorderRadii(folly::dynamic &dyn, const AnimatedPropBase &animatedProp);
22+
static void packTransform(folly::dynamic &dyn, const AnimatedPropBase &animatedProp);
23+
static void packBackgroundColor(folly::dynamic &dyn, const AnimatedPropBase &animatedProp);
24+
static void
25+
packBorderRadiusCorner(folly::dynamic &dyn, const std::string &propName, const std::optional<ValueUnit> &cornerValue);
26+
};
27+
} // namespace facebook::react

packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackend.cpp

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
*/
77

88
#include "AnimationBackend.h"
9+
#include <react/renderer/graphics/Color.h>
910
#include <chrono>
11+
#include "AnimatedPropsSerializer.h"
1012

1113
namespace facebook::react {
1214

@@ -156,27 +158,7 @@ void AnimationBackend::commitUpdates(
156158
void AnimationBackend::synchronouslyUpdateProps(
157159
const std::unordered_map<Tag, AnimatedProps>& updates) {
158160
for (auto& [tag, animatedProps] : updates) {
159-
auto dyn = animatedProps.rawProps ? animatedProps.rawProps->toDynamic()
160-
: folly::dynamic::object();
161-
for (auto& animatedProp : animatedProps.props) {
162-
// TODO: We shouldn't repack it into dynamic, but for that a rewrite of
163-
// directManipulationCallback_ is needed
164-
switch (animatedProp->propName) {
165-
case OPACITY:
166-
dyn.insert("opacity", get<Float>(animatedProp));
167-
break;
168-
169-
case BORDER_RADII:
170-
case TRANSFORM:
171-
// TODO: handle other things than opacity
172-
break;
173-
174-
case WIDTH:
175-
case HEIGHT:
176-
case FLEX:
177-
throw "Tried to synchronously update layout props";
178-
}
179-
}
161+
auto dyn = AnimatedPropsSerializer::packAnimatedProps(animatedProps);
180162
directManipulationCallback_(tag, dyn);
181163
}
182164
}

0 commit comments

Comments
 (0)