197 lines
6.2 KiB
C++
197 lines
6.2 KiB
C++
#include <reanimated/CSS/configs/CSSAnimationConfig.h>
|
|
|
|
#include <utility>
|
|
|
|
namespace reanimated::css {
|
|
|
|
double getIterationCount(jsi::Runtime &rt, const jsi::Object &settings) {
|
|
return settings.getProperty(rt, "iterationCount").asNumber();
|
|
}
|
|
|
|
AnimationDirection getDirection(jsi::Runtime &rt, const jsi::Object &settings) {
|
|
static const std::unordered_map<std::string, AnimationDirection>
|
|
strToEnumMap = {
|
|
{"normal", AnimationDirection::Normal},
|
|
{"reverse", AnimationDirection::Reverse},
|
|
{"alternate", AnimationDirection::Alternate},
|
|
{"alternate-reverse", AnimationDirection::AlternateReverse}};
|
|
|
|
const auto str = settings.getProperty(rt, "direction").asString(rt).utf8(rt);
|
|
auto it = strToEnumMap.find(str);
|
|
if (it == strToEnumMap.cend()) {
|
|
throw std::invalid_argument(
|
|
"[Reanimated] Invalid animationDirection: " + str);
|
|
}
|
|
return it->second;
|
|
}
|
|
|
|
AnimationFillMode getFillMode(jsi::Runtime &rt, const jsi::Object &settings) {
|
|
static const std::unordered_map<std::string, AnimationFillMode> strToEnumMap =
|
|
{{"none", AnimationFillMode::None},
|
|
{"forwards", AnimationFillMode::Forwards},
|
|
{"backwards", AnimationFillMode::Backwards},
|
|
{"both", AnimationFillMode::Both}};
|
|
|
|
const auto str = settings.getProperty(rt, "fillMode").asString(rt).utf8(rt);
|
|
auto it = strToEnumMap.find(str);
|
|
if (it == strToEnumMap.cend()) {
|
|
throw std::invalid_argument(
|
|
"[Reanimated] Invalid animationFillMode: " + str);
|
|
}
|
|
return it->second;
|
|
}
|
|
|
|
AnimationPlayState getPlayState(jsi::Runtime &rt, const jsi::Object &settings) {
|
|
static const std::unordered_map<std::string, AnimationPlayState>
|
|
strToEnumMap = {
|
|
{"running", AnimationPlayState::Running},
|
|
{"paused", AnimationPlayState::Paused}};
|
|
|
|
const auto str = settings.getProperty(rt, "playState").asString(rt).utf8(rt);
|
|
auto it = strToEnumMap.find(str);
|
|
if (it == strToEnumMap.cend()) {
|
|
throw std::invalid_argument(
|
|
"[Reanimated] Invalid animationPlayState: " + str);
|
|
}
|
|
return it->second;
|
|
}
|
|
|
|
CSSAnimationSettings parseCSSAnimationSettings(
|
|
jsi::Runtime &rt,
|
|
const jsi::Value &settings) {
|
|
const auto &settingsObj = settings.asObject(rt);
|
|
|
|
return {
|
|
getDuration(rt, settingsObj),
|
|
getTimingFunction(rt, settingsObj),
|
|
getDelay(rt, settingsObj),
|
|
getIterationCount(rt, settingsObj),
|
|
getDirection(rt, settingsObj),
|
|
getFillMode(rt, settingsObj),
|
|
getPlayState(rt, settingsObj)};
|
|
}
|
|
|
|
PartialCSSAnimationSettings parsePartialCSSAnimationSettings(
|
|
jsi::Runtime &rt,
|
|
const jsi::Value &partialSettings) {
|
|
const auto &partialObj = partialSettings.asObject(rt);
|
|
|
|
PartialCSSAnimationSettings result;
|
|
|
|
if (partialObj.hasProperty(rt, "duration")) {
|
|
result.duration = getDuration(rt, partialObj);
|
|
}
|
|
if (partialObj.hasProperty(rt, "timingFunction")) {
|
|
result.easingFunction = getTimingFunction(rt, partialObj);
|
|
}
|
|
if (partialObj.hasProperty(rt, "delay")) {
|
|
result.delay = getDelay(rt, partialObj);
|
|
}
|
|
if (partialObj.hasProperty(rt, "iterationCount")) {
|
|
result.iterationCount = getIterationCount(rt, partialObj);
|
|
}
|
|
if (partialObj.hasProperty(rt, "direction")) {
|
|
result.direction = getDirection(rt, partialObj);
|
|
}
|
|
if (partialObj.hasProperty(rt, "fillMode")) {
|
|
result.fillMode = getFillMode(rt, partialObj);
|
|
}
|
|
if (partialObj.hasProperty(rt, "playState")) {
|
|
result.playState = getPlayState(rt, partialObj);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
std::vector<std::string> parseAnimationNames(
|
|
jsi::Runtime &rt,
|
|
const jsi::Value &animationNames) {
|
|
std::vector<std::string> result;
|
|
|
|
const auto &namesArray = animationNames.asObject(rt).asArray(rt);
|
|
const auto animationNamesCount = namesArray.size(rt);
|
|
result.reserve(animationNamesCount);
|
|
|
|
for (size_t i = 0; i < animationNamesCount; i++) {
|
|
result.emplace_back(
|
|
namesArray.getValueAtIndex(rt, i).asString(rt).utf8(rt));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
template <typename TResult>
|
|
std::unordered_map<size_t, TResult> parseHelper(
|
|
jsi::Runtime &rt,
|
|
const jsi::Object &settingsObj,
|
|
std::function<TResult(jsi::Runtime &, const jsi::Value &)> parseFunction) {
|
|
std::unordered_map<size_t, TResult> result;
|
|
|
|
const auto animationIndices = settingsObj.getPropertyNames(rt);
|
|
const auto animationIndicesCount = animationIndices.size(rt);
|
|
result.reserve(animationIndicesCount);
|
|
|
|
for (size_t i = 0; i < animationIndicesCount; i++) {
|
|
const auto &indexStr = animationIndices.getValueAtIndex(rt, i).toString(rt);
|
|
const auto &animationSettings = settingsObj.getProperty(rt, indexStr);
|
|
|
|
const auto index = std::stoul(indexStr.utf8(rt));
|
|
result[index] = parseFunction(rt, animationSettings);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
CSSAnimationSettingsMap parseNewAnimationSettings(
|
|
jsi::Runtime &rt,
|
|
const std::vector<std::string> &animationNames,
|
|
const jsi::Value &newSettings) {
|
|
return parseHelper<CSSAnimationSettings>(
|
|
rt,
|
|
newSettings.asObject(rt),
|
|
[&](jsi::Runtime &rt, const jsi::Value &settings) {
|
|
return parseCSSAnimationSettings(rt, settings);
|
|
});
|
|
}
|
|
|
|
CSSAnimationSettingsUpdatesMap parseSettingsUpdates(
|
|
jsi::Runtime &rt,
|
|
const jsi::Value &settingsUpdates) {
|
|
return parseHelper<PartialCSSAnimationSettings>(
|
|
rt,
|
|
settingsUpdates.asObject(rt),
|
|
[](jsi::Runtime &rt, const jsi::Value &settings) {
|
|
return parsePartialCSSAnimationSettings(rt, settings);
|
|
});
|
|
}
|
|
|
|
CSSAnimationUpdates parseCSSAnimationUpdates(
|
|
jsi::Runtime &rt,
|
|
const jsi::Value &config) {
|
|
const auto &configObj = config.asObject(rt);
|
|
|
|
CSSAnimationUpdates result;
|
|
|
|
if (configObj.hasProperty(rt, "animationNames")) {
|
|
const auto animationNames =
|
|
parseAnimationNames(rt, configObj.getProperty(rt, "animationNames"));
|
|
result.animationNames = std::move(animationNames);
|
|
|
|
if (configObj.hasProperty(rt, "newAnimationSettings")) {
|
|
result.newAnimationSettings = parseNewAnimationSettings(
|
|
rt,
|
|
animationNames,
|
|
configObj.getProperty(rt, "newAnimationSettings"));
|
|
}
|
|
}
|
|
|
|
if (configObj.hasProperty(rt, "settingsUpdates")) {
|
|
result.settingsUpdates =
|
|
parseSettingsUpdates(rt, configObj.getProperty(rt, "settingsUpdates"));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
} // namespace reanimated::css
|