Skip to content
Draft
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,7 @@ namespace reanimated::css {

using namespace facebook;

using PropertyNames = std::vector<std::string>;
using PropertyPath = std::vector<std::string>;
/**
* If nullopt - all style properties can trigger transition
* If empty vector - no style property can trigger transition
* Otherwise - only specified style properties can trigger transition
*/
using TransitionProperties = std::optional<PropertyNames>;

using EasingFunction = std::function<double(double)>;
using ColorChannels = std::array<uint8_t, 4>;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,55 +1,89 @@
#include <reanimated/CSS/configs/CSSTransitionConfig.h>

#include <string>
#include <reanimated/CSS/configs/common.h>

namespace reanimated::css {

std::optional<CSSTransitionPropertySettings> getTransitionPropertySettings(
const CSSTransitionPropertiesSettings &propertiesSettings,
const std::string &propName) {
// Try to use property specific settings first
const auto &propIt = propertiesSettings.find(propName);
if (propIt != propertiesSettings.end()) {
return propIt->second;
}
// Fallback to "all" settings if no property specific settings are available
const auto &allIt = propertiesSettings.find("all");
if (allIt != propertiesSettings.end()) {
return allIt->second;
CSSTransitionPropertyUpdates parsePropertyUpdates(jsi::Runtime &rt, const jsi::Object &diffs) {
CSSTransitionPropertyUpdates result;
const auto propertyNames = diffs.getPropertyNames(rt);
const auto propertyCount = propertyNames.size(rt);

for (size_t i = 0; i < propertyCount; ++i) {
const auto propertyName = propertyNames.getValueAtIndex(rt, i).asString(rt).utf8(rt);
const auto diffValue = diffs.getProperty(rt, jsi::PropNameID::forUtf8(rt, propertyName));

if (diffValue.isNull()) {
result.emplace(propertyName, std::nullopt);
continue;
}

if (!diffValue.isObject()) {
continue;
}

const auto diffArray = diffValue.asObject(rt).asArray(rt);
if (diffArray.size(rt) != 2) {
continue;
}

result.emplace(
propertyName,
std::make_optional(std::make_pair(diffArray.getValueAtIndex(rt, 0), diffArray.getValueAtIndex(rt, 1))));
}
// Or return nullopt if no settings are available
return std::nullopt;

return result;
}

TransitionProperties getProperties(jsi::Runtime &rt, const jsi::Object &config) {
const auto transitionProperty = config.getProperty(rt, "properties");
PartialCSSTransitionPropertySettings parsePartialPropertySettings(jsi::Runtime &rt, const jsi::Object &settings) {
PartialCSSTransitionPropertySettings result;

if (transitionProperty.isObject()) {
PropertyNames properties;
if (settings.hasProperty(rt, "duration")) {
result.duration = getDuration(rt, settings);
}

const auto propertiesArray = transitionProperty.asObject(rt).asArray(rt);
const auto propertiesCount = propertiesArray.size(rt);
for (size_t i = 0; i < propertiesCount; ++i) {
properties.emplace_back(propertiesArray.getValueAtIndex(rt, i).asString(rt).utf8(rt));
}
if (settings.hasProperty(rt, "timingFunction")) {
result.easingFunction = getTimingFunction(rt, settings);
}

return properties;
if (settings.hasProperty(rt, "delay")) {
result.delay = getDelay(rt, settings);
}

return std::nullopt;
if (settings.hasProperty(rt, "allowDiscrete")) {
result.allowDiscrete = settings.getProperty(rt, "allowDiscrete").getBool();
}

return result;
}

bool getAllowDiscrete(jsi::Runtime &rt, const jsi::Object &config) {
return config.getProperty(rt, "allowDiscrete").asBool();
CSSTransitionPropertySettingsUpdates parseSettingsUpdates(jsi::Runtime &rt, const jsi::Object &settings) {
CSSTransitionPropertySettingsUpdates result;
const auto propertyNames = settings.getPropertyNames(rt);
const auto propertyCount = propertyNames.size(rt);

for (size_t i = 0; i < propertyCount; ++i) {
const auto propertyName = propertyNames.getValueAtIndex(rt, i).asString(rt).utf8(rt);
const auto propertyValue = settings.getProperty(rt, jsi::PropNameID::forUtf8(rt, propertyName));

if (!propertyValue.isObject()) {
continue;
}

const auto propertySettings = propertyValue.asObject(rt);
auto parsedSettings = parsePartialPropertySettings(rt, propertySettings);
result.emplace(propertyName, std::move(parsedSettings));
}

return result;
}

CSSTransitionPropertiesSettings parseCSSTransitionPropertiesSettings(jsi::Runtime &rt, const jsi::Object &settings) {
CSSTransitionPropertiesSettings parseSettings(jsi::Runtime &rt, const jsi::Object &settings) {
CSSTransitionPropertiesSettings result;

const auto propertyNames = settings.getPropertyNames(rt);
const auto propertiesCount = propertyNames.size(rt);
const auto propertyCount = propertyNames.size(rt);

for (size_t i = 0; i < propertiesCount; ++i) {
for (size_t i = 0; i < propertyCount; ++i) {
const auto propertyName = propertyNames.getValueAtIndex(rt, i).asString(rt).utf8(rt);
const auto propertySettings = settings.getProperty(rt, jsi::PropNameID::forUtf8(rt, propertyName)).asObject(rt);

Expand All @@ -59,29 +93,51 @@ CSSTransitionPropertiesSettings parseCSSTransitionPropertiesSettings(jsi::Runtim
getDuration(rt, propertySettings),
getTimingFunction(rt, propertySettings),
getDelay(rt, propertySettings),
getAllowDiscrete(rt, propertySettings)});
propertySettings.getProperty(rt, "allowDiscrete").asBool()});
}

return result;
}

std::optional<CSSTransitionPropertySettings> getTransitionPropertySettings(
const CSSTransitionPropertiesSettings &propertiesSettings,
const std::string &propName) {
const auto &propIt = propertiesSettings.find(propName);
if (propIt != propertiesSettings.end()) {
return propIt->second;
}

const auto &allIt = propertiesSettings.find("all");
if (allIt != propertiesSettings.end()) {
return allIt->second;
}

return std::nullopt;
}

CSSTransitionConfig parseCSSTransitionConfig(jsi::Runtime &rt, const jsi::Value &config) {
const auto configObj = config.asObject(rt);
return CSSTransitionConfig{
getProperties(rt, configObj),
parseCSSTransitionPropertiesSettings(rt, configObj.getProperty(rt, "settings").asObject(rt))};
}

PartialCSSTransitionConfig parsePartialCSSTransitionConfig(jsi::Runtime &rt, const jsi::Value &partialConfig) {
const auto partialObj = partialConfig.asObject(rt);
CSSTransitionConfig result{
.properties = parsePropertyUpdates(rt, configObj.getProperty(rt, "properties").asObject(rt)),
.settings = parseSettings(rt, configObj.getProperty(rt, "settings").asObject(rt)),
};

PartialCSSTransitionConfig result;
return result;
}

if (partialObj.hasProperty(rt, "properties")) {
result.properties = getProperties(rt, partialObj);
}
if (partialObj.hasProperty(rt, "settings")) {
result.settings = parseCSSTransitionPropertiesSettings(rt, partialObj.getProperty(rt, "settings").asObject(rt));
CSSTransitionUpdates parseCSSTransitionUpdates(jsi::Runtime &rt, const jsi::Value &updates) {
const auto updatesObj = updates.asObject(rt);
CSSTransitionUpdates result{
.properties = parsePropertyUpdates(rt, updatesObj.getProperty(rt, "properties").asObject(rt)),
};

if (updatesObj.hasProperty(rt, "settings")) {
const auto settingsValue = updatesObj.getProperty(rt, "settings");
auto settingsUpdates = parseSettingsUpdates(rt, settingsValue.asObject(rt));
if (!settingsUpdates.empty()) {
result.settings = std::move(settingsUpdates);
}
}

return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
#include <reanimated/CSS/configs/common.h>
#include <reanimated/CSS/easing/EasingFunctions.h>

#include <optional>
#include <string>
#include <unordered_map>
#include <utility>

namespace reanimated::css {

Expand All @@ -18,26 +20,32 @@ struct CSSTransitionPropertySettings {

using CSSTransitionPropertiesSettings = std::unordered_map<std::string, CSSTransitionPropertySettings>;

using CSSTransitionPropertyUpdates = std::unordered_map<std::string, std::optional<std::pair<jsi::Value, jsi::Value>>>;

struct CSSTransitionConfig {
TransitionProperties properties;
CSSTransitionPropertyUpdates properties;
CSSTransitionPropertiesSettings settings;
};

struct PartialCSSTransitionConfig {
std::optional<TransitionProperties> properties;
std::optional<CSSTransitionPropertiesSettings> settings;
struct PartialCSSTransitionPropertySettings {
std::optional<double> duration;
std::optional<EasingFunction> easingFunction;
std::optional<double> delay;
std::optional<bool> allowDiscrete;
};

using CSSTransitionPropertySettingsUpdates = std::unordered_map<std::string, PartialCSSTransitionPropertySettings>;

struct CSSTransitionUpdates {
CSSTransitionPropertyUpdates properties;
std::optional<CSSTransitionPropertySettingsUpdates> settings;
};

std::optional<CSSTransitionPropertySettings> getTransitionPropertySettings(
const CSSTransitionPropertiesSettings &propertiesSettings,
const std::string &propName);

TransitionProperties getProperties(jsi::Runtime &rt, const jsi::Object &config);

CSSTransitionPropertiesSettings parseCSSTransitionPropertiesSettings(jsi::Runtime &rt, const jsi::Object &settings);

CSSTransitionConfig parseCSSTransitionConfig(jsi::Runtime &rt, const jsi::Value &config);

PartialCSSTransitionConfig parsePartialCSSTransitionConfig(jsi::Runtime &rt, const jsi::Value &partialConfig);
CSSTransitionUpdates parseCSSTransitionUpdates(jsi::Runtime &rt, const jsi::Value &updates);

} // namespace reanimated::css
Loading
Loading