diff options
author | loyso <loyso@chromium.org> | 2014-12-21 22:28:32 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-12-22 06:29:21 +0000 |
commit | 515c5da5528c725f8a73584768dc6d1b22e5fbbc (patch) | |
tree | d235569823aad34ca5c2ed7ea8364ac3eeff762b /cc/animation | |
parent | f52eda659eba356621fd01a78088fa243a59b51a (diff) | |
download | chromium_src-515c5da5528c725f8a73584768dc6d1b22e5fbbc.zip chromium_src-515c5da5528c725f8a73584768dc6d1b22e5fbbc.tar.gz chromium_src-515c5da5528c725f8a73584768dc6d1b22e5fbbc.tar.bz2 |
Define step timing function for the cc animation framework.
This is a chromium-side part.
BUG=441006
R=dstockwell@chromium.org
R=ajuma@chromium.org
TEST=ManualTests/animation/compositor-animation-steps.html
Review URL: https://codereview.chromium.org/809523004
Cr-Commit-Position: refs/heads/master@{#309399}
Diffstat (limited to 'cc/animation')
-rw-r--r-- | cc/animation/keyframed_animation_curve_unittest.cc | 95 | ||||
-rw-r--r-- | cc/animation/timing_function.cc | 38 | ||||
-rw-r--r-- | cc/animation/timing_function.h | 22 |
3 files changed, 155 insertions, 0 deletions
diff --git a/cc/animation/keyframed_animation_curve_unittest.cc b/cc/animation/keyframed_animation_curve_unittest.cc index 314ce9d..0fd8da9 100644 --- a/cc/animation/keyframed_animation_curve_unittest.cc +++ b/cc/animation/keyframed_animation_curve_unittest.cc @@ -440,6 +440,101 @@ TEST(KeyframedAnimationCurveTest, CubicBezierTimingFunction) { EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); } +// Tests a step timing function if the change of values occur at the start. +TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtStart) { + scoped_ptr<KeyframedFloatAnimationCurve> curve( + KeyframedFloatAnimationCurve::Create()); + const int num_steps = 36; + const float steps_start_offset = 1.0f; + curve->AddKeyframe(FloatKeyframe::Create( + base::TimeDelta(), 0.f, + StepsTimingFunction::Create(num_steps, steps_start_offset))); + curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), + num_steps, nullptr)); + + const float time_threshold = 0.0001f; + + for (float i = 0.f; i < num_steps; i += 1.f) { + const base::TimeDelta time1 = + base::TimeDelta::FromSecondsD(i / num_steps - time_threshold); + const base::TimeDelta time2 = + base::TimeDelta::FromSecondsD(i / num_steps + time_threshold); + EXPECT_FLOAT_EQ(std::ceil(i), curve->GetValue(time1)); + EXPECT_FLOAT_EQ(std::ceil(i) + 1.f, curve->GetValue(time2)); + } + EXPECT_FLOAT_EQ(num_steps, + curve->GetValue(base::TimeDelta::FromSecondsD(1.0))); + + for (float i = 0.5f; i <= num_steps; i += 1.0f) { + const base::TimeDelta time = base::TimeDelta::FromSecondsD(i / num_steps); + EXPECT_FLOAT_EQ(std::ceil(i), curve->GetValue(time)); + } +} + +// Tests a step timing function if the change of values occur at the middle. +TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtMiddle) { + scoped_ptr<KeyframedFloatAnimationCurve> curve( + KeyframedFloatAnimationCurve::Create()); + const int num_steps = 36; + const float steps_start_offset = 0.5f; + curve->AddKeyframe(FloatKeyframe::Create( + base::TimeDelta(), 0.f, + StepsTimingFunction::Create(num_steps, steps_start_offset))); + curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), + num_steps, nullptr)); + + const float time_threshold = 0.0001f; + + EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta())); + for (float i = 0.5f; i < num_steps; i += 1.f) { + const base::TimeDelta time1 = + base::TimeDelta::FromSecondsD(i / num_steps - time_threshold); + const base::TimeDelta time2 = + base::TimeDelta::FromSecondsD(i / num_steps + time_threshold); + EXPECT_FLOAT_EQ(std::floor(i), curve->GetValue(time1)); + EXPECT_FLOAT_EQ(std::floor(i) + 1.f, curve->GetValue(time2)); + } + EXPECT_FLOAT_EQ(num_steps, + curve->GetValue(base::TimeDelta::FromSecondsD(1.0))); + + for (float i = 0.25f; i <= num_steps; i += 1.0f) { + const base::TimeDelta time = base::TimeDelta::FromSecondsD(i / num_steps); + EXPECT_FLOAT_EQ(std::floor(i), curve->GetValue(time)); + } +} + +// Tests a step timing function if the change of values occur at the end. +TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtEnd) { + scoped_ptr<KeyframedFloatAnimationCurve> curve( + KeyframedFloatAnimationCurve::Create()); + const int num_steps = 36; + const float steps_start_offset = 0.0f; + curve->AddKeyframe(FloatKeyframe::Create( + base::TimeDelta(), 0.f, + StepsTimingFunction::Create(num_steps, steps_start_offset))); + curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), + num_steps, nullptr)); + + const float time_threshold = 0.0001f; + + EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta())); + for (float i = 1.f; i <= num_steps; i += 1.f) { + const base::TimeDelta time1 = + base::TimeDelta::FromSecondsD(i / num_steps - time_threshold); + const base::TimeDelta time2 = + base::TimeDelta::FromSecondsD(i / num_steps + time_threshold); + EXPECT_FLOAT_EQ(std::floor(i) - 1.f, curve->GetValue(time1)); + EXPECT_FLOAT_EQ(std::floor(i), curve->GetValue(time2)); + } + EXPECT_FLOAT_EQ(num_steps, + curve->GetValue(base::TimeDelta::FromSecondsD(1.0))); + + for (float i = 0.5f; i <= num_steps; i += 1.0f) { + const base::TimeDelta time = base::TimeDelta::FromSecondsD(i / num_steps); + EXPECT_FLOAT_EQ(std::floor(i), curve->GetValue(time)); + } +} + // Tests that animated bounds are computed as expected. TEST(KeyframedAnimationCurveTest, AnimatedBounds) { scoped_ptr<KeyframedTransformAnimationCurve> curve( diff --git a/cc/animation/timing_function.cc b/cc/animation/timing_function.cc index 2531cc6..94bf128 100644 --- a/cc/animation/timing_function.cc +++ b/cc/animation/timing_function.cc @@ -5,6 +5,7 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "cc/animation/timing_function.h" +#include "cc/base/math_util.h" namespace cc { @@ -63,4 +64,41 @@ scoped_ptr<TimingFunction> EaseInOutTimingFunction::Create() { return CubicBezierTimingFunction::Create(0.42, 0.0, 0.58, 1); } +scoped_ptr<StepsTimingFunction> StepsTimingFunction::Create( + int steps, + float steps_start_offset) { + return make_scoped_ptr(new StepsTimingFunction(steps, steps_start_offset)); +} + +StepsTimingFunction::StepsTimingFunction(int steps, float steps_start_offset) + : steps_(steps), steps_start_offset_(steps_start_offset) { + // Restrict it to CSS presets: step_start, step_end and step_middle. + // See the Web Animations specification, 3.12.4. Timing in discrete steps. + DCHECK(steps_start_offset_ == 0 || steps_start_offset_ == 1 || + steps_start_offset_ == 0.5); +} + +StepsTimingFunction::~StepsTimingFunction() { +} + +float StepsTimingFunction::GetValue(double t) const { + const double steps = static_cast<double>(steps_); + const double value = MathUtil::ClampToRange( + std::floor((steps * t) + steps_start_offset_) / steps, 0.0, 1.0); + return static_cast<float>(value); +} + +scoped_ptr<TimingFunction> StepsTimingFunction::Clone() const { + return make_scoped_ptr(new StepsTimingFunction(*this)); +} + +void StepsTimingFunction::Range(float* min, float* max) const { + *min = 0.0f; + *max = 1.0f; +} + +float StepsTimingFunction::Velocity(double x) const { + return 0.0f; +} + } // namespace cc diff --git a/cc/animation/timing_function.h b/cc/animation/timing_function.h index 69d1cc9..95144a7 100644 --- a/cc/animation/timing_function.h +++ b/cc/animation/timing_function.h @@ -81,6 +81,28 @@ class CC_EXPORT EaseInOutTimingFunction { DISALLOW_IMPLICIT_CONSTRUCTORS(EaseInOutTimingFunction); }; +class CC_EXPORT StepsTimingFunction : public TimingFunction { + public: + static scoped_ptr<StepsTimingFunction> Create(int steps, + float steps_start_offset); + ~StepsTimingFunction() override; + + float GetValue(double t) const override; + scoped_ptr<TimingFunction> Clone() const override; + + void Range(float* min, float* max) const override; + float Velocity(double time) const override; + + protected: + StepsTimingFunction(int steps, float steps_start_offset); + + private: + int steps_; + float steps_start_offset_; + + DISALLOW_ASSIGN(StepsTimingFunction); +}; + } // namespace cc #endif // CC_ANIMATION_TIMING_FUNCTION_H_ |