Currently duration is simply returned or changed without checking whether the stream...
[chromium-blink-merge.git] / cc / animation / keyframed_animation_curve.cc
blobd855decbaf93c08ceb39068beecf2e6b0452a5ed
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.
5 #include "cc/animation/keyframed_animation_curve.h"
6 #include "ui/gfx/animation/tween.h"
7 #include "ui/gfx/box_f.h"
9 namespace cc {
11 namespace {
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;
27 keyframes.push_back(keyframe.Pass());
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()));
36 if (keyframes[i]->timing_function())
37 progress = keyframes[i]->timing_function()->GetValue(progress);
38 return progress;
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()));
49 } // namespace
51 Keyframe::Keyframe(double time, scoped_ptr<TimingFunction> timing_function)
52 : time_(time),
53 timing_function_(timing_function.Pass()) {}
55 Keyframe::~Keyframe() {}
57 double Keyframe::Time() const {
58 return time_;
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()));
69 ColorKeyframe::ColorKeyframe(double time,
70 SkColor value,
71 scoped_ptr<TimingFunction> timing_function)
72 : Keyframe(time, timing_function.Pass()),
73 value_(value) {}
75 ColorKeyframe::~ColorKeyframe() {}
77 SkColor ColorKeyframe::Value() const { return value_; }
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());
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()));
94 FloatKeyframe::FloatKeyframe(double time,
95 float value,
96 scoped_ptr<TimingFunction> timing_function)
97 : Keyframe(time, timing_function.Pass()),
98 value_(value) {}
100 FloatKeyframe::~FloatKeyframe() {}
102 float FloatKeyframe::Value() const {
103 return value_;
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());
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()));
121 TransformKeyframe::TransformKeyframe(double time,
122 const TransformOperations& value,
123 scoped_ptr<TimingFunction> timing_function)
124 : Keyframe(time, timing_function.Pass()),
125 value_(value) {}
127 TransformKeyframe::~TransformKeyframe() {}
129 const TransformOperations& TransformKeyframe::Value() const {
130 return value_;
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());
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()));
148 FilterKeyframe::FilterKeyframe(double time,
149 const FilterOperations& value,
150 scoped_ptr<TimingFunction> timing_function)
151 : Keyframe(time, timing_function.Pass()),
152 value_(value) {}
154 FilterKeyframe::~FilterKeyframe() {}
156 const FilterOperations& FilterKeyframe::Value() const {
157 return value_;
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());
167 scoped_ptr<KeyframedColorAnimationCurve> KeyframedColorAnimationCurve::
168 Create() {
169 return make_scoped_ptr(new KeyframedColorAnimationCurve);
172 KeyframedColorAnimationCurve::KeyframedColorAnimationCurve() {}
174 KeyframedColorAnimationCurve::~KeyframedColorAnimationCurve() {}
176 void KeyframedColorAnimationCurve::AddKeyframe(
177 scoped_ptr<ColorKeyframe> keyframe) {
178 InsertKeyframe(keyframe.Pass(), keyframes_);
181 double KeyframedColorAnimationCurve::Duration() const {
182 return keyframes_.back()->Time() - keyframes_.front()->Time();
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>();
193 SkColor KeyframedColorAnimationCurve::GetValue(double t) const {
194 if (t <= keyframes_.front()->Time())
195 return keyframes_.front()->Value();
197 if (t >= keyframes_.back()->Time())
198 return keyframes_.back()->Value();
200 size_t i = 0;
201 for (; i < keyframes_.size() - 1; ++i) {
202 if (t < keyframes_[i + 1]->Time())
203 break;
206 float progress = GetProgress(t, i, keyframes_);
208 return gfx::Tween::ColorValueBetween(
209 progress, keyframes_[i]->Value(), keyframes_[i + 1]->Value());
212 // KeyframedFloatAnimationCurve
214 scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve::
215 Create() {
216 return make_scoped_ptr(new KeyframedFloatAnimationCurve);
219 KeyframedFloatAnimationCurve::KeyframedFloatAnimationCurve() {}
221 KeyframedFloatAnimationCurve::~KeyframedFloatAnimationCurve() {}
223 void KeyframedFloatAnimationCurve::AddKeyframe(
224 scoped_ptr<FloatKeyframe> keyframe) {
225 InsertKeyframe(keyframe.Pass(), keyframes_);
228 double KeyframedFloatAnimationCurve::Duration() const {
229 return keyframes_.back()->Time() - keyframes_.front()->Time();
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>();
240 float KeyframedFloatAnimationCurve::GetValue(double t) const {
241 if (t <= keyframes_.front()->Time())
242 return keyframes_.front()->Value();
244 if (t >= keyframes_.back()->Time())
245 return keyframes_.back()->Value();
247 size_t i = 0;
248 for (; i < keyframes_.size() - 1; ++i) {
249 if (t < keyframes_[i+1]->Time())
250 break;
253 float progress = GetProgress(t, i, keyframes_);
255 return keyframes_[i]->Value() +
256 (keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress;
259 scoped_ptr<KeyframedTransformAnimationCurve> KeyframedTransformAnimationCurve::
260 Create() {
261 return make_scoped_ptr(new KeyframedTransformAnimationCurve);
264 KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {}
266 KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {}
268 void KeyframedTransformAnimationCurve::AddKeyframe(
269 scoped_ptr<TransformKeyframe> keyframe) {
270 InsertKeyframe(keyframe.Pass(), keyframes_);
273 double KeyframedTransformAnimationCurve::Duration() const {
274 return keyframes_.back()->Time() - keyframes_.front()->Time();
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>();
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;
295 double progress = (t - (*keyframes)[i]->Time()) /
296 ((*keyframes)[i+1]->Time() - (*keyframes)[i]->Time());
298 if ((*keyframes)[i]->timing_function())
299 progress = (*keyframes)[i]->timing_function()->GetValue(progress);
301 return (*keyframes)[i+1]->Value().Blend((*keyframes)[i]->Value(), progress);
304 gfx::Transform KeyframedTransformAnimationCurve::GetValue(double t) const {
305 if (t <= keyframes_.front()->Time())
306 return keyframes_.front()->Value().Apply();
308 if (t >= keyframes_.back()->Time())
309 return keyframes_.back()->Value().Apply();
311 return GetCurveValue<gfx::Transform, TransformKeyframe>(&keyframes_, t);
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);
333 return true;
336 scoped_ptr<KeyframedFilterAnimationCurve> KeyframedFilterAnimationCurve::
337 Create() {
338 return make_scoped_ptr(new KeyframedFilterAnimationCurve);
341 KeyframedFilterAnimationCurve::KeyframedFilterAnimationCurve() {}
343 KeyframedFilterAnimationCurve::~KeyframedFilterAnimationCurve() {}
345 void KeyframedFilterAnimationCurve::AddKeyframe(
346 scoped_ptr<FilterKeyframe> keyframe) {
347 InsertKeyframe(keyframe.Pass(), keyframes_);
350 double KeyframedFilterAnimationCurve::Duration() const {
351 return keyframes_.back()->Time() - keyframes_.front()->Time();
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>();
362 FilterOperations KeyframedFilterAnimationCurve::GetValue(double t) const {
363 if (t <= keyframes_.front()->Time())
364 return keyframes_.front()->Value();
366 if (t >= keyframes_.back()->Time())
367 return keyframes_.back()->Value();
369 return GetCurveValue<FilterOperations, FilterKeyframe>(&keyframes_, t);
372 } // namespace cc