• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
InsertKeyframe(scoped_ptr<Keyframe> keyframe,ScopedPtrVector<Keyframe> & keyframes)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>
GetProgress(double t,size_t i,const Keyframes & 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 
CloneTimingFunction(const TimingFunction * timing_function)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 
Keyframe(double time,scoped_ptr<TimingFunction> timing_function)51 Keyframe::Keyframe(double time, scoped_ptr<TimingFunction> timing_function)
52     : time_(time),
53       timing_function_(timing_function.Pass()) {}
54 
~Keyframe()55 Keyframe::~Keyframe() {}
56 
Time() const57 double Keyframe::Time() const {
58   return time_;
59 }
60 
Create(double time,SkColor value,scoped_ptr<TimingFunction> timing_function)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 
ColorKeyframe(double time,SkColor value,scoped_ptr<TimingFunction> timing_function)69 ColorKeyframe::ColorKeyframe(double time,
70                              SkColor value,
71                              scoped_ptr<TimingFunction> timing_function)
72     : Keyframe(time, timing_function.Pass()),
73       value_(value) {}
74 
~ColorKeyframe()75 ColorKeyframe::~ColorKeyframe() {}
76 
Value() const77 SkColor ColorKeyframe::Value() const { return value_; }
78 
Clone() const79 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 
Create(double time,float value,scoped_ptr<TimingFunction> timing_function)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 
FloatKeyframe(double time,float value,scoped_ptr<TimingFunction> timing_function)94 FloatKeyframe::FloatKeyframe(double time,
95                              float value,
96                              scoped_ptr<TimingFunction> timing_function)
97     : Keyframe(time, timing_function.Pass()),
98       value_(value) {}
99 
~FloatKeyframe()100 FloatKeyframe::~FloatKeyframe() {}
101 
Value() const102 float FloatKeyframe::Value() const {
103   return value_;
104 }
105 
Clone() const106 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 
Create(double time,const TransformOperations & value,scoped_ptr<TimingFunction> timing_function)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 
TransformKeyframe(double time,const TransformOperations & value,scoped_ptr<TimingFunction> timing_function)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 
~TransformKeyframe()127 TransformKeyframe::~TransformKeyframe() {}
128 
Value() const129 const TransformOperations& TransformKeyframe::Value() const {
130   return value_;
131 }
132 
Clone() const133 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 
Create(double time,const FilterOperations & value,scoped_ptr<TimingFunction> timing_function)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 
FilterKeyframe(double time,const FilterOperations & value,scoped_ptr<TimingFunction> timing_function)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 
~FilterKeyframe()154 FilterKeyframe::~FilterKeyframe() {}
155 
Value() const156 const FilterOperations& FilterKeyframe::Value() const {
157   return value_;
158 }
159 
Clone() const160 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::
Create()168     Create() {
169   return make_scoped_ptr(new KeyframedColorAnimationCurve);
170 }
171 
KeyframedColorAnimationCurve()172 KeyframedColorAnimationCurve::KeyframedColorAnimationCurve() {}
173 
~KeyframedColorAnimationCurve()174 KeyframedColorAnimationCurve::~KeyframedColorAnimationCurve() {}
175 
AddKeyframe(scoped_ptr<ColorKeyframe> keyframe)176 void KeyframedColorAnimationCurve::AddKeyframe(
177     scoped_ptr<ColorKeyframe> keyframe) {
178   InsertKeyframe(keyframe.Pass(), keyframes_);
179 }
180 
Duration() const181 double KeyframedColorAnimationCurve::Duration() const {
182   return keyframes_.back()->Time() - keyframes_.front()->Time();
183 }
184 
Clone() const185 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 
GetValue(double t) const193 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::
Create()215     Create() {
216   return make_scoped_ptr(new KeyframedFloatAnimationCurve);
217 }
218 
KeyframedFloatAnimationCurve()219 KeyframedFloatAnimationCurve::KeyframedFloatAnimationCurve() {}
220 
~KeyframedFloatAnimationCurve()221 KeyframedFloatAnimationCurve::~KeyframedFloatAnimationCurve() {}
222 
AddKeyframe(scoped_ptr<FloatKeyframe> keyframe)223 void KeyframedFloatAnimationCurve::AddKeyframe(
224     scoped_ptr<FloatKeyframe> keyframe) {
225   InsertKeyframe(keyframe.Pass(), keyframes_);
226 }
227 
Duration() const228 double KeyframedFloatAnimationCurve::Duration() const {
229   return keyframes_.back()->Time() - keyframes_.front()->Time();
230 }
231 
Clone() const232 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 
GetValue(double t) const240 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::
Create()260     Create() {
261   return make_scoped_ptr(new KeyframedTransformAnimationCurve);
262 }
263 
KeyframedTransformAnimationCurve()264 KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {}
265 
~KeyframedTransformAnimationCurve()266 KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {}
267 
AddKeyframe(scoped_ptr<TransformKeyframe> keyframe)268 void KeyframedTransformAnimationCurve::AddKeyframe(
269     scoped_ptr<TransformKeyframe> keyframe) {
270   InsertKeyframe(keyframe.Pass(), keyframes_);
271 }
272 
Duration() const273 double KeyframedTransformAnimationCurve::Duration() const {
274   return keyframes_.back()->Time() - keyframes_.front()->Time();
275 }
276 
Clone() const277 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>
GetCurveValue(const ScopedPtrVector<KeyframeType> * keyframes,double t)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 
GetValue(double t) const304 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 
AnimatedBoundsForBox(const gfx::BoxF & box,gfx::BoxF * bounds) const314 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::
Create()337     Create() {
338   return make_scoped_ptr(new KeyframedFilterAnimationCurve);
339 }
340 
KeyframedFilterAnimationCurve()341 KeyframedFilterAnimationCurve::KeyframedFilterAnimationCurve() {}
342 
~KeyframedFilterAnimationCurve()343 KeyframedFilterAnimationCurve::~KeyframedFilterAnimationCurve() {}
344 
AddKeyframe(scoped_ptr<FilterKeyframe> keyframe)345 void KeyframedFilterAnimationCurve::AddKeyframe(
346     scoped_ptr<FilterKeyframe> keyframe) {
347   InsertKeyframe(keyframe.Pass(), keyframes_);
348 }
349 
Duration() const350 double KeyframedFilterAnimationCurve::Duration() const {
351   return keyframes_.back()->Time() - keyframes_.front()->Time();
352 }
353 
Clone() const354 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 
GetValue(double t) const362 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