From b562d7c9f043bac872e4853bd21ef771b2c22386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81opaci=C5=84ski?= Date: Fri, 7 Feb 2025 12:34:37 +0100 Subject: [PATCH] Some progress --- .../screens/testExamples/Playground.tsx | 2 - .../cpp/reanimated/CSS/core/CSSAnimation.cpp | 13 +++-- .../cpp/reanimated/CSS/core/CSSAnimation.h | 6 +- .../cpp/reanimated/CSS/core/CSSTransition.cpp | 16 +++-- .../CSS/interpolation/PropertyInterpolator.h | 18 +----- .../groups/GroupPropertiesInterpolator.h | 3 - .../styles/TransitionStyleInterpolator.cpp | 58 +++++++++---------- .../styles/TransitionStyleInterpolator.h | 7 ++- .../values/ResolvableValueInterpolator.h | 2 +- .../interpolation/values/ValueInterpolator.h | 49 +++++----------- .../src/css/models/CSSKeyframesRuleBase.ts | 4 -- 11 files changed, 70 insertions(+), 108 deletions(-) diff --git a/apps/common-app/src/apps/css/examples/animations/screens/testExamples/Playground.tsx b/apps/common-app/src/apps/css/examples/animations/screens/testExamples/Playground.tsx index 12b74153b4e..ddd6390736a 100644 --- a/apps/common-app/src/apps/css/examples/animations/screens/testExamples/Playground.tsx +++ b/apps/common-app/src/apps/css/examples/animations/screens/testExamples/Playground.tsx @@ -13,8 +13,6 @@ import { flex } from '@/theme'; const AnimatedView = createAnimatedComponent(View); export default function Playground() { - console.log(`animation: ${styles.child.animationName[0]} 1s ease`); - return ( Hello world! diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/CSSAnimation.cpp b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/CSSAnimation.cpp index 0d2865d84a3..4ba9edb4a23 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/CSSAnimation.cpp +++ b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/CSSAnimation.cpp @@ -69,21 +69,22 @@ jsi::Value CSSAnimation::getViewStyle(jsi::Runtime &rt) const { } jsi::Value CSSAnimation::getCurrentInterpolationStyle(jsi::Runtime &rt) const { - return styleInterpolator_.getCurrentInterpolationStyle(rt, shadowNode_); + return styleInterpolator_.interpolate(rt, shadowNode_, progressProvider_); } -jsi::Value CSSAnimation::getBackwardsFillStyle(jsi::Runtime &rt) { +jsi::Value CSSAnimation::getBackwardsFillStyle(jsi::Runtime &rt) const { return isReversed() ? styleInterpolator_.getLastKeyframeValue(rt) : styleInterpolator_.getFirstKeyframeValue(rt); } -jsi::Value CSSAnimation::getForwardFillStyle(jsi::Runtime &rt) { +jsi::Value CSSAnimation::getForwardFillStyle(jsi::Runtime &rt) const { return isReversed() ? styleInterpolator_.getFirstKeyframeValue(rt) : styleInterpolator_.getLastKeyframeValue(rt); } -jsi::Value CSSAnimation::resetStyle(jsi::Runtime &rt) { - return styleInterpolator_.reset(rt, shadowNode_); +jsi::Value CSSAnimation::getResetStyle(jsi::Runtime &rt) const { + // TODO + return jsi::Value::undefined(); } void CSSAnimation::run(const double timestamp) { @@ -107,7 +108,7 @@ jsi::Value CSSAnimation::update(jsi::Runtime &rt, const double timestamp) { : jsi::Value::undefined(); } - return styleInterpolator_.update(rt, shadowNode_); + return styleInterpolator_.interpolate(rt, shadowNode_, progressProvider_); } void CSSAnimation::updateSettings( diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/CSSAnimation.h b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/CSSAnimation.h index 1510c833ec7..108066cd099 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/CSSAnimation.h +++ b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/CSSAnimation.h @@ -37,9 +37,9 @@ class CSSAnimation { jsi::Value getViewStyle(jsi::Runtime &rt) const; jsi::Value getCurrentInterpolationStyle(jsi::Runtime &rt) const; - jsi::Value getBackwardsFillStyle(jsi::Runtime &rt); - jsi::Value getForwardFillStyle(jsi::Runtime &rt); - jsi::Value resetStyle(jsi::Runtime &rt); + jsi::Value getBackwardsFillStyle(jsi::Runtime &rt) const; + jsi::Value getForwardFillStyle(jsi::Runtime &rt) const; + jsi::Value getResetStyle(jsi::Runtime &rt) const; void run(double timestamp); jsi::Value update(jsi::Runtime &rt, double timestamp); diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/CSSTransition.cpp b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/CSSTransition.cpp index 2c21de802ff..90f0d59f512 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/CSSTransition.cpp +++ b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/CSSTransition.cpp @@ -31,7 +31,8 @@ TransitionProgressState CSSTransition::getState() const { } jsi::Value CSSTransition::getCurrentInterpolationStyle(jsi::Runtime &rt) const { - return styleInterpolator_.getCurrentInterpolationStyle(rt, shadowNode_); + return styleInterpolator_.getCurrentInterpolationStyle( + rt, shadowNode_, progressProvider_); } PropertyNames CSSTransition::getAllowedProperties( @@ -98,15 +99,22 @@ jsi::Value CSSTransition::run( changedProps.changedPropertyNames, styleInterpolator_.getReversedPropertyNames(rt, changedProps.newProps)); styleInterpolator_.updateInterpolatedProperties( - rt, changedProps, progressProvider_.getPropertyProgressProviders()); + rt, + changedProps, + jsi::Value::undefined(), // TODO + jsi::Value::undefined()); // TODO return update(rt, timestamp); } jsi::Value CSSTransition::update(jsi::Runtime &rt, const double timestamp) { progressProvider_.update(timestamp); - return styleInterpolator_.update( - rt, shadowNode_, progressProvider_.getRemovedProperties()); + const auto result = + styleInterpolator_.interpolate(rt, shadowNode_, progressProvider_); + // Remove interpolators for which interpolation has finished + // (we won't need them anymore in the current transition) + styleInterpolator_.discardFinishedInterpolators(progressProvider_); + return result; } void CSSTransition::updateTransitionProperties( diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/PropertyInterpolator.h b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/PropertyInterpolator.h index c99c8ecf420..579fc348219 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/PropertyInterpolator.h +++ b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/PropertyInterpolator.h @@ -17,22 +17,14 @@ class PropertyInterpolator { public: explicit PropertyInterpolator( const PropertyPath &propertyPath, - const std::shared_ptr &progressProvider, const std::shared_ptr &viewStylesRepository); - virtual void setProgressProvider( - const std::shared_ptr &progressProvider); - virtual jsi::Value getStyleValue( jsi::Runtime &rt, const ShadowNode::Shared &shadowNode) const = 0; virtual jsi::Value getFirstKeyframeValue(jsi::Runtime &rt) const = 0; virtual jsi::Value getLastKeyframeValue(jsi::Runtime &rt) const = 0; - virtual bool equalsReversingAdjustedStartValue( - jsi::Runtime &rt, - const jsi::Value &propertyValue) const = 0; - virtual void updateKeyframes( jsi::Runtime &rt, const jsi::Value &keyframes) = 0; @@ -43,17 +35,14 @@ class PropertyInterpolator { const jsi::Value &previousValue, const jsi::Value &reversingAdjustedStartValue) = 0; - virtual jsi::Value update( - jsi::Runtime &rt, - const ShadowNode::Shared &shadowNode) = 0; - virtual jsi::Value reset( + virtual jsi::Value interpolate( jsi::Runtime &rt, - const ShadowNode::Shared &shadowNode) = 0; + const ShadowNode::Shared &shadowNode, + const std::shared_ptr &progressProvider) = 0; protected: const PropertyPath propertyPath_; const std::shared_ptr viewStylesRepository_; - std::shared_ptr progressProvider_; }; class PropertyInterpolatorFactory { @@ -66,7 +55,6 @@ class PropertyInterpolatorFactory { virtual std::shared_ptr create( const PropertyPath &propertyPath, - const std::shared_ptr &progressProvider, const std::shared_ptr &viewStylesRepository) const = 0; }; diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/groups/GroupPropertiesInterpolator.h b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/groups/GroupPropertiesInterpolator.h index 134beb6d5f4..cd6855d3f51 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/groups/GroupPropertiesInterpolator.h +++ b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/groups/GroupPropertiesInterpolator.h @@ -22,9 +22,6 @@ class GroupPropertiesInterpolator : public PropertyInterpolator { jsi::Value getStyleValue( jsi::Runtime &rt, const ShadowNode::Shared &shadowNode) const override; - jsi::Value getCurrentValue( - jsi::Runtime &rt, - const ShadowNode::Shared &shadowNode) const override; jsi::Value getFirstKeyframeValue(jsi::Runtime &rt) const override; jsi::Value getLastKeyframeValue(jsi::Runtime &rt) const override; diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/styles/TransitionStyleInterpolator.cpp b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/styles/TransitionStyleInterpolator.cpp index 5ecc181a7ad..23fc6244d38 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/styles/TransitionStyleInterpolator.cpp +++ b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/styles/TransitionStyleInterpolator.cpp @@ -9,11 +9,14 @@ TransitionStyleInterpolator::TransitionStyleInterpolator( jsi::Value TransitionStyleInterpolator::getCurrentInterpolationStyle( jsi::Runtime &rt, - const ShadowNode::Shared &shadowNode) const { + const ShadowNode::Shared &shadowNode, + const TransitionProgressProvider &progressProvider) const { jsi::Object result(rt); - for (const auto &[propertyName, interpolator] : interpolators_) { - jsi::Value value = interpolator->getCurrentValue(rt, shadowNode); + for (const auto &[propertyName, progressProvider] : progressProviders_) { + const auto interpolator = interpolators_.at(propertyName); + const auto value = + interpolator->interpolate(rt, shadowNode, progressProvider); result.setProperty(rt, propertyName.c_str(), value); } @@ -46,32 +49,34 @@ TransitionStyleInterpolator::getReversedPropertyNames( return reversedProperties; } -jsi::Value TransitionStyleInterpolator::update( +jsi::Value TransitionStyleInterpolator::interpolate( jsi::Runtime &rt, const ShadowNode::Shared &shadowNode, - const std::unordered_set &propertiesToRemove) { + const TransitionProgressProvider &transitionProgressProvider) const { if (interpolators_.empty()) { return jsi::Value::undefined(); } jsi::Object result(rt); - for (auto it = interpolators_.begin(); it != interpolators_.end();) { - const auto &[propertyName, interpolator] = *it; - - jsi::Value value = interpolator->update(rt, shadowNode); + for (const auto &[propertyName, progressProvider] : + transitionProgressProvider.getPropertyProgressProviders()) { + const auto interpolator = interpolators_.at(propertyName); + const auto value = + interpolator->interpolate(rt, shadowNode, progressProvider); result.setProperty(rt, propertyName.c_str(), value); - - if (propertiesToRemove.find(propertyName) != propertiesToRemove.cend()) { - it = interpolators_.erase(it); - } else { - ++it; - } } return result; } +void TransitionStyleInterpolator::discardFinishedInterpolators( + const TransitionProgressProvider &progressProvider) { + for (const auto propertyName : progressProvider.getRemovedProperties()) { + interpolators_.erase(propertyName); + } +} + void TransitionStyleInterpolator::discardIrrelevantInterpolators( const std::unordered_set &transitionPropertyNames) { for (auto it = interpolators_.begin(); it != interpolators_.end();) { @@ -88,37 +93,28 @@ void TransitionStyleInterpolator::discardIrrelevantInterpolators( void TransitionStyleInterpolator::updateInterpolatedProperties( jsi::Runtime &rt, - const jsi::Value &oldStyleValue, - const jsi::Value &newStyleValue, - const jsi::Value &previousValue, - const jsi::Value &reversingAdjustedStartValue) { + const ChangedProps &changedProps, + const jsi::Value &previousValue, // TODO + const jsi::Value &reversingAdjustedStartValue /* TODO */) { const auto oldPropsObj = changedProps.oldProps.asObject(rt); const auto newPropsObj = changedProps.newProps.asObject(rt); for (const auto &propertyName : changedProps.changedPropertyNames) { - auto interpolatorIt = interpolators_.find(propertyName); + auto it = interpolators_.find(propertyName); const auto oldValue = oldPropsObj.getProperty(rt, propertyName.c_str()); const auto newValue = newPropsObj.getProperty(rt, propertyName.c_str()); - if (interpolatorIt == interpolators_.end()) { + if (it == interpolators_.end()) { const auto newInterpolator = createPropertyInterpolator( propertyName, {}, PROPERTY_INTERPOLATORS_CONFIG, - progressProviders.at(propertyName), viewStylesRepository_); - interpolatorIt = - interpolators_.emplace(propertyName, newInterpolator).first; - } else { - // We have to set the new progress provider when the new transition - // starts and the interpolator already exists, because the new property - // progress provider was created on the new transition start. - interpolatorIt->second->setProgressProvider( - progressProviders.at(propertyName)); + it = interpolators_.emplace(propertyName, newInterpolator).first; } - interpolatorIt->second->updateKeyframesFromStyleChange( + it->second->updateKeyframesFromStyleChange( rt, oldValue, newValue, previousValue, reversingAdjustedStartValue); } } diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/styles/TransitionStyleInterpolator.h b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/styles/TransitionStyleInterpolator.h index f379273ca1e..7e97c414779 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/styles/TransitionStyleInterpolator.h +++ b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/styles/TransitionStyleInterpolator.h @@ -20,15 +20,16 @@ class TransitionStyleInterpolator { jsi::Value getCurrentInterpolationStyle( jsi::Runtime &rt, - const ShadowNode::Shared &shadowNode) const; + const ShadowNode::Shared &shadowNode, + const TransitionProgressProvider &progressProvider) const; std::unordered_set getReversedPropertyNames( jsi::Runtime &rt, const jsi::Value &newPropertyValues) const; - jsi::Value update( + jsi::Value interpolate( jsi::Runtime &rt, const ShadowNode::Shared &shadowNode, - const std::unordered_set &propertiesToRemove); + const TransitionProgressProvider &progressProvider) const; void discardIrrelevantInterpolators( const std::unordered_set &transitionPropertyNames); diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/values/ResolvableValueInterpolator.h b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/values/ResolvableValueInterpolator.h index a0d4b8e483a..2a733973ece 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/values/ResolvableValueInterpolator.h +++ b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/values/ResolvableValueInterpolator.h @@ -32,7 +32,7 @@ class ResolvableValueInterpolator : public ValueInterpolator { virtual ~ResolvableValueInterpolator() = default; protected: - ValueType interpolate( + ValueType interpolateValue( double progress, const ValueType &fromValue, const ValueType &toValue, diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/values/ValueInterpolator.h b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/values/ValueInterpolator.h index 898b4b0999e..b72edbe2989 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/values/ValueInterpolator.h +++ b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/interpolation/values/ValueInterpolator.h @@ -37,12 +37,8 @@ class ValueInterpolator : public PropertyInterpolator { explicit ValueInterpolator( const PropertyPath &propertyPath, const ValueType &defaultStyleValue, - const std::shared_ptr &progressProvider, const std::shared_ptr &viewStylesRepository) - : PropertyInterpolator( - propertyPath, - progressProvider, - viewStylesRepository), + : PropertyInterpolator(propertyPath, viewStylesRepository), defaultStyleValue_(defaultStyleValue) {} virtual ~ValueInterpolator() = default; @@ -84,6 +80,7 @@ class ValueInterpolator : public PropertyInterpolator { const jsi::Value &reversingAdjustedStartValue) override { KeyframeType firstKeyframe, lastKeyframe; + // TODO - check if this if (!previousValue.isUndefined()) { firstKeyframe = {0, ValueType(rt, previousValue)}; } else { @@ -99,9 +96,12 @@ class ValueInterpolator : public PropertyInterpolator { keyframes_ = {firstKeyframe, lastKeyframe}; } - jsi::Value update(jsi::Runtime &rt, const ShadowNode::Shared &shadowNode) + jsi::Value interpolate( + jsi::Runtime &rt, + const ShadowNode::Shared &shadowNode, + const std::shared_ptr &progressProvider) override { - const auto afterIndex = getKeyframeAfterIndex(); + const auto afterIndex = getKeyframeAfterIndex(progressProvider); const auto beforeIndex = afterIndex - 1; const auto &keyframeBefore = keyframes_.at(beforeIndex); @@ -126,7 +126,7 @@ class ValueInterpolator : public PropertyInterpolator { } else if (keyframeProgress == 0.0) { result = fromValue.value(); } else { - result = interpolate( + result = interpolateImpl( keyframeProgress, fromValue.value(), toValue.value(), @@ -139,7 +139,7 @@ class ValueInterpolator : public PropertyInterpolator { protected: ValueType defaultStyleValue_; - virtual ValueType interpolate( + virtual ValueType interpolateValue( double progress, const ValueType &fromValue, const ValueType &toValue, @@ -161,36 +161,13 @@ class ValueInterpolator : public PropertyInterpolator { ValueType resolveKeyframeValue( const ValueType &unresolvedValue, const ShadowNode::Shared &shadowNode) const { - return interpolate( + return interpolateValue( 0, unresolvedValue, unresolvedValue, {.node = shadowNode}); } - ValueKeyframe getKeyframeAtIndex( - jsi::Runtime &rt, - const ShadowNode::Shared &shadowNode, - size_t index, - bool shouldResolve) const { - const auto &keyframe = keyframes_.at(index); - - if (shouldResolve) { - const double offset = keyframe.offset; - std::optional unresolvedValue; - - if (keyframe.value.has_value()) { - unresolvedValue = keyframe.value.value(); - } else { - unresolvedValue = getFallbackValue(rt, shadowNode); - } - - return ValueKeyframe{ - offset, resolveKeyframeValue(unresolvedValue.value(), shadowNode)}; - } - - return keyframe; - } - - size_t getKeyframeAfterIndex() const { - const auto progress = progressProvider_->getGlobalProgress(); + size_t getKeyframeAfterIndex( + const std::shared_ptr &progressProvider) const { + const auto progress = progressProvider->getGlobalProgress(); const auto index = std::lower_bound( keyframes_.begin(), keyframes_.end(), diff --git a/packages/react-native-reanimated/src/css/models/CSSKeyframesRuleBase.ts b/packages/react-native-reanimated/src/css/models/CSSKeyframesRuleBase.ts index 306341dc2e0..38d95eb2b5a 100644 --- a/packages/react-native-reanimated/src/css/models/CSSKeyframesRuleBase.ts +++ b/packages/react-native-reanimated/src/css/models/CSSKeyframesRuleBase.ts @@ -39,10 +39,6 @@ export default abstract class CSSKeyframesRuleBase return this.name_; } - toString() { - return this.name_; - } - static generateNextKeyframeName() { return `REA-CSS-${currentAnimationID++}`; }