mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
LayoutAnimations: allow Paragraph props to be interpolated
Summary: 1. Split out the prop interpolation function out of the View ComponentDescriptor, into an inline'd function that can be used elsewhere. 2. Call it from View and from Paragraph component descriptors. This causes animations including Text to look normal on iOS. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D21675804 fbshipit-source-id: c34a317749fd6c108aef072d47f3dcb14ce8aa5c
This commit is contained in:
committed by
Facebook GitHub Bot
parent
3f9fad1052
commit
c75e8ae4ff
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "ParagraphShadowNode.h"
|
||||
|
||||
#include <react/components/view/ViewPropsInterpolation.h>
|
||||
#include <react/config/ReactNativeConfig.h>
|
||||
#include <react/core/ConcreteComponentDescriptor.h>
|
||||
#include <react/textlayoutmanager/TextLayoutManager.h>
|
||||
@@ -30,6 +31,18 @@ class ParagraphComponentDescriptor final
|
||||
textLayoutManager_ = std::make_shared<TextLayoutManager>(contextContainer_);
|
||||
}
|
||||
|
||||
virtual SharedProps interpolateProps(
|
||||
float animationProgress,
|
||||
const SharedProps &props,
|
||||
const SharedProps &newProps) const override {
|
||||
SharedProps interpolatedPropsShared = cloneProps(newProps, {});
|
||||
|
||||
interpolateViewProps(
|
||||
animationProgress, props, newProps, interpolatedPropsShared);
|
||||
|
||||
return interpolatedPropsShared;
|
||||
};
|
||||
|
||||
protected:
|
||||
void adopt(UnsharedShadowNode shadowNode) const override {
|
||||
ConcreteComponentDescriptor::adopt(shadowNode);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <react/components/view/ViewShadowNode.h>
|
||||
#include <react/core/ConcreteComponentDescriptor.h>
|
||||
#include "ViewProps.h"
|
||||
#include "ViewPropsInterpolation.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
@@ -24,34 +25,10 @@ class ViewComponentDescriptor
|
||||
float animationProgress,
|
||||
const SharedProps &props,
|
||||
const SharedProps &newProps) const override {
|
||||
ViewProps const *oldViewProps =
|
||||
dynamic_cast<ViewProps const *>(props.get());
|
||||
ViewProps const *newViewProps =
|
||||
dynamic_cast<ViewProps const *>(newProps.get());
|
||||
|
||||
SharedProps interpolatedPropsShared = cloneProps(newProps, {});
|
||||
ViewProps *interpolatedProps = const_cast<ViewProps *>(
|
||||
dynamic_cast<ViewProps const *>(interpolatedPropsShared.get()));
|
||||
|
||||
interpolatedProps->opacity = oldViewProps->opacity +
|
||||
(newViewProps->opacity - oldViewProps->opacity) * animationProgress;
|
||||
|
||||
interpolatedProps->transform = Transform::Interpolate(
|
||||
animationProgress, oldViewProps->transform, newViewProps->transform);
|
||||
|
||||
// Android uses RawProps, not props, to update props on the platform...
|
||||
// Since interpolated props don't interpolate at all using RawProps, we need
|
||||
// to "re-hydrate" raw props after interpolating. This is what actually gets
|
||||
// sent to the mounting layer. This is a temporary hack, only for platforms
|
||||
// that use RawProps/folly::dynamic instead of concrete props on the
|
||||
// mounting layer. Once we can remove this, we should change `rawProps` to
|
||||
// be const again.
|
||||
#ifdef ANDROID
|
||||
interpolatedProps->rawProps["opacity"] = interpolatedProps->opacity;
|
||||
|
||||
interpolatedProps->rawProps["transform"] =
|
||||
(folly::dynamic)interpolatedProps->transform;
|
||||
#endif
|
||||
interpolateViewProps(
|
||||
animationProgress, props, newProps, interpolatedPropsShared);
|
||||
|
||||
return interpolatedPropsShared;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 "ViewProps.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/**
|
||||
* Given animation progress, old props, new props, and an "interpolated" shared
|
||||
* props struct, this will mutate the "interpolated" struct in-place to give it
|
||||
* values interpolated between the old and new props.
|
||||
*/
|
||||
static inline void interpolateViewProps(
|
||||
Float animationProgress,
|
||||
const SharedProps &oldPropsShared,
|
||||
const SharedProps &newPropsShared,
|
||||
SharedProps &interpolatedPropsShared) {
|
||||
ViewProps const *oldViewProps =
|
||||
dynamic_cast<ViewProps const *>(oldPropsShared.get());
|
||||
ViewProps const *newViewProps =
|
||||
dynamic_cast<ViewProps const *>(newPropsShared.get());
|
||||
ViewProps *interpolatedProps = const_cast<ViewProps *>(
|
||||
dynamic_cast<ViewProps const *>(interpolatedPropsShared.get()));
|
||||
|
||||
assert(
|
||||
oldViewProps != nullptr && newViewProps != nullptr &&
|
||||
interpolatedProps != nullptr);
|
||||
|
||||
interpolatedProps->opacity = oldViewProps->opacity +
|
||||
(newViewProps->opacity - oldViewProps->opacity) * animationProgress;
|
||||
|
||||
interpolatedProps->transform = Transform::Interpolate(
|
||||
animationProgress, oldViewProps->transform, newViewProps->transform);
|
||||
|
||||
// Android uses RawProps, not props, to update props on the platform...
|
||||
// Since interpolated props don't interpolate at all using RawProps, we need
|
||||
// to "re-hydrate" raw props after interpolating. This is what actually gets
|
||||
// sent to the mounting layer. This is a temporary hack, only for platforms
|
||||
// that use RawProps/folly::dynamic instead of concrete props on the
|
||||
// mounting layer. Once we can remove this, we should change `rawProps` to
|
||||
// be const again.
|
||||
#ifdef ANDROID
|
||||
interpolatedProps->rawProps["opacity"] = interpolatedProps->opacity;
|
||||
|
||||
interpolatedProps->rawProps["transform"] =
|
||||
(folly::dynamic)interpolatedProps->transform;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
Reference in New Issue
Block a user