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 
      7 namespace cc {
      8 
      9 namespace {
     10 
     11 template <class Keyframe>
     12 void InsertKeyframe(scoped_ptr<Keyframe> keyframe,
     13                     ScopedPtrVector<Keyframe>& keyframes) {
     14   // Usually, the keyframes will be added in order, so this loop would be
     15   // unnecessary and we should skip it if possible.
     16   if (!keyframes.empty() && keyframe->Time() < keyframes.back()->Time()) {
     17     for (size_t i = 0; i < keyframes.size(); ++i) {
     18       if (keyframe->Time() < keyframes[i]->Time()) {
     19         keyframes.insert(keyframes.begin() + i, keyframe.Pass());
     20         return;
     21       }
     22     }
     23   }
     24 
     25   keyframes.push_back(keyframe.Pass());
     26 }
     27 
     28 scoped_ptr<TimingFunction> CloneTimingFunction(
     29     const TimingFunction* timing_function) {
     30   DCHECK(timing_function);
     31   scoped_ptr<AnimationCurve> curve(timing_function->Clone());
     32   return scoped_ptr<TimingFunction>(
     33       static_cast<TimingFunction*>(curve.release()));
     34 }
     35 
     36 }  // namespace
     37 
     38 Keyframe::Keyframe(double time, scoped_ptr<TimingFunction> timing_function)
     39     : time_(time),
     40       timing_function_(timing_function.Pass()) {}
     41 
     42 Keyframe::~Keyframe() {}
     43 
     44 double Keyframe::Time() const {
     45   return time_;
     46 }
     47 
     48 scoped_ptr<FloatKeyframe> FloatKeyframe::Create(
     49     double time,
     50     float value,
     51     scoped_ptr<TimingFunction> timing_function) {
     52   return make_scoped_ptr(
     53       new FloatKeyframe(time, value, timing_function.Pass()));
     54 }
     55 
     56 FloatKeyframe::FloatKeyframe(double time,
     57                              float value,
     58                              scoped_ptr<TimingFunction> timing_function)
     59     : Keyframe(time, timing_function.Pass()),
     60       value_(value) {}
     61 
     62 FloatKeyframe::~FloatKeyframe() {}
     63 
     64 float FloatKeyframe::Value() const {
     65   return value_;
     66 }
     67 
     68 scoped_ptr<FloatKeyframe> FloatKeyframe::Clone() const {
     69   scoped_ptr<TimingFunction> func;
     70   if (timing_function())
     71     func = CloneTimingFunction(timing_function());
     72   return FloatKeyframe::Create(Time(), Value(), func.Pass());
     73 }
     74 
     75 scoped_ptr<TransformKeyframe> TransformKeyframe::Create(
     76     double time,
     77     const TransformOperations& value,
     78     scoped_ptr<TimingFunction> timing_function) {
     79   return make_scoped_ptr(
     80       new TransformKeyframe(time, value, timing_function.Pass()));
     81 }
     82 
     83 TransformKeyframe::TransformKeyframe(double time,
     84                                      const TransformOperations& value,
     85                                      scoped_ptr<TimingFunction> timing_function)
     86     : Keyframe(time, timing_function.Pass()),
     87       value_(value) {}
     88 
     89 TransformKeyframe::~TransformKeyframe() {}
     90 
     91 const TransformOperations& TransformKeyframe::Value() const {
     92   return value_;
     93 }
     94 
     95 scoped_ptr<TransformKeyframe> TransformKeyframe::Clone() const {
     96   scoped_ptr<TimingFunction> func;
     97   if (timing_function())
     98     func = CloneTimingFunction(timing_function());
     99   return TransformKeyframe::Create(Time(), Value(), func.Pass());
    100 }
    101 
    102 scoped_ptr<FilterKeyframe> FilterKeyframe::Create(
    103     double time,
    104     const FilterOperations& value,
    105     scoped_ptr<TimingFunction> timing_function) {
    106   return make_scoped_ptr(
    107       new FilterKeyframe(time, value, timing_function.Pass()));
    108 }
    109 
    110 FilterKeyframe::FilterKeyframe(double time,
    111                                const FilterOperations& value,
    112                                scoped_ptr<TimingFunction> timing_function)
    113     : Keyframe(time, timing_function.Pass()),
    114       value_(value) {}
    115 
    116 FilterKeyframe::~FilterKeyframe() {}
    117 
    118 const FilterOperations& FilterKeyframe::Value() const {
    119   return value_;
    120 }
    121 
    122 scoped_ptr<FilterKeyframe> FilterKeyframe::Clone() const {
    123   scoped_ptr<TimingFunction> func;
    124   if (timing_function())
    125     func = CloneTimingFunction(timing_function());
    126   return FilterKeyframe::Create(Time(), Value(), func.Pass());
    127 }
    128 
    129 scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve::
    130     Create() {
    131   return make_scoped_ptr(new KeyframedFloatAnimationCurve);
    132 }
    133 
    134 KeyframedFloatAnimationCurve::KeyframedFloatAnimationCurve() {}
    135 
    136 KeyframedFloatAnimationCurve::~KeyframedFloatAnimationCurve() {}
    137 
    138 void KeyframedFloatAnimationCurve::AddKeyframe(
    139     scoped_ptr<FloatKeyframe> keyframe) {
    140   InsertKeyframe(keyframe.Pass(), keyframes_);
    141 }
    142 
    143 double KeyframedFloatAnimationCurve::Duration() const {
    144   return keyframes_.back()->Time() - keyframes_.front()->Time();
    145 }
    146 
    147 scoped_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const {
    148   scoped_ptr<KeyframedFloatAnimationCurve> to_return(
    149       KeyframedFloatAnimationCurve::Create());
    150   for (size_t i = 0; i < keyframes_.size(); ++i)
    151     to_return->AddKeyframe(keyframes_[i]->Clone());
    152   return to_return.PassAs<AnimationCurve>();
    153 }
    154 
    155 float KeyframedFloatAnimationCurve::GetValue(double t) const {
    156   if (t <= keyframes_.front()->Time())
    157     return keyframes_.front()->Value();
    158 
    159   if (t >= keyframes_.back()->Time())
    160     return keyframes_.back()->Value();
    161 
    162   size_t i = 0;
    163   for (; i < keyframes_.size() - 1; ++i) {
    164     if (t < keyframes_[i+1]->Time())
    165       break;
    166   }
    167 
    168   float progress =
    169       static_cast<float>((t - keyframes_[i]->Time()) /
    170                          (keyframes_[i+1]->Time() - keyframes_[i]->Time()));
    171 
    172   if (keyframes_[i]->timing_function())
    173     progress = keyframes_[i]->timing_function()->GetValue(progress);
    174 
    175   return keyframes_[i]->Value() +
    176       (keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress;
    177 }
    178 
    179 scoped_ptr<KeyframedTransformAnimationCurve> KeyframedTransformAnimationCurve::
    180     Create() {
    181   return make_scoped_ptr(new KeyframedTransformAnimationCurve);
    182 }
    183 
    184 KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {}
    185 
    186 KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {}
    187 
    188 void KeyframedTransformAnimationCurve::AddKeyframe(
    189     scoped_ptr<TransformKeyframe> keyframe) {
    190   InsertKeyframe(keyframe.Pass(), keyframes_);
    191 }
    192 
    193 double KeyframedTransformAnimationCurve::Duration() const {
    194   return keyframes_.back()->Time() - keyframes_.front()->Time();
    195 }
    196 
    197 scoped_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() const {
    198   scoped_ptr<KeyframedTransformAnimationCurve> to_return(
    199       KeyframedTransformAnimationCurve::Create());
    200   for (size_t i = 0; i < keyframes_.size(); ++i)
    201     to_return->AddKeyframe(keyframes_[i]->Clone());
    202   return to_return.PassAs<AnimationCurve>();
    203 }
    204 
    205 // Assumes that (*keyframes).front()->Time() < t < (*keyframes).back()-Time().
    206 template<typename ValueType, typename KeyframeType>
    207 static ValueType GetCurveValue(const ScopedPtrVector<KeyframeType>* keyframes,
    208                                double t) {
    209   size_t i = 0;
    210   for (; i < keyframes->size() - 1; ++i) {
    211     if (t < (*keyframes)[i+1]->Time())
    212       break;
    213   }
    214 
    215   double progress = (t - (*keyframes)[i]->Time()) /
    216                     ((*keyframes)[i+1]->Time() - (*keyframes)[i]->Time());
    217 
    218   if ((*keyframes)[i]->timing_function())
    219     progress = (*keyframes)[i]->timing_function()->GetValue(progress);
    220 
    221   return (*keyframes)[i+1]->Value().Blend((*keyframes)[i]->Value(), progress);
    222 }
    223 
    224 gfx::Transform KeyframedTransformAnimationCurve::GetValue(double t) const {
    225   if (t <= keyframes_.front()->Time())
    226     return keyframes_.front()->Value().Apply();
    227 
    228   if (t >= keyframes_.back()->Time())
    229     return keyframes_.back()->Value().Apply();
    230 
    231   return GetCurveValue<gfx::Transform, TransformKeyframe>(&keyframes_, t);
    232 }
    233 
    234 scoped_ptr<KeyframedFilterAnimationCurve> KeyframedFilterAnimationCurve::
    235     Create() {
    236   return make_scoped_ptr(new KeyframedFilterAnimationCurve);
    237 }
    238 
    239 KeyframedFilterAnimationCurve::KeyframedFilterAnimationCurve() {}
    240 
    241 KeyframedFilterAnimationCurve::~KeyframedFilterAnimationCurve() {}
    242 
    243 void KeyframedFilterAnimationCurve::AddKeyframe(
    244     scoped_ptr<FilterKeyframe> keyframe) {
    245   InsertKeyframe(keyframe.Pass(), keyframes_);
    246 }
    247 
    248 double KeyframedFilterAnimationCurve::Duration() const {
    249   return keyframes_.back()->Time() - keyframes_.front()->Time();
    250 }
    251 
    252 scoped_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const {
    253   scoped_ptr<KeyframedFilterAnimationCurve> to_return(
    254       KeyframedFilterAnimationCurve::Create());
    255   for (size_t i = 0; i < keyframes_.size(); ++i)
    256     to_return->AddKeyframe(keyframes_[i]->Clone());
    257   return to_return.PassAs<AnimationCurve>();
    258 }
    259 
    260 FilterOperations KeyframedFilterAnimationCurve::GetValue(double t) const {
    261   if (t <= keyframes_.front()->Time())
    262     return keyframes_.front()->Value();
    263 
    264   if (t >= keyframes_.back()->Time())
    265     return keyframes_.back()->Value();
    266 
    267   return GetCurveValue<FilterOperations, FilterKeyframe>(&keyframes_, t);
    268 }
    269 
    270 }  // namespace cc
    271