From 176efaf405e271514f71e2d855698e412afd8f97 Mon Sep 17 00:00:00 2001 From: Eric Rozell Date: Mon, 20 Dec 2021 12:25:53 -0500 Subject: [PATCH 1/2] Animate value property rather than offset In the RN Animated API, the offset value should not change unless explicitly set by the user (or extract offset / flatten offset is called on the value node). In the previous composition implementation for NativeAnimated, the offset property in the CompositionPropertySet was animated, meaning if the user specified an offset value, its initial value was assumed to be zero for the spring and decay drivers, and more problematically, the animation needed to implicitly flattened at the end of the animation. This change keeps a fixed offset during animations and instead animates the raw value. Fixes #9256 --- .../Modules/Animated/AnimationDriver.cpp | 5 ++--- .../Modules/Animated/CalculatedAnimationDriver.cpp | 6 +++--- .../Modules/Animated/FrameAnimationDriver.cpp | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/vnext/Microsoft.ReactNative/Modules/Animated/AnimationDriver.cpp b/vnext/Microsoft.ReactNative/Modules/Animated/AnimationDriver.cpp index e6a01fb1965..9caf25db30d 100644 --- a/vnext/Microsoft.ReactNative/Modules/Animated/AnimationDriver.cpp +++ b/vnext/Microsoft.ReactNative/Modules/Animated/AnimationDriver.cpp @@ -44,7 +44,7 @@ AnimationDriver::~AnimationDriver() { void AnimationDriver::StartAnimation() { const auto [animation, scopedBatch] = MakeAnimation(m_config); if (auto const animatedValue = GetAnimatedValue()) { - animatedValue->PropertySet().StartAnimation(ValueAnimatedNode::s_offsetName, animation); + animatedValue->PropertySet().StartAnimation(ValueAnimatedNode::s_valueName, animation); animatedValue->AddActiveAnimation(m_id); } scopedBatch.End(); @@ -58,7 +58,6 @@ void AnimationDriver::StartAnimation() { if (auto manager = weakManager.lock()) { if (auto const animatedValue = manager->GetValueAnimatedNode(tag)) { animatedValue->RemoveActiveAnimation(id); - animatedValue->FlattenOffset(); } manager->RemoveActiveAnimation(id); } @@ -70,7 +69,7 @@ void AnimationDriver::StartAnimation() { void AnimationDriver::StopAnimation(bool ignoreCompletedHandlers) { if (const auto animatedValue = GetAnimatedValue()) { - animatedValue->PropertySet().StopAnimation(ValueAnimatedNode::s_offsetName); + animatedValue->PropertySet().StopAnimation(ValueAnimatedNode::s_valueName); if (!ignoreCompletedHandlers) { animatedValue->RemoveActiveAnimation(m_id); diff --git a/vnext/Microsoft.ReactNative/Modules/Animated/CalculatedAnimationDriver.cpp b/vnext/Microsoft.ReactNative/Modules/Animated/CalculatedAnimationDriver.cpp index b0ff2041611..a675d96d567 100644 --- a/vnext/Microsoft.ReactNative/Modules/Animated/CalculatedAnimationDriver.cpp +++ b/vnext/Microsoft.ReactNative/Modules/Animated/CalculatedAnimationDriver.cpp @@ -37,11 +37,11 @@ std::tuple CalculatedA std::chrono::milliseconds duration(static_cast(keyFrames.size() / 60.0f * 1000.0f)); animation.Duration(duration); auto normalizedProgress = 0.0f; - // We are animating the values offset property which should start at 0. - animation.InsertKeyFrame(normalizedProgress, 0.0f, easingFunction); + auto fromValue = static_cast(GetAnimatedValue()->RawValue()); + animation.InsertKeyFrame(normalizedProgress, fromValue, easingFunction); for (const auto keyFrame : keyFrames) { normalizedProgress = std::min(normalizedProgress + 1.0f / keyFrames.size(), 1.0f); - animation.InsertKeyFrame(normalizedProgress, keyFrame - static_cast(m_startValue), easingFunction); + animation.InsertKeyFrame(normalizedProgress, keyFrame, easingFunction); } if (m_iterations == -1) { diff --git a/vnext/Microsoft.ReactNative/Modules/Animated/FrameAnimationDriver.cpp b/vnext/Microsoft.ReactNative/Modules/Animated/FrameAnimationDriver.cpp index 99664d19b54..8982b4c42e1 100644 --- a/vnext/Microsoft.ReactNative/Modules/Animated/FrameAnimationDriver.cpp +++ b/vnext/Microsoft.ReactNative/Modules/Animated/FrameAnimationDriver.cpp @@ -40,7 +40,7 @@ std::tuple FrameAnimat auto fromValue = GetAnimatedValue()->RawValue(); for (auto frame : m_frames) { normalizedProgress = std::min(normalizedProgress += step, 1.0f); - animation.InsertKeyFrame(normalizedProgress, static_cast(frame * (m_toValue - fromValue))); + animation.InsertKeyFrame(normalizedProgress, static_cast(fromValue + frame * (m_toValue - fromValue))); } if (m_iterations == -1) { From d0e7ee1aefee1fb618d5b69e6e012954424c8eaf Mon Sep 17 00:00:00 2001 From: Eric Rozell Date: Mon, 20 Dec 2021 12:49:10 -0500 Subject: [PATCH 2/2] Change files --- ...ative-windows-f6c9b8a9-e496-4be1-a2a5-ad3a4a9bece8.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/react-native-windows-f6c9b8a9-e496-4be1-a2a5-ad3a4a9bece8.json diff --git a/change/react-native-windows-f6c9b8a9-e496-4be1-a2a5-ad3a4a9bece8.json b/change/react-native-windows-f6c9b8a9-e496-4be1-a2a5-ad3a4a9bece8.json new file mode 100644 index 00000000000..8bbee6a4023 --- /dev/null +++ b/change/react-native-windows-f6c9b8a9-e496-4be1-a2a5-ad3a4a9bece8.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Animate value property rather than offset", + "packageName": "react-native-windows", + "email": "erozell@outlook.com", + "dependentChangeType": "patch" +}