Files
Fluxup_PAP/node_modules/react-native/ReactCommon/react/renderer/animations/conversions.h
2026-03-10 16:18:05 +00:00

204 lines
6.3 KiB
C++

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <glog/logging.h>
#include <react/renderer/animations/primitives.h>
#include <optional>
namespace facebook::react {
static inline std::optional<AnimationType> parseAnimationType(std::string param)
{
if (param == "spring") {
return AnimationType::Spring;
}
if (param == "linear") {
return AnimationType::Linear;
}
if (param == "easeInEaseOut") {
return AnimationType::EaseInEaseOut;
}
if (param == "easeIn") {
return AnimationType::EaseIn;
}
if (param == "easeOut") {
return AnimationType::EaseOut;
}
if (param == "keyboard") {
return AnimationType::Keyboard;
}
LOG(ERROR) << "Error parsing animation type: " << param;
return {};
}
static inline std::optional<AnimationProperty> parseAnimationProperty(std::string param)
{
if (param == "opacity") {
return AnimationProperty::Opacity;
}
if (param == "scaleX") {
return AnimationProperty::ScaleX;
}
if (param == "scaleY") {
return AnimationProperty::ScaleY;
}
if (param == "scaleXY") {
return AnimationProperty::ScaleXY;
}
LOG(ERROR) << "Error parsing animation property: " << param;
return {};
}
static inline std::optional<AnimationConfig>
parseAnimationConfig(const folly::dynamic &config, double defaultDuration, bool parsePropertyType)
{
if (config.empty() || !config.isObject()) {
return AnimationConfig{
.animationType = AnimationType::Linear,
.animationProperty = AnimationProperty::NotApplicable,
.duration = defaultDuration,
.delay = 0,
.springDamping = 0,
.initialVelocity = 0};
}
const auto typeIt = config.find("type");
if (typeIt == config.items().end()) {
LOG(ERROR) << "Error parsing animation config: could not find field `type`";
return {};
}
const auto animationTypeParam = typeIt->second;
if (animationTypeParam.empty() || !animationTypeParam.isString()) {
LOG(ERROR) << "Error parsing animation config: could not unwrap field `type`";
return {};
}
const auto animationType = parseAnimationType(animationTypeParam.asString());
if (!animationType) {
LOG(ERROR) << "Error parsing animation config: could not parse field `type`";
return {};
}
AnimationProperty animationProperty = AnimationProperty::NotApplicable;
if (parsePropertyType) {
const auto propertyIt = config.find("property");
if (propertyIt == config.items().end()) {
LOG(ERROR) << "Error parsing animation config: could not find field `property`";
return {};
}
const auto animationPropertyParam = propertyIt->second;
if (animationPropertyParam.empty() || !animationPropertyParam.isString()) {
LOG(ERROR) << "Error parsing animation config: could not unwrap field `property`";
return {};
}
const auto animationPropertyParsed = parseAnimationProperty(animationPropertyParam.asString());
if (!animationPropertyParsed) {
LOG(ERROR) << "Error parsing animation config: could not parse field `property`";
return {};
}
animationProperty = *animationPropertyParsed;
}
double duration = defaultDuration;
double delay = 0;
Float springDamping = 0.5;
Float initialVelocity = 0;
const auto durationIt = config.find("duration");
if (durationIt != config.items().end()) {
if (durationIt->second.isDouble()) {
duration = durationIt->second.asDouble();
} else {
LOG(ERROR) << "Error parsing animation config: field `duration` must be a number";
return {};
}
}
const auto delayIt = config.find("delay");
if (delayIt != config.items().end()) {
if (delayIt->second.isDouble()) {
delay = delayIt->second.asDouble();
} else {
LOG(ERROR) << "Error parsing animation config: field `delay` must be a number";
return {};
}
}
const auto springDampingIt = config.find("springDamping");
if (springDampingIt != config.items().end() && springDampingIt->second.isDouble()) {
if (springDampingIt->second.isDouble()) {
springDamping = (Float)springDampingIt->second.asDouble();
} else {
LOG(ERROR) << "Error parsing animation config: field `springDamping` must be a number";
return {};
}
}
const auto initialVelocityIt = config.find("initialVelocity");
if (initialVelocityIt != config.items().end()) {
if (initialVelocityIt->second.isDouble()) {
initialVelocity = (Float)initialVelocityIt->second.asDouble();
} else {
LOG(ERROR) << "Error parsing animation config: field `initialVelocity` must be a number";
return {};
}
}
return std::optional<AnimationConfig>(AnimationConfig{
.animationType = *animationType,
.animationProperty = animationProperty,
.duration = duration,
.delay = delay,
.springDamping = springDamping,
.initialVelocity = initialVelocity});
}
// Parse animation config from JS
static inline std::optional<LayoutAnimationConfig> parseLayoutAnimationConfig(const folly::dynamic &config)
{
if (config.empty() || !config.isObject()) {
return {};
}
const auto durationIt = config.find("duration");
if (durationIt == config.items().end() || !durationIt->second.isDouble()) {
return {};
}
const double duration = durationIt->second.asDouble();
const auto createConfigIt = config.find("create");
const auto createConfig = createConfigIt == config.items().end()
? std::optional<AnimationConfig>(AnimationConfig{})
: parseAnimationConfig(createConfigIt->second, duration, true);
const auto updateConfigIt = config.find("update");
const auto updateConfig = updateConfigIt == config.items().end()
? std::optional<AnimationConfig>(AnimationConfig{})
: parseAnimationConfig(updateConfigIt->second, duration, false);
const auto deleteConfigIt = config.find("delete");
const auto deleteConfig = deleteConfigIt == config.items().end()
? std::optional<AnimationConfig>(AnimationConfig{})
: parseAnimationConfig(deleteConfigIt->second, duration, true);
if (!createConfig || !updateConfig || !deleteConfig) {
return {};
}
return LayoutAnimationConfig{
.duration = duration,
.createConfig = *createConfig,
.updateConfig = *updateConfig,
.deleteConfig = *deleteConfig};
}
} // namespace facebook::react