diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | cc/animation/animation.cc | 46 | ||||
-rw-r--r-- | cc/animation/animation.h | 12 | ||||
-rw-r--r-- | cc/animation/animation_unittest.cc | 87 | ||||
-rw-r--r-- | webkit/renderer/compositor_bindings/web_animation_impl.cc | 39 | ||||
-rw-r--r-- | webkit/renderer/compositor_bindings/web_animation_impl.h | 5 | ||||
-rw-r--r-- | webkit/renderer/compositor_bindings/web_animation_unittest.cc | 12 |
7 files changed, 171 insertions, 31 deletions
@@ -35,6 +35,7 @@ Andrew Brampton <me@bramp.net> Andrew Tulloch <andrew@tullo.ch> Anish Patankar <anish.p@samsung.com> Antonio Gomes <a1.gomes@sisa.samsung.com> +Arnaud Renevier <a.renevier@samsung.com> Arthur Lussos <developer0420@gmail.com> Arun Mankuzhi <arun.m@samsung.com> Arunprasad Rajkumar <ararunprasad@gmail.com> diff --git a/cc/animation/animation.cc b/cc/animation/animation.cc index 1af35d2..be0e291 100644 --- a/cc/animation/animation.cc +++ b/cc/animation/animation.cc @@ -65,7 +65,7 @@ Animation::Animation(scoped_ptr<AnimationCurve> curve, run_state_(WaitingForTargetAvailability), iterations_(1), start_time_(0), - alternates_direction_(false), + direction_(Normal), time_offset_(0), needs_synchronized_start_time_(false), received_finished_event_(false), @@ -176,8 +176,8 @@ double Animation::TrimTimeToCurrentIteration(double monotonic_time) const { needs_synchronized_start_time()) trimmed = time_offset_; - // Zero is always the start of the animation. - if (trimmed <= 0) + // Return 0 if we are before the start of the animation + if (trimmed < 0) return 0; // Always return zero if we have no iterations. @@ -188,26 +188,32 @@ double Animation::TrimTimeToCurrentIteration(double monotonic_time) const { if (curve_->Duration() <= 0) return 0; - // If less than an iteration duration, just return trimmed. - if (trimmed < curve_->Duration()) - return trimmed; - - // If greater than or equal to the total duration, return iteration duration. - if (iterations_ >= 0 && trimmed >= curve_->Duration() * iterations_) { - if (alternates_direction_ && !(iterations_ % 2)) - return 0; - return curve_->Duration(); - } + // check if we are past active interval + bool is_past_total_duration = + (iterations_ > 0 && trimmed >= curve_->Duration() * iterations_); // We need to know the current iteration if we're alternating. - int iteration = static_cast<int>(trimmed / curve_->Duration()); + int iteration = 0; + + // If we are past the active interval, return iteration duration. + if (is_past_total_duration) { + iteration = iterations_; + trimmed = curve_->Duration(); + } else { + iteration = static_cast<int>(trimmed / curve_->Duration()); + // Calculate x where trimmed = x + n * curve_->Duration() for some positive + // integer n. + trimmed = fmod(trimmed, curve_->Duration()); + } - // Calculate x where trimmed = x + n * curve_->Duration() for some positive - // integer n. - trimmed = fmod(trimmed, curve_->Duration()); + // check if we are running the animation in reverse direction for the current + // iteration + bool reverse = (direction_ == Reverse) || + (direction_ == Alternate && iteration % 2 == 1) || + (direction_ == AlternateReverse && iteration % 2 == 0); - // If we're alternating and on an odd iteration, reverse the direction. - if (alternates_direction_ && iteration % 2 == 1) + // if we are running the animation in reverse direction, reverse the result + if (reverse) return curve_->Duration() - trimmed; return trimmed; @@ -223,7 +229,7 @@ scoped_ptr<Animation> Animation::CloneAndInitialize( to_return->pause_time_ = pause_time_; to_return->total_paused_time_ = total_paused_time_; to_return->time_offset_ = time_offset_; - to_return->alternates_direction_ = alternates_direction_; + to_return->direction_ = direction_; DCHECK(!to_return->is_controlling_instance_); to_return->is_controlling_instance_ = true; return to_return.Pass(); diff --git a/cc/animation/animation.h b/cc/animation/animation.h index ecc48b5..e4476ff 100644 --- a/cc/animation/animation.h +++ b/cc/animation/animation.h @@ -48,6 +48,8 @@ class CC_EXPORT Animation { TargetPropertyEnumSize }; + enum Direction { Normal, Reverse, Alternate, AlternateReverse }; + static scoped_ptr<Animation> Create(scoped_ptr<AnimationCurve> curve, int animation_id, int group_id, @@ -78,12 +80,8 @@ class CC_EXPORT Animation { void Suspend(double monotonic_time); void Resume(double monotonic_time); - // If alternates_direction is true, on odd numbered iterations we reverse the - // curve. - bool alternates_direction() const { return alternates_direction_; } - void set_alternates_direction(bool alternates) { - alternates_direction_ = alternates; - } + Direction direction() { return direction_; } + void set_direction(Direction direction) { direction_ = direction; } bool IsFinishedAt(double monotonic_time) const; bool is_finished() const { @@ -158,7 +156,7 @@ class CC_EXPORT Animation { RunState run_state_; int iterations_; double start_time_; - bool alternates_direction_; + Direction direction_; // The time offset effectively pushes the start of the animation back in time. // This is used for resuming paused animations -- an animation is added with a diff --git a/cc/animation/animation_unittest.cc b/cc/animation/animation_unittest.cc index 8223cee..7a9019d 100644 --- a/cc/animation/animation_unittest.cc +++ b/cc/animation/animation_unittest.cc @@ -49,15 +49,39 @@ TEST(AnimationTest, TrimTimeInfiniteIterations) { EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(1.5)); } -TEST(AnimationTest, TrimTimeAlternating) { +TEST(AnimationTest, TrimTimeReverse) { scoped_ptr<Animation> anim(CreateAnimation(-1)); - anim->set_alternates_direction(true); + anim->set_direction(Animation::Reverse); + EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0)); + EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(0.25)); + EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5)); + EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(0.75)); + EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(1.0)); + EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(1.25)); +} + +TEST(AnimationTest, TrimTimeAlternate) { + scoped_ptr<Animation> anim(CreateAnimation(-1)); + anim->set_direction(Animation::Alternate); EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(0.0)); + EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(0.25)); EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5)); + EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(0.75)); EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(1.0)); EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(1.25)); } +TEST(AnimationTest, TrimTimeAlternateReverse) { + scoped_ptr<Animation> anim(CreateAnimation(-1)); + anim->set_direction(Animation::AlternateReverse); + EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0.0)); + EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(0.25)); + EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5)); + EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(0.75)); + EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(1.0)); + EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(1.25)); +} + TEST(AnimationTest, TrimTimeStartTime) { scoped_ptr<Animation> anim(CreateAnimation(1)); anim->set_start_time(4); @@ -68,6 +92,17 @@ TEST(AnimationTest, TrimTimeStartTime) { EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(6.0)); } +TEST(AnimationTest, TrimTimeStartTimeReverse) { + scoped_ptr<Animation> anim(CreateAnimation(1)); + anim->set_start_time(4); + anim->set_direction(Animation::Reverse); + EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(0.0)); + EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(4.0)); + EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(4.5)); + EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(5.0)); + EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(6.0)); +} + TEST(AnimationTest, TrimTimeTimeOffset) { scoped_ptr<Animation> anim(CreateAnimation(1)); anim->set_time_offset(4); @@ -78,6 +113,17 @@ TEST(AnimationTest, TrimTimeTimeOffset) { EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(1.0)); } +TEST(AnimationTest, TrimTimeTimeOffsetReverse) { + scoped_ptr<Animation> anim(CreateAnimation(1)); + anim->set_time_offset(4); + anim->set_start_time(4); + anim->set_direction(Animation::Reverse); + EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0.0)); + EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5)); + EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(1.0)); + EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(1.0)); +} + TEST(AnimationTest, TrimTimeNegativeTimeOffset) { scoped_ptr<Animation> anim(CreateAnimation(1)); anim->set_time_offset(-4); @@ -88,6 +134,17 @@ TEST(AnimationTest, TrimTimeNegativeTimeOffset) { EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(5.0)); } +TEST(AnimationTest, TrimTimeNegativeTimeOffsetReverse) { + scoped_ptr<Animation> anim(CreateAnimation(1)); + anim->set_time_offset(-4); + anim->set_direction(Animation::Reverse); + + EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(0.0)); + EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(4.0)); + EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(4.5)); + EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(5.0)); +} + TEST(AnimationTest, TrimTimePauseResume) { scoped_ptr<Animation> anim(CreateAnimation(1)); anim->SetRunState(Animation::Running, 0.0); @@ -100,6 +157,19 @@ TEST(AnimationTest, TrimTimePauseResume) { EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(1024.5)); } +TEST(AnimationTest, TrimTimePauseResumeReverse) { + scoped_ptr<Animation> anim(CreateAnimation(1)); + anim->set_direction(Animation::Reverse); + anim->SetRunState(Animation::Running, 0.0); + EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0.0)); + EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5)); + anim->SetRunState(Animation::Paused, 0.25); + EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(1024.0)); + anim->SetRunState(Animation::Running, 1024.0); + EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(1024.0)); + EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(1024.75)); +} + TEST(AnimationTest, TrimTimeSuspendResume) { scoped_ptr<Animation> anim(CreateAnimation(1)); anim->SetRunState(Animation::Running, 0.0); @@ -112,6 +182,19 @@ TEST(AnimationTest, TrimTimeSuspendResume) { EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(1024.5)); } +TEST(AnimationTest, TrimTimeSuspendResumeReverse) { + scoped_ptr<Animation> anim(CreateAnimation(1)); + anim->set_direction(Animation::Reverse); + anim->SetRunState(Animation::Running, 0.0); + EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0.0)); + EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(0.25)); + anim->Suspend(0.75); + EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(1024.0)); + anim->Resume(1024); + EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(1024.0)); + EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(1024.25)); +} + TEST(AnimationTest, TrimTimeZeroDuration) { scoped_ptr<Animation> anim(CreateAnimation(0, 0)); anim->SetRunState(Animation::Running, 0.0); diff --git a/webkit/renderer/compositor_bindings/web_animation_impl.cc b/webkit/renderer/compositor_bindings/web_animation_impl.cc index c401d5c..d910acf 100644 --- a/webkit/renderer/compositor_bindings/web_animation_impl.cc +++ b/webkit/renderer/compositor_bindings/web_animation_impl.cc @@ -95,13 +95,48 @@ void WebAnimationImpl::setTimeOffset(double monotonic_time) { animation_->set_time_offset(monotonic_time); } +#if WEB_ANIMATION_SUPPORTS_FULL_DIRECTION +blink::WebAnimation::Direction WebAnimationImpl::direction() const { + switch (animation_->direction()) { + case cc::Animation::Normal: + return DirectionNormal; + case cc::Animation::Reverse: + return DirectionReverse; + case cc::Animation::Alternate: + return DirectionAlternate; + case cc::Animation::AlternateReverse: + return DirectionAlternateReverse; + default: + NOTREACHED(); + } + return DirectionNormal; +} + +void WebAnimationImpl::setDirection(Direction direction) { + switch (direction) { + case DirectionNormal: + animation_->set_direction(cc::Animation::Normal); + break; + case DirectionReverse: + animation_->set_direction(cc::Animation::Reverse); + break; + case DirectionAlternate: + animation_->set_direction(cc::Animation::Alternate); + break; + case DirectionAlternateReverse: + animation_->set_direction(cc::Animation::AlternateReverse); + break; + } +} +#else bool WebAnimationImpl::alternatesDirection() const { - return animation_->alternates_direction(); + return animation_->direction() == cc::Animation::Alternate; } void WebAnimationImpl::setAlternatesDirection(bool alternates) { - animation_->set_alternates_direction(alternates); + return animation_->set_direction(cc::Animation::Alternate); } +#endif scoped_ptr<cc::Animation> WebAnimationImpl::PassAnimation() { animation_->set_needs_synchronized_start_time(true); diff --git a/webkit/renderer/compositor_bindings/web_animation_impl.h b/webkit/renderer/compositor_bindings/web_animation_impl.h index 0c248fc..07d72c7 100644 --- a/webkit/renderer/compositor_bindings/web_animation_impl.h +++ b/webkit/renderer/compositor_bindings/web_animation_impl.h @@ -33,8 +33,13 @@ class WebAnimationImpl : public blink::WebAnimation { virtual void setStartTime(double monotonic_time); virtual double timeOffset() const; virtual void setTimeOffset(double monotonic_time); +#if WEB_ANIMATION_SUPPORTS_FULL_DIRECTION + virtual Direction direction() const; + virtual void setDirection(Direction); +#else virtual bool alternatesDirection() const; virtual void setAlternatesDirection(bool alternates); +#endif scoped_ptr<cc::Animation> PassAnimation(); diff --git a/webkit/renderer/compositor_bindings/web_animation_unittest.cc b/webkit/renderer/compositor_bindings/web_animation_unittest.cc index e5be25a..2b3e288 100644 --- a/webkit/renderer/compositor_bindings/web_animation_unittest.cc +++ b/webkit/renderer/compositor_bindings/web_animation_unittest.cc @@ -23,7 +23,11 @@ TEST(WebAnimationTest, DefaultSettings) { EXPECT_EQ(1, animation->iterations()); EXPECT_EQ(0, animation->startTime()); EXPECT_EQ(0, animation->timeOffset()); +#if WEB_ANIMATION_SUPPORTS_FULL_DIRECTION + EXPECT_EQ(WebAnimation::DirectionNormal, animation->direction()); +#else EXPECT_FALSE(animation->alternatesDirection()); +#endif } TEST(WebAnimationTest, ModifiedSettings) { @@ -33,12 +37,20 @@ TEST(WebAnimationTest, ModifiedSettings) { animation->setIterations(2); animation->setStartTime(2); animation->setTimeOffset(2); +#if WEB_ANIMATION_SUPPORTS_FULL_DIRECTION + animation->setDirection(WebAnimation::DirectionReverse); +#else animation->setAlternatesDirection(true); +#endif EXPECT_EQ(2, animation->iterations()); EXPECT_EQ(2, animation->startTime()); EXPECT_EQ(2, animation->timeOffset()); +#if WEB_ANIMATION_SUPPORTS_FULL_DIRECTION + EXPECT_EQ(WebAnimation::DirectionReverse, animation->direction()); +#else EXPECT_TRUE(animation->alternatesDirection()); +#endif } } // namespace |