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

Unified Diff: third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.cpp

Issue 1548873002: Port CSS visibility animations to CSSInterpolationTypes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added deferred interpolation comment Created 4 years, 11 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/CSSVisibilityInterpolationType.cpp
diff --git a/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dd897271643ab830bdb5c9d86e8202b0f1e0c723
--- /dev/null
+++ b/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.cpp
@@ -0,0 +1,177 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/animation/CSSVisibilityInterpolationType.h"
+
+#include "core/css/CSSPrimitiveValueMappings.h"
+#include "core/css/resolver/StyleResolverState.h"
+
+namespace blink {
+
+class CSSVisibilityNonInterpolableValue : public NonInterpolableValue {
+public:
+ ~CSSVisibilityNonInterpolableValue() final { }
+
+ static PassRefPtr<CSSVisibilityNonInterpolableValue> create(EVisibility start, EVisibility end)
+ {
+ return adoptRef(new CSSVisibilityNonInterpolableValue(start, end));
+ }
+
+ EVisibility visibility() const
+ {
+ ASSERT(m_isSingle);
+ return m_start;
+ }
+
+ EVisibility visibility(double fraction) const
+ {
+ if (m_isSingle || fraction <= 0)
+ return m_start;
+ if (fraction >= 1)
+ return m_end;
+ if (m_start == VISIBLE || m_end == VISIBLE)
+ return VISIBLE;
+ return fraction < 0.5 ? m_start : m_end;
+ }
+
+ DECLARE_NON_INTERPOLABLE_VALUE_TYPE();
+
+private:
+ CSSVisibilityNonInterpolableValue(EVisibility start, EVisibility end)
+ : m_start(start)
+ , m_end(end)
+ , m_isSingle(m_start == m_end)
+ { }
+
+ const EVisibility m_start;
+ const EVisibility m_end;
+ const bool m_isSingle;
+};
+
+DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSVisibilityNonInterpolableValue);
+DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSVisibilityNonInterpolableValue);
+
+class UnderlyingVisibilityChecker : public InterpolationType::ConversionChecker {
+public:
+ ~UnderlyingVisibilityChecker() final {}
+
+ static PassOwnPtr<UnderlyingVisibilityChecker> create(const InterpolationType& type, EVisibility visibility)
+ {
+ return adoptPtr(new UnderlyingVisibilityChecker(type, visibility));
+ }
+
+private:
+ UnderlyingVisibilityChecker(const InterpolationType& type, EVisibility visibility)
+ : ConversionChecker(type)
+ , m_visibility(visibility)
+ { }
+
+ bool isValid(const InterpolationEnvironment&, const UnderlyingValue& underlyingValue) const final
+ {
+ double underlyingFraction = toInterpolableNumber(underlyingValue->interpolableValue()).value();
+ EVisibility underlyingVisibility = toCSSVisibilityNonInterpolableValue(underlyingValue->nonInterpolableValue())->visibility(underlyingFraction);
+ return m_visibility == underlyingVisibility;
+ }
+
+ const EVisibility m_visibility;
+};
+
+class ParentVisibilityChecker : public InterpolationType::ConversionChecker {
+public:
+ static PassOwnPtr<ParentVisibilityChecker> create(const InterpolationType& type, EVisibility visibility)
+ {
+ return adoptPtr(new ParentVisibilityChecker(type, visibility));
+ }
+
+private:
+ ParentVisibilityChecker(const InterpolationType& type, EVisibility visibility)
+ : ConversionChecker(type)
+ , m_visibility(visibility)
+ { }
+
+ bool isValid(const InterpolationEnvironment& environment, const UnderlyingValue&) const final
+ {
+ return m_visibility == environment.state().parentStyle()->visibility();
+ }
+
+ DEFINE_INLINE_VIRTUAL_TRACE() { ConversionChecker::trace(visitor); }
+
+ const double m_visibility;
+};
+
+PassOwnPtr<InterpolationValue> CSSVisibilityInterpolationType::createVisibilityValue(EVisibility visibility) const
+{
+ return InterpolationValue::create(*this, InterpolableNumber::create(0), CSSVisibilityNonInterpolableValue::create(visibility, visibility));
+}
+
+PassOwnPtr<InterpolationValue> CSSVisibilityInterpolationType::maybeConvertNeutral(const UnderlyingValue& underlyingValue, ConversionCheckers& conversionCheckers) const
+{
+ double underlyingFraction = toInterpolableNumber(underlyingValue->interpolableValue()).value();
+ EVisibility underlyingVisibility = toCSSVisibilityNonInterpolableValue(underlyingValue->nonInterpolableValue())->visibility(underlyingFraction);
+ conversionCheckers.append(UnderlyingVisibilityChecker::create(*this, underlyingVisibility));
+ return createVisibilityValue(underlyingVisibility);
+}
+
+PassOwnPtr<InterpolationValue> CSSVisibilityInterpolationType::maybeConvertInitial() const
+{
+ return createVisibilityValue(VISIBLE);
+}
+
+PassOwnPtr<InterpolationValue> CSSVisibilityInterpolationType::maybeConvertInherit(const StyleResolverState& state, ConversionCheckers& conversionCheckers) const
+{
+ if (!state.parentStyle())
+ return nullptr;
+ EVisibility inheritedVisibility = state.parentStyle()->visibility();
+ conversionCheckers.append(ParentVisibilityChecker::create(*this, inheritedVisibility));
+ return createVisibilityValue(inheritedVisibility);
+}
+
+PassOwnPtr<InterpolationValue> CSSVisibilityInterpolationType::maybeConvertValue(const CSSValue& value, const StyleResolverState& state, ConversionCheckers& conversionCheckers) const
+{
+ if (!value.isPrimitiveValue())
+ return nullptr;
+
+ const CSSPrimitiveValue& primitiveValue = toCSSPrimitiveValue(value);
+ CSSValueID keyword = primitiveValue.getValueID();
+
+ switch (keyword) {
+ case CSSValueHidden:
+ case CSSValueVisible:
+ case CSSValueCollapse:
+ return createVisibilityValue(primitiveValue.convertTo<EVisibility>());
+ default:
+ return nullptr;
+ }
+}
+
+PassOwnPtr<InterpolationValue> CSSVisibilityInterpolationType::maybeConvertUnderlyingValue(const InterpolationEnvironment& environment) const
+{
+ return createVisibilityValue(environment.state().style()->visibility());
+}
+
+PassOwnPtr<PairwisePrimitiveInterpolation> CSSVisibilityInterpolationType::mergeSingleConversions(InterpolationValue& startValue, InterpolationValue& endValue) const
+{
+ return PairwisePrimitiveInterpolation::create(
+ *this,
+ InterpolableNumber::create(0),
+ InterpolableNumber::create(1),
+ CSSVisibilityNonInterpolableValue::create(
+ toCSSVisibilityNonInterpolableValue(startValue.nonInterpolableValue())->visibility(),
+ toCSSVisibilityNonInterpolableValue(endValue.nonInterpolableValue())->visibility()));
+}
+
+void CSSVisibilityInterpolationType::composite(UnderlyingValue& underlyingValue, double underlyingFraction, const InterpolationValue& value) const
+{
+ underlyingValue.set(&value);
+}
+
+void CSSVisibilityInterpolationType::apply(const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, InterpolationEnvironment& environment) const
+{
+ // Visibility interpolation has been deferred to application time here due to its non-linear behaviour.
+ double fraction = toInterpolableNumber(interpolableValue).value();
+ EVisibility visibility = toCSSVisibilityNonInterpolableValue(nonInterpolableValue)->visibility(fraction);
+ environment.state().style()->setVisibility(visibility);
+}
+
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698