- add sources.
[platform/framework/web/crosswalk.git] / src / cc / animation / keyframed_animation_curve.cc
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