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: shergin Differential Revision: D21635473 fbshipit-source-id: 470f43fd24a6e80d8696ee2f2a09d9e693b7f280
This commit is contained in:
Родитель
3cbafcccba
Коммит
a799367baf
|
@ -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
|
Загрузка…
Ссылка в новой задаче