Chromium Code Reviews| Index: Source/core/platform/animation/TimingFunction.h |
| diff --git a/Source/core/platform/animation/TimingFunction.h b/Source/core/platform/animation/TimingFunction.h |
| index cc9db512250d142bee9dc3ac1c9370bed1915aef..606fe4c4df2c1e65cbcb3b4621a49e8431e7635c 100644 |
| --- a/Source/core/platform/animation/TimingFunction.h |
| +++ b/Source/core/platform/animation/TimingFunction.h |
| @@ -39,6 +39,8 @@ |
| namespace WebCore { |
| +class TimingFunction; |
| + |
| class TimingFunction : public RefCounted<TimingFunction> { |
| public: |
| @@ -54,6 +56,9 @@ public: |
| // accuracy and is not guaranteed. |
| virtual double evaluate(double fraction, double accuracy) const = 0; |
| virtual bool operator==(const TimingFunction& other) const = 0; |
| + virtual bool operator!=(const TimingFunction& other) const { return !operator==(other); } |
| + |
| + virtual PassRefPtr<TimingFunction> reverse() const = 0; |
|
Steve Block
2013/11/03 09:52:32
Can you add a comment describing exactly what you
|
| protected: |
| TimingFunction(Type type) |
| @@ -86,6 +91,11 @@ public: |
| return other.type() == LinearFunction; |
| } |
| + virtual PassRefPtr<TimingFunction> reverse() const |
| + { |
| + return const_cast<LinearTimingFunction*>(this); |
| + } |
| + |
| private: |
| LinearTimingFunction() |
| : TimingFunction(LinearFunction) |
| @@ -105,6 +115,20 @@ public: |
| static PassRefPtr<CubicBezierTimingFunction> create(double x1, double y1, double x2, double y2) |
| { |
| + // Prevent accidental creation of presets via this method (makes operator== easier too). |
| + if (x1 == 0.25 && y1 == 0.1 && x2 == 0.25 && y2 == 1.0) { |
| + return preset(Ease); |
| + } |
| + if (x1 == 0.42 && y1 == 0.0 && x2 == 1.0 && y2 == 1.0) { |
| + return preset(EaseIn); |
| + } |
| + if (x1 == 0.0 && y1 == 0.0 && x2 == 0.58 && y2 == 1.0) { |
| + return preset(EaseOut); |
| + } |
| + if (x1 == 0.42 && y1 == 0.0 && x2 == 0.58 && y2 == 1.0) { |
| + return preset(EaseInOut); |
| + } |
| + |
|
Steve Block
2013/11/03 09:52:32
This introduces a change in behavior for CSS. The
|
| return adoptRef(new CubicBezierTimingFunction(Custom, x1, y1, x2, y2)); |
| } |
| @@ -150,14 +174,14 @@ public: |
| virtual bool operator==(const TimingFunction& other) const |
| { |
| - if (other.type() == CubicBezierFunction) { |
| - const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(&other); |
| - if (m_subType != Custom) |
| - return m_subType == ctf->m_subType; |
| + if (other.type() != CubicBezierFunction) |
| + return false; |
|
Steve Block
2013/11/03 09:52:32
Why don't you test for 'this == &other' here, like
|
| + const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(&other); |
| + if (m_subType == Custom && ctf->m_subType == Custom) |
| return m_x1 == ctf->m_x1 && m_y1 == ctf->m_y1 && m_x2 == ctf->m_x2 && m_y2 == ctf->m_y2; |
| - } |
| - return false; |
| + |
| + return m_subType == ctf->m_subType; |
| } |
| double x1() const { return m_x1; } |
| @@ -167,6 +191,26 @@ public: |
| SubType subType() const { return m_subType; } |
| + virtual PassRefPtr<TimingFunction> reverse() const |
| + { |
| + switch (m_subType) { |
| + case Ease: |
| + return const_cast<CubicBezierTimingFunction*>(this); |
|
Steve Block
2013/11/03 09:52:32
This is incorrect. 'Ease' is not symmetric about x
|
| + case EaseIn: |
| + return preset(EaseOut); |
| + case EaseOut: |
| + return preset(EaseIn); |
| + case EaseInOut: |
| + return const_cast<CubicBezierTimingFunction*>(this); |
| + case Custom: |
| + // Flip the timing function in x. We also have to flip it in y to |
| + // maintain the invariant that it runs from (0, 0) to (1, 1). |
| + return create(1 - m_x2, 1 - m_y2, 1 - m_x1, 1 - m_y1); |
| + default: |
| + ASSERT_NOT_REACHED(); |
| + } |
| + } |
| + |
| private: |
| explicit CubicBezierTimingFunction(SubType subType, double x1, double y1, double x2, double y2) |
| : TimingFunction(CubicBezierFunction) |
| @@ -218,7 +262,6 @@ public: |
| } |
| } |
| - |
| ~StepsTimingFunction() { } |
| virtual double evaluate(double fraction, double) const |
| @@ -230,13 +273,16 @@ public: |
| virtual bool operator==(const TimingFunction& other) const |
| { |
| - if (other.type() == StepsFunction) { |
| - const StepsTimingFunction* stf = static_cast<const StepsTimingFunction*>(&other); |
| - if (m_subType != Custom) |
| - return m_subType == stf->m_subType; |
| - return m_steps == stf->m_steps && m_stepAtStart == stf->m_stepAtStart; |
| - } |
| - return false; |
| + if (other.type() != StepsFunction) |
| + return false; |
| + |
| + if (this == &other) |
| + return true; |
| + |
| + const StepsTimingFunction* stf = static_cast<const StepsTimingFunction*>(&other); |
| + if (m_subType != Custom) |
| + return m_subType == stf->m_subType; |
| + return m_steps == stf->m_steps && m_stepAtStart == stf->m_stepAtStart; |
| } |
| int numberOfSteps() const { return m_steps; } |
| @@ -244,6 +290,21 @@ public: |
| SubType subType() const { return m_subType; } |
| + virtual PassRefPtr<TimingFunction> reverse() const |
| + { |
| + switch (m_subType) { |
| + case Start: |
| + return preset(End); |
|
Steve Block
2013/11/03 09:52:32
If I'm right about how I think you intend to use r
Steve Block
2013/11/04 04:36:08
Sorry, should be ...
A step-start has output 1 for
Steve Block
2013/11/04 04:40:57
step-start has an output of 1 at input 0. See http
|
| + case End: |
| + return preset(Start); |
| + case Custom: |
| + return create(m_steps, !m_stepAtStart); |
| + default: |
| + ASSERT_NOT_REACHED(); |
| + return 0; |
| + } |
| + } |
| + |
| private: |
| StepsTimingFunction(SubType subType, int steps, bool stepAtStart) |
| : TimingFunction(StepsFunction) |
| @@ -271,6 +332,7 @@ public: |
| ASSERT(upperBound > max); |
| m_segments.append(Segment(max, upperBound, timingFunction)); |
| } |
| + |
| virtual double evaluate(double fraction, double accuracy) const |
| { |
| RELEASE_ASSERT_WITH_MESSAGE(fraction >= 0 && fraction <= 1, "Web Animations not yet implemented: Timing function behavior outside the range [0, 1] is not yet specified"); |
| @@ -286,9 +348,32 @@ public: |
| virtual bool operator==(const TimingFunction& other) const |
|
Steve Block
2013/11/03 09:52:32
What exactly do you need operator==() for? Current
|
| { |
| - // This class is not exposed to CSS, so this method is not required. |
| - ASSERT_NOT_REACHED(); |
| - return false; |
| + if (other.type() != ChainedFunction) |
| + return false; |
| + |
| + if (this == &other) |
| + return true; |
| + |
| + const ChainedTimingFunction* ctf = static_cast<const ChainedTimingFunction*>(&other); |
| + if (ctf->m_segments.size() != m_segments.size()) |
| + return false; |
| + |
| + for (size_t i = 0; i < m_segments.size(); i++) { |
| + if (m_segments[i] != ctf->m_segments[i]) |
| + return false; |
| + } |
| + return true; |
| + } |
| + |
| + virtual PassRefPtr<TimingFunction> reverse() const |
| + { |
| + RefPtr<ChainedTimingFunction> reversed = create(); |
| + for (size_t i = 0; i < m_segments.size(); i++) { |
| + size_t index = m_segments.size() - i - 1; |
| + |
| + reversed->appendSegment(1 - m_segments[index].m_min, m_segments[index].m_timingFunction->reverse().get()); |
| + } |
| + return reversed; |
| } |
| private: |
| @@ -306,6 +391,17 @@ private: |
| return scaleFromLocal(m_timingFunction->evaluate(scaleToLocal(fraction), accuracy)); |
| } |
| + bool operator==(const Segment& other) const |
| + { |
| + if (this == &other) |
| + return true; |
| + |
| + return m_min == other.m_min && m_max == other.m_max && m_timingFunction == other.m_timingFunction; |
| + } |
| + bool operator!=(const Segment& other) const |
| + { |
| + return !operator==(other); |
| + } |
| private: |
| double scaleToLocal(double x) const { return (x - m_min) / (m_max - m_min); } |
| double scaleFromLocal(double x) const { return blend(m_min, m_max, x); } |
| @@ -314,6 +410,8 @@ private: |
| double m_max; |
| RefPtr<TimingFunction> m_timingFunction; |
| + friend class ChainedTimingFunction; |
| + |
| // Allow printing of our segments. Can be removed once |
| // ChainedTimingFunction has a public API for segments. |
| friend void PrintTo(const ChainedTimingFunction&, ::std::ostream*, bool); |