Home | History | Annotate | Download | only in animation
      1 // Copyright 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "cc/animation/keyframed_animation_curve.h"
      6 #include "ui/gfx/animation/tween.h"
      7 #include "ui/gfx/box_f.h"
      8 
      9 namespace cc {
     10 
     11 namespace {
     12 
     13 template <class Keyframe>
     14 void InsertKeyframe(scoped_ptr<Keyframe> keyframe,
     15                     ScopedPtrVector<Keyframe>& keyframes) {
     16   // Usually, the keyframes will be added in order, so this loop would be
     17   // unnecessary and we should skip it if possible.
     18   if (!keyframes.empty() && keyframe->Time() < keyframes.back()->Time()) {
     19     for (size_t i = 0; i < keyframes.size(); ++i) {
     20       if (keyframe->Time() < keyframes[i]->Time()) {
     21         keyframes.insert(keyframes.begin() + i, keyframe.Pass());
     22         return;
     23       }
     24     }
     25   }
     26 
     27   keyframes.push_back(keyframe.Pass());
     28 }
     29 
     30 template <class Keyframes>
     31 float GetProgress(double t, size_t i, const Keyframes& keyframes) {
     32   float progress =
     33       static_cast<float>((t - keyframes[i]->Time()) /
     34                          (keyframes[i + 1]->Time() - keyframes[i]->Time()));
     35 
     36   if (keyframes[i]->timing_function())
     37     progress = keyframes[i]->timing_function()->GetValue(progress);
     38   return progress;
     39 }
     40 
     41 scoped_ptr<TimingFunction> CloneTimingFunction(
     42     const TimingFunction* timing_function) {
     43   DCHECK(timing_function);
     44   scoped_ptr<AnimationCurve> curve(timing_function->Clone());
     45   return scoped_ptr<TimingFunction>(
     46       static_cast<TimingFunction*>(curve.release()));
     47 }
     48 
     49 }  // namespace
     50 
     51 Keyframe::Keyframe(double time, scoped_ptr<TimingFunction> timing_function)
     52     : time_(time),
     53       timing_function_(timing_function.Pass()) {}
     54 
     55 Keyframe::~Keyframe() {}
     56 
     57 double Keyframe::Time() const {
     58   return time_;
     59 }
     60 
     61 scoped_ptr<ColorKeyframe> ColorKeyframe::Create(
     62     double time,
     63     SkColor value,
     64     scoped_ptr<TimingFunction> timing_function) {
     65   return make_scoped_ptr(
     66       new ColorKeyframe(time, value, timing_function.Pass()));
     67 }
     68 
     69 ColorKeyframe::ColorKeyframe(double time,
     70                              SkColor value,
     71                              scoped_ptr<TimingFunction> timing_function)
     72     : Keyframe(time, timing_function.Pass()),
     73       value_(value) {}
     74 
     75 ColorKeyframe::~ColorKeyframe() {}
     76 
     77 SkColor ColorKeyframe::Value() const { return value_; }
     78 
     79 scoped_ptr<ColorKeyframe> ColorKeyframe::Clone() const {
     80   scoped_ptr<TimingFunction> func;
     81   if (timing_function())
     82     func = CloneTimingFunction(timing_function());
     83   return ColorKeyframe::Create(Time(), Value(), func.Pass());
     84 }
     85 
     86 scoped_ptr<FloatKeyframe> FloatKeyframe::Create(
     87     double time,
     88     float value,
     89     scoped_ptr<TimingFunction> timing_function) {
     90   return make_scoped_ptr(
     91       new FloatKeyframe(time, value, timing_function.Pass()));
     92 }
     93 
     94 FloatKeyframe::FloatKeyframe(double time,
     95                              float value,
     96                              scoped_ptr<TimingFunction> timing_function)
     97     : Keyframe(time, timing_function.Pass()),
     98       value_(value) {}
     99 
    100 FloatKeyframe::~FloatKeyframe() {}
    101 
    102 float FloatKeyframe::Value() const {
    103   return value_;
    104 }
    105 
    106 scoped_ptr<FloatKeyframe> FloatKeyframe::Clone() const {
    107   scoped_ptr<TimingFunction> func;
    108   if (timing_function())
    109     func = CloneTimingFunction(timing_function());
    110   return FloatKeyframe::Create(Time(), Value(), func.Pass());
    111 }
    112 
    113 scoped_ptr<TransformKeyframe> TransformKeyframe::Create(
    114     double time,
    115     const TransformOperations& value,
    116     scoped_ptr<TimingFunction> timing_function) {
    117   return make_scoped_ptr(
    118       new TransformKeyframe(time, value, timing_function.Pass()));
    119 }
    120 
    121 TransformKeyframe::TransformKeyframe(double time,
    122                                      const TransformOperations& value,
    123                                      scoped_ptr<TimingFunction> timing_function)
    124     : Keyframe(time, timing_function.Pass()),
    125       value_(value) {}
    126 
    127 TransformKeyframe::~TransformKeyframe() {}
    128 
    129 const TransformOperations& TransformKeyframe::Value() const {
    130   return value_;
    131 }
    132 
    133 scoped_ptr<TransformKeyframe> TransformKeyframe::Clone() const {
    134   scoped_ptr<TimingFunction> func;
    135   if (timing_function())
    136     func = CloneTimingFunction(timing_function());
    137   return TransformKeyframe::Create(Time(), Value(), func.Pass());
    138 }
    139 
    140 scoped_ptr<FilterKeyframe> FilterKeyframe::Create(
    141     double time,
    142     const FilterOperations& value,
    143     scoped_ptr<TimingFunction> timing_function) {
    144   return make_scoped_ptr(
    145       new FilterKeyframe(time, value, timing_function.Pass()));
    146 }
    147 
    148 FilterKeyframe::FilterKeyframe(double time,
    149                                const FilterOperations& value,
    150                                scoped_ptr<TimingFunction> timing_function)
    151     : Keyframe(time, timing_function.Pass()),
    152       value_(value) {}
    153 
    154 FilterKeyframe::~FilterKeyframe() {}
    155 
    156 const FilterOperations& FilterKeyframe::Value() const {
    157   return value_;
    158 }
    159 
    160 scoped_ptr<FilterKeyframe> FilterKeyframe::Clone() const {
    161   scoped_ptr<TimingFunction> func;
    162   if (timing_function())
    163     func = CloneTimingFunction(timing_function());
    164   return FilterKeyframe::Create(Time(), Value(), func.Pass());
    165 }
    166 
    167 scoped_ptr<KeyframedColorAnimationCurve> KeyframedColorAnimationCurve::
    168     Create() {
    169   return make_scoped_ptr(new KeyframedColorAnimationCurve);
    170 }
    171 
    172 KeyframedColorAnimationCurve::KeyframedColorAnimationCurve() {}
    173 
    174 KeyframedColorAnimationCurve::~KeyframedColorAnimationCurve() {}
    175 
    176 void KeyframedColorAnimationCurve::AddKeyframe(
    177     scoped_ptr<ColorKeyframe> keyframe) {
    178   InsertKeyframe(keyframe.Pass(), keyframes_);
    179 }
    180 
    181 double KeyframedColorAnimationCurve::Duration() const {
    182   return keyframes_.back()->Time() - keyframes_.front()->Time();
    183 }
    184 
    185 scoped_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const {
    186   scoped_ptr<KeyframedColorAnimationCurve> to_return(
    187       KeyframedColorAnimationCurve::Create());
    188   for (size_t i = 0; i < keyframes_.size(); ++i)
    189     to_return->AddKeyframe(keyframes_[i]->Clone());
    190   return to_return.PassAs<AnimationCurve>();
    191 }
    192 
    193 SkColor KeyframedColorAnimationCurve::GetValue(double t) const {
    194   if (t <= keyframes_.front()->Time())
    195     return keyframes_.front()->Value();
    196 
    197   if (t >= keyframes_.back()->Time())
    198     return keyframes_.back()->Value();
    199 
    200   size_t i = 0;
    201   for (; i < keyframes_.size() - 1; ++i) {
    202     if (t < keyframes_[i + 1]->Time())
    203       break;
    204   }
    205 
    206   float progress = GetProgress(t, i, keyframes_);
    207 
    208   return gfx::Tween::ColorValueBetween(
    209       progress, keyframes_[i]->Value(), keyframes_[i + 1]->Value());
    210 }
    211 
    212 // KeyframedFloatAnimationCurve
    213 
    214 scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve::
    215     Create() {
    216   return make_scoped_ptr(new KeyframedFloatAnimationCurve);
    217 }
    218 
    219 KeyframedFloatAnimationCurve::KeyframedFloatAnimationCurve() {}
    220 
    221 KeyframedFloatAnimationCurve::~KeyframedFloatAnimationCurve() {}
    222 
    223 void KeyframedFloatAnimationCurve::AddKeyframe(
    224     scoped_ptr<FloatKeyframe> keyframe) {
    225   InsertKeyframe(keyframe.Pass(), keyframes_);
    226 }
    227 
    228 double KeyframedFloatAnimationCurve::Duration() const {
    229   return keyframes_.back()->Time() - keyframes_.front()->Time();
    230 }
    231 
    232 scoped_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const {
    233   scoped_ptr<KeyframedFloatAnimationCurve> to_return(
    234       KeyframedFloatAnimationCurve::Create());
    235   for (size_t i = 0; i < keyframes_.size(); ++i)
    236     to_return->AddKeyframe(keyframes_[i]->Clone());
    237   return to_return.PassAs<AnimationCurve>();
    238 }
    239 
    240 float KeyframedFloatAnimationCurve::GetValue(double t) const {
    241   if (t <= keyframes_.front()->Time())
    242     return keyframes_.front()->Value();
    243 
    244   if (t >= keyframes_.back()->Time())
    245     return keyframes_.back()->Value();
    246 
    247   size_t i = 0;
    248   for (; i < keyframes_.size() - 1; ++i) {
    249     if (t < keyframes_[i+1]->Time())
    250       break;
    251   }
    252 
    253   float progress = GetProgress(t, i, keyframes_);
    254 
    255   return keyframes_[i]->Value() +
    256       (keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress;
    257 }
    258 
    259 scoped_ptr<KeyframedTransformAnimationCurve> KeyframedTransformAnimationCurve::
    260     Create() {
    261   return make_scoped_ptr(new KeyframedTransformAnimationCurve);
    262 }
    263 
    264 KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {}
    265 
    266 KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {}
    267 
    268 void KeyframedTransformAnimationCurve::AddKeyframe(
    269     scoped_ptr<TransformKeyframe> keyframe) {
    270   InsertKeyframe(keyframe.Pass(), keyframes_);
    271 }
    272 
    273 double KeyframedTransformAnimationCurve::Duration() const {
    274   return keyframes_.back()->Time() - keyframes_.front()->Time();
    275 }
    276 
    277 scoped_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() const {
    278   scoped_ptr<KeyframedTransformAnimationCurve> to_return(
    279       KeyframedTransformAnimationCurve::Create());
    280   for (size_t i = 0; i < keyframes_.size(); ++i)
    281     to_return->AddKeyframe(keyframes_[i]->Clone());
    282   return to_return.PassAs<AnimationCurve>();
    283 }
    284 
    285 // Assumes that (*keyframes).front()->Time() < t < (*keyframes).back()-Time().
    286 template<typename ValueType, typename KeyframeType>
    287 static ValueType GetCurveValue(const ScopedPtrVector<KeyframeType>* keyframes,
    288                                double t) {
    289   size_t i = 0;
    290   for (; i < keyframes->size() - 1; ++i) {
    291     if (t < (*keyframes)[i+1]->Time())
    292       break;
    293   }
    294 
    295   double progress = (t - (*keyframes)[i]->Time()) /
    296                     ((*keyframes)[i+1]->Time() - (*keyframes)[i]->Time());
    297 
    298   if ((*keyframes)[i]->timing_function())
    299     progress = (*keyframes)[i]->timing_function()->GetValue(progress);
    300 
    301   return (*keyframes)[i+1]->Value().Blend((*keyframes)[i]->Value(), progress);
    302 }
    303 
    304 gfx::Transform KeyframedTransformAnimationCurve::GetValue(double t) const {
    305   if (t <= keyframes_.front()->Time())
    306     return keyframes_.front()->Value().Apply();
    307 
    308   if (t >= keyframes_.back()->Time())
    309     return keyframes_.back()->Value().Apply();
    310 
    311   return GetCurveValue<gfx::Transform, TransformKeyframe>(&keyframes_, t);
    312 }
    313 
    314 bool KeyframedTransformAnimationCurve::AnimatedBoundsForBox(
    315     const gfx::BoxF& box,
    316     gfx::BoxF* bounds) const {
    317   DCHECK_GE(keyframes_.size(), 2ul);
    318   *bounds = gfx::BoxF();
    319   for (size_t i = 0; i < keyframes_.size() - 1; ++i) {
    320     gfx::BoxF bounds_for_step;
    321     float min_progress = 0.0;
    322     float max_progress = 1.0;
    323     if (keyframes_[i]->timing_function())
    324       keyframes_[i]->timing_function()->Range(&min_progress, &max_progress);
    325     if (!keyframes_[i+1]->Value().BlendedBoundsForBox(box,
    326                                                       keyframes_[i]->Value(),
    327                                                       min_progress,
    328                                                       max_progress,
    329                                                       &bounds_for_step))
    330       return false;
    331     bounds->Union(bounds_for_step);
    332   }
    333   return true;
    334 }
    335 
    336 scoped_ptr<KeyframedFilterAnimationCurve> KeyframedFilterAnimationCurve::
    337     Create() {
    338   return make_scoped_ptr(new KeyframedFilterAnimationCurve);
    339 }
    340 
    341 KeyframedFilterAnimationCurve::KeyframedFilterAnimationCurve() {}
    342 
    343 KeyframedFilterAnimationCurve::~KeyframedFilterAnimationCurve() {}
    344 
    345 void KeyframedFilterAnimationCurve::AddKeyframe(
    346     scoped_ptr<FilterKeyframe> keyframe) {
    347   InsertKeyframe(keyframe.Pass(), keyframes_);
    348 }
    349 
    350 double KeyframedFilterAnimationCurve::Duration() const {
    351   return keyframes_.back()->Time() - keyframes_.front()->Time();
    352 }
    353 
    354 scoped_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const {
    355   scoped_ptr<KeyframedFilterAnimationCurve> to_return(
    356       KeyframedFilterAnimationCurve::Create());
    357   for (size_t i = 0; i < keyframes_.size(); ++i)
    358     to_return->AddKeyframe(keyframes_[i]->Clone());
    359   return to_return.PassAs<AnimationCurve>();
    360 }
    361 
    362 FilterOperations KeyframedFilterAnimationCurve::GetValue(double t) const {
    363   if (t <= keyframes_.front()->Time())
    364     return keyframes_.front()->Value();
    365 
    366   if (t >= keyframes_.back()->Time())
    367     return keyframes_.back()->Value();
    368 
    369   return GetCurveValue<FilterOperations, FilterKeyframe>(&keyframes_, t);
    370 }
    371 
    372 }  // namespace cc
    373