summaryrefslogtreecommitdiffstats
path: root/cc/animation
diff options
context:
space:
mode:
authorloyso <loyso@chromium.org>2014-12-21 22:28:32 -0800
committerCommit bot <commit-bot@chromium.org>2014-12-22 06:29:21 +0000
commit515c5da5528c725f8a73584768dc6d1b22e5fbbc (patch)
treed235569823aad34ca5c2ed7ea8364ac3eeff762b /cc/animation
parentf52eda659eba356621fd01a78088fa243a59b51a (diff)
downloadchromium_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.cc95
-rw-r--r--cc/animation/timing_function.cc38
-rw-r--r--cc/animation/timing_function.h22
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_