Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Unified Diff: third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp

Issue 2680923005: Refactor CSS Transitions to use CSSInterpolationTypes instead of AnimatableValues (Closed)
Patch Set: lint Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp
diff --git a/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp b/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp
index 39a15c6b8a3760c1ee1ebc041080462e0fe64027..24921c33e71c9c3d617ef3b262ad97ee2ff59766 100644
--- a/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp
+++ b/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp
@@ -30,16 +30,21 @@
#include "core/animation/css/CSSAnimations.h"
+#include <algorithm>
+#include <bitset>
#include "core/StylePropertyShorthand.h"
#include "core/animation/Animation.h"
+#include "core/animation/CSSInterpolationTypesMap.h"
#include "core/animation/CompositorAnimations.h"
#include "core/animation/DocumentTimeline.h"
#include "core/animation/ElementAnimations.h"
#include "core/animation/InertEffect.h"
#include "core/animation/Interpolation.h"
+#include "core/animation/InterpolationEnvironment.h"
+#include "core/animation/InterpolationType.h"
#include "core/animation/KeyframeEffectModel.h"
#include "core/animation/KeyframeEffectReadOnly.h"
-#include "core/animation/LegacyStyleInterpolation.h"
+#include "core/animation/TransitionInterpolation.h"
#include "core/animation/css/CSSAnimatableValueFactory.h"
#include "core/css/CSSKeyframeRule.h"
#include "core/css/CSSPropertyEquality.h"
@@ -59,8 +64,6 @@
#include "platform/animation/TimingFunction.h"
#include "public/platform/Platform.h"
#include "wtf/HashSet.h"
-#include <algorithm>
-#include <bitset>
namespace blink {
@@ -554,16 +557,14 @@ void CSSAnimations::maybeApplyPendingUpdate(Element* element) {
: element->document().timeline().currentTimeInternal() -
oldStartTime;
- AnimatableValueKeyframeEffectModel* oldEffect =
- toAnimatableValueKeyframeEffectModel(inertAnimation->model());
+ TransitionKeyframeEffectModel* oldEffect =
+ toTransitionKeyframeEffectModel(inertAnimation->model());
const KeyframeVector& frames = oldEffect->getFrames();
- AnimatableValueKeyframeVector newFrames;
- newFrames.push_back(toAnimatableValueKeyframe(frames[0]->clone().get()));
- newFrames.push_back(toAnimatableValueKeyframe(frames[1]->clone().get()));
- newFrames.push_back(toAnimatableValueKeyframe(frames[2]->clone().get()));
- newFrames[0]->clearPropertyValue(id);
- newFrames[1]->clearPropertyValue(id);
+ TransitionKeyframeVector newFrames;
+ newFrames.push_back(toTransitionKeyframe(frames[0]->clone().get()));
+ newFrames.push_back(toTransitionKeyframe(frames[1]->clone().get()));
+ newFrames.push_back(toTransitionKeyframe(frames[2]->clone().get()));
InertEffect* inertAnimationForSampling = InertEffect::create(
oldAnimation->model(), oldAnimation->specifiedTiming(), false,
@@ -571,11 +572,15 @@ void CSSAnimations::maybeApplyPendingUpdate(Element* element) {
Vector<RefPtr<Interpolation>> sample;
inertAnimationForSampling->sample(sample);
if (sample.size() == 1) {
- newFrames[0]->setPropertyValue(
- id, toLegacyStyleInterpolation(sample.at(0).get())->currentValue());
- newFrames[1]->setPropertyValue(
- id, toLegacyStyleInterpolation(sample.at(0).get())->currentValue());
- model = AnimatableValueKeyframeEffectModel::create(newFrames);
+ const auto& transitionInterpolation =
+ toTransitionInterpolation(*sample.at(0));
+ newFrames[0]->setValue(transitionInterpolation.getInterpolatedValue());
+ newFrames[0]->setCompositorValue(
+ transitionInterpolation.getInterpolatedCompositorValue());
+ newFrames[1]->setValue(transitionInterpolation.getInterpolatedValue());
+ newFrames[1]->setCompositorValue(
+ transitionInterpolation.getInterpolatedCompositorValue());
+ model = TransitionKeyframeEffectModel::create(newFrames);
}
}
@@ -617,7 +622,7 @@ void CSSAnimations::calculateTransitionUpdateForProperty(
if (activeTransitionIter != activeTransitions->end()) {
const RunningTransition* runningTransition = &activeTransitionIter->value;
to = CSSAnimatableValueFactory::create(id, style);
- const AnimatableValue* activeTo = runningTransition->to;
+ const AnimatableValue* activeTo = runningTransition->to.get();
if (to->equals(activeTo))
return;
update.cancelTransition(id);
@@ -631,15 +636,45 @@ void CSSAnimations::calculateTransitionUpdateForProperty(
if (CSSPropertyEquality::propertiesEqual(id, oldStyle, style))
return;
+
if (!to)
to = CSSAnimatableValueFactory::create(id, style);
-
RefPtr<AnimatableValue> from =
CSSAnimatableValueFactory::create(id, oldStyle);
+
+ // TODO(alancutter): Support transitions on registered custom properties and
+ // give the map a PropertyRegistry.
+ CSSInterpolationTypesMap map(nullptr);
+ InterpolationEnvironment oldEnvironment(map, oldStyle);
+ InterpolationEnvironment newEnvironment(map, style);
+ InterpolationValue start = nullptr;
+ InterpolationValue end = nullptr;
+ const InterpolationType* transitionType = nullptr;
+ PropertyHandle property(id);
+ for (const auto& interpolationType : map.get(property)) {
+ start = interpolationType->maybeConvertUnderlyingValue(oldEnvironment);
+ if (!start) {
+ continue;
+ }
+ end = interpolationType->maybeConvertUnderlyingValue(newEnvironment);
+ if (!end) {
+ continue;
+ }
+ // Merge will only succeed if the two values are considered interpolable.
+ if (interpolationType->maybeMergeSingles(start.clone(), end.clone())) {
+ transitionType = interpolationType.get();
+ break;
+ }
+ }
+
+ // No smooth interpolation exists between these values so don't start a
+ // transition.
+ if (!transitionType) {
+ return;
+ }
+
// If we have multiple transitions on the same property, we will use the
// last one since we iterate over them in order.
- if (AnimatableValue::usesDefaultInterpolation(to.get(), from.get()))
- return;
Timing timing = transitionData.convertToTiming(transitionIndex);
if (timing.startDelay + timing.iterationDuration <= 0)
@@ -653,8 +688,7 @@ void CSSAnimations::calculateTransitionUpdateForProperty(
if (!std::isnan(interruptedProgress)) {
// const_cast because we need to take a ref later when passing to
suzyh_UTC10 (ex-contributor) 2017/02/17 00:34:19 Comment obsolete?
alancutter (OOO until 2018) 2017/02/17 00:54:57 Removed, thanks for catch.
// startTransition.
- reversingAdjustedStartValue =
- const_cast<AnimatableValue*>(interruptedTransition->to);
+ reversingAdjustedStartValue = interruptedTransition->to.get();
reversingShorteningFactor =
clampTo((interruptedProgress *
interruptedTransition->reversingShorteningFactor) +
@@ -667,7 +701,7 @@ void CSSAnimations::calculateTransitionUpdateForProperty(
}
}
- AnimatableValueKeyframeVector keyframes;
+ TransitionKeyframeVector keyframes;
double startKeyframeOffset = 0;
if (timing.startDelay > 0) {
@@ -676,28 +710,39 @@ void CSSAnimations::calculateTransitionUpdateForProperty(
timing.startDelay = 0;
}
- RefPtr<AnimatableValueKeyframe> delayKeyframe =
- AnimatableValueKeyframe::create();
- delayKeyframe->setPropertyValue(id, from.get());
+ RefPtr<TransitionKeyframe> delayKeyframe =
+ TransitionKeyframe::create(property);
+ delayKeyframe->setValue(TypedInterpolationValue::create(
+ *transitionType, start.interpolableValue->clone(),
+ start.nonInterpolableValue));
delayKeyframe->setOffset(0);
keyframes.push_back(delayKeyframe);
- RefPtr<AnimatableValueKeyframe> startKeyframe =
- AnimatableValueKeyframe::create();
- startKeyframe->setPropertyValue(id, from.get());
+ RefPtr<TransitionKeyframe> startKeyframe =
+ TransitionKeyframe::create(property);
+ startKeyframe->setValue(TypedInterpolationValue::create(
+ *transitionType, start.interpolableValue->clone(),
+ start.nonInterpolableValue));
startKeyframe->setOffset(startKeyframeOffset);
startKeyframe->setEasing(std::move(timing.timingFunction));
timing.timingFunction = LinearTimingFunction::shared();
keyframes.push_back(startKeyframe);
- RefPtr<AnimatableValueKeyframe> endKeyframe =
- AnimatableValueKeyframe::create();
- endKeyframe->setPropertyValue(id, to.get());
+ RefPtr<TransitionKeyframe> endKeyframe = TransitionKeyframe::create(property);
+ endKeyframe->setValue(TypedInterpolationValue::create(
+ *transitionType, end.interpolableValue->clone(),
+ end.nonInterpolableValue));
endKeyframe->setOffset(1);
keyframes.push_back(endKeyframe);
- AnimatableValueKeyframeEffectModel* model =
- AnimatableValueKeyframeEffectModel::create(keyframes);
+ if (CompositorAnimations::isCompositableProperty(id)) {
+ delayKeyframe->setCompositorValue(from);
+ startKeyframe->setCompositorValue(from);
+ endKeyframe->setCompositorValue(to);
+ }
+
+ TransitionKeyframeEffectModel* model =
+ TransitionKeyframeEffectModel::create(keyframes);
update.startTransition(id, from.get(), to.get(), reversingAdjustedStartValue,
reversingShorteningFactor,
*InertEffect::create(model, timing, false, 0));

Powered by Google App Engine
This is Rietveld 408576698