Add default implementations for AppWindowRegistry::Observer notifications.
[chromium-blink-merge.git] / cc / animation / keyframed_animation_curve.cc
blob4522ca2e6d98029a155e540743d4a2a7a653c429
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 <algorithm>
7 #include "cc/animation/keyframed_animation_curve.h"
8 #include "ui/gfx/animation/tween.h"
9 #include "ui/gfx/box_f.h"
11 namespace cc {
13 namespace {
15 template <class Keyframe>
16 void InsertKeyframe(scoped_ptr<Keyframe> keyframe,
17 ScopedPtrVector<Keyframe>& keyframes) {
18 // Usually, the keyframes will be added in order, so this loop would be
19 // unnecessary and we should skip it if possible.
20 if (!keyframes.empty() && keyframe->Time() < keyframes.back()->Time()) {
21 for (size_t i = 0; i < keyframes.size(); ++i) {
22 if (keyframe->Time() < keyframes[i]->Time()) {
23 keyframes.insert(keyframes.begin() + i, keyframe.Pass());
24 return;
29 keyframes.push_back(keyframe.Pass());
32 template <class Keyframes>
33 float GetProgress(double t, size_t i, const Keyframes& keyframes) {
34 float progress =
35 static_cast<float>((t - keyframes[i]->Time()) /
36 (keyframes[i + 1]->Time() - keyframes[i]->Time()));
38 if (keyframes[i]->timing_function())
39 progress = keyframes[i]->timing_function()->GetValue(progress);
40 return progress;
43 scoped_ptr<TimingFunction> CloneTimingFunction(
44 const TimingFunction* timing_function) {
45 DCHECK(timing_function);
46 scoped_ptr<AnimationCurve> curve(timing_function->Clone());
47 return scoped_ptr<TimingFunction>(
48 static_cast<TimingFunction*>(curve.release()));
51 } // namespace
53 Keyframe::Keyframe(double time, scoped_ptr<TimingFunction> timing_function)
54 : time_(time),
55 timing_function_(timing_function.Pass()) {}
57 Keyframe::~Keyframe() {}
59 double Keyframe::Time() const {
60 return time_;
63 scoped_ptr<ColorKeyframe> ColorKeyframe::Create(
64 double time,
65 SkColor value,
66 scoped_ptr<TimingFunction> timing_function) {
67 return make_scoped_ptr(
68 new ColorKeyframe(time, value, timing_function.Pass()));
71 ColorKeyframe::ColorKeyframe(double time,
72 SkColor value,
73 scoped_ptr<TimingFunction> timing_function)
74 : Keyframe(time, timing_function.Pass()),
75 value_(value) {}
77 ColorKeyframe::~ColorKeyframe() {}
79 SkColor ColorKeyframe::Value() const { return value_; }
81 scoped_ptr<ColorKeyframe> ColorKeyframe::Clone() const {
82 scoped_ptr<TimingFunction> func;
83 if (timing_function())
84 func = CloneTimingFunction(timing_function());
85 return ColorKeyframe::Create(Time(), Value(), func.Pass());
88 scoped_ptr<FloatKeyframe> FloatKeyframe::Create(
89 double time,
90 float value,
91 scoped_ptr<TimingFunction> timing_function) {
92 return make_scoped_ptr(
93 new FloatKeyframe(time, value, timing_function.Pass()));
96 FloatKeyframe::FloatKeyframe(double time,
97 float value,
98 scoped_ptr<TimingFunction> timing_function)
99 : Keyframe(time, timing_function.Pass()),
100 value_(value) {}
102 FloatKeyframe::~FloatKeyframe() {}
104 float FloatKeyframe::Value() const {
105 return value_;
108 scoped_ptr<FloatKeyframe> FloatKeyframe::Clone() const {
109 scoped_ptr<TimingFunction> func;
110 if (timing_function())
111 func = CloneTimingFunction(timing_function());
112 return FloatKeyframe::Create(Time(), Value(), func.Pass());
115 scoped_ptr<TransformKeyframe> TransformKeyframe::Create(
116 double time,
117 const TransformOperations& value,
118 scoped_ptr<TimingFunction> timing_function) {
119 return make_scoped_ptr(
120 new TransformKeyframe(time, value, timing_function.Pass()));
123 TransformKeyframe::TransformKeyframe(double time,
124 const TransformOperations& value,
125 scoped_ptr<TimingFunction> timing_function)
126 : Keyframe(time, timing_function.Pass()),
127 value_(value) {}
129 TransformKeyframe::~TransformKeyframe() {}
131 const TransformOperations& TransformKeyframe::Value() const {
132 return value_;
135 scoped_ptr<TransformKeyframe> TransformKeyframe::Clone() const {
136 scoped_ptr<TimingFunction> func;
137 if (timing_function())
138 func = CloneTimingFunction(timing_function());
139 return TransformKeyframe::Create(Time(), Value(), func.Pass());
142 scoped_ptr<FilterKeyframe> FilterKeyframe::Create(
143 double time,
144 const FilterOperations& value,
145 scoped_ptr<TimingFunction> timing_function) {
146 return make_scoped_ptr(
147 new FilterKeyframe(time, value, timing_function.Pass()));
150 FilterKeyframe::FilterKeyframe(double time,
151 const FilterOperations& value,
152 scoped_ptr<TimingFunction> timing_function)
153 : Keyframe(time, timing_function.Pass()),
154 value_(value) {}
156 FilterKeyframe::~FilterKeyframe() {}
158 const FilterOperations& FilterKeyframe::Value() const {
159 return value_;
162 scoped_ptr<FilterKeyframe> FilterKeyframe::Clone() const {
163 scoped_ptr<TimingFunction> func;
164 if (timing_function())
165 func = CloneTimingFunction(timing_function());
166 return FilterKeyframe::Create(Time(), Value(), func.Pass());
169 scoped_ptr<KeyframedColorAnimationCurve> KeyframedColorAnimationCurve::
170 Create() {
171 return make_scoped_ptr(new KeyframedColorAnimationCurve);
174 KeyframedColorAnimationCurve::KeyframedColorAnimationCurve() {}
176 KeyframedColorAnimationCurve::~KeyframedColorAnimationCurve() {}
178 void KeyframedColorAnimationCurve::AddKeyframe(
179 scoped_ptr<ColorKeyframe> keyframe) {
180 InsertKeyframe(keyframe.Pass(), keyframes_);
183 double KeyframedColorAnimationCurve::Duration() const {
184 return keyframes_.back()->Time() - keyframes_.front()->Time();
187 scoped_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const {
188 scoped_ptr<KeyframedColorAnimationCurve> to_return(
189 KeyframedColorAnimationCurve::Create());
190 for (size_t i = 0; i < keyframes_.size(); ++i)
191 to_return->AddKeyframe(keyframes_[i]->Clone());
192 return to_return.PassAs<AnimationCurve>();
195 SkColor KeyframedColorAnimationCurve::GetValue(double t) const {
196 if (t <= keyframes_.front()->Time())
197 return keyframes_.front()->Value();
199 if (t >= keyframes_.back()->Time())
200 return keyframes_.back()->Value();
202 size_t i = 0;
203 for (; i < keyframes_.size() - 1; ++i) {
204 if (t < keyframes_[i + 1]->Time())
205 break;
208 float progress = GetProgress(t, i, keyframes_);
210 return gfx::Tween::ColorValueBetween(
211 progress, keyframes_[i]->Value(), keyframes_[i + 1]->Value());
214 // KeyframedFloatAnimationCurve
216 scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve::
217 Create() {
218 return make_scoped_ptr(new KeyframedFloatAnimationCurve);
221 KeyframedFloatAnimationCurve::KeyframedFloatAnimationCurve() {}
223 KeyframedFloatAnimationCurve::~KeyframedFloatAnimationCurve() {}
225 void KeyframedFloatAnimationCurve::AddKeyframe(
226 scoped_ptr<FloatKeyframe> keyframe) {
227 InsertKeyframe(keyframe.Pass(), keyframes_);
230 double KeyframedFloatAnimationCurve::Duration() const {
231 return keyframes_.back()->Time() - keyframes_.front()->Time();
234 scoped_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const {
235 scoped_ptr<KeyframedFloatAnimationCurve> to_return(
236 KeyframedFloatAnimationCurve::Create());
237 for (size_t i = 0; i < keyframes_.size(); ++i)
238 to_return->AddKeyframe(keyframes_[i]->Clone());
239 return to_return.PassAs<AnimationCurve>();
242 float KeyframedFloatAnimationCurve::GetValue(double t) const {
243 if (t <= keyframes_.front()->Time())
244 return keyframes_.front()->Value();
246 if (t >= keyframes_.back()->Time())
247 return keyframes_.back()->Value();
249 size_t i = 0;
250 for (; i < keyframes_.size() - 1; ++i) {
251 if (t < keyframes_[i+1]->Time())
252 break;
255 float progress = GetProgress(t, i, keyframes_);
257 return keyframes_[i]->Value() +
258 (keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress;
261 scoped_ptr<KeyframedTransformAnimationCurve> KeyframedTransformAnimationCurve::
262 Create() {
263 return make_scoped_ptr(new KeyframedTransformAnimationCurve);
266 KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {}
268 KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {}
270 void KeyframedTransformAnimationCurve::AddKeyframe(
271 scoped_ptr<TransformKeyframe> keyframe) {
272 InsertKeyframe(keyframe.Pass(), keyframes_);
275 double KeyframedTransformAnimationCurve::Duration() const {
276 return keyframes_.back()->Time() - keyframes_.front()->Time();
279 scoped_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() const {
280 scoped_ptr<KeyframedTransformAnimationCurve> to_return(
281 KeyframedTransformAnimationCurve::Create());
282 for (size_t i = 0; i < keyframes_.size(); ++i)
283 to_return->AddKeyframe(keyframes_[i]->Clone());
284 return to_return.PassAs<AnimationCurve>();
287 // Assumes that (*keyframes).front()->Time() < t < (*keyframes).back()-Time().
288 template<typename ValueType, typename KeyframeType>
289 static ValueType GetCurveValue(const ScopedPtrVector<KeyframeType>* keyframes,
290 double t) {
291 size_t i = 0;
292 for (; i < keyframes->size() - 1; ++i) {
293 if (t < (*keyframes)[i+1]->Time())
294 break;
297 double progress = (t - (*keyframes)[i]->Time()) /
298 ((*keyframes)[i+1]->Time() - (*keyframes)[i]->Time());
300 if ((*keyframes)[i]->timing_function())
301 progress = (*keyframes)[i]->timing_function()->GetValue(progress);
303 return (*keyframes)[i+1]->Value().Blend((*keyframes)[i]->Value(), progress);
306 gfx::Transform KeyframedTransformAnimationCurve::GetValue(double t) const {
307 if (t <= keyframes_.front()->Time())
308 return keyframes_.front()->Value().Apply();
310 if (t >= keyframes_.back()->Time())
311 return keyframes_.back()->Value().Apply();
313 return GetCurveValue<gfx::Transform, TransformKeyframe>(&keyframes_, t);
316 bool KeyframedTransformAnimationCurve::AnimatedBoundsForBox(
317 const gfx::BoxF& box,
318 gfx::BoxF* bounds) const {
319 DCHECK_GE(keyframes_.size(), 2ul);
320 *bounds = gfx::BoxF();
321 for (size_t i = 0; i < keyframes_.size() - 1; ++i) {
322 gfx::BoxF bounds_for_step;
323 float min_progress = 0.0;
324 float max_progress = 1.0;
325 if (keyframes_[i]->timing_function())
326 keyframes_[i]->timing_function()->Range(&min_progress, &max_progress);
327 if (!keyframes_[i+1]->Value().BlendedBoundsForBox(box,
328 keyframes_[i]->Value(),
329 min_progress,
330 max_progress,
331 &bounds_for_step))
332 return false;
333 bounds->Union(bounds_for_step);
335 return true;
338 bool KeyframedTransformAnimationCurve::AffectsScale() const {
339 for (size_t i = 0; i < keyframes_.size(); ++i) {
340 if (keyframes_[i]->Value().AffectsScale())
341 return true;
343 return false;
346 bool KeyframedTransformAnimationCurve::IsTranslation() const {
347 for (size_t i = 0; i < keyframes_.size(); ++i) {
348 if (!keyframes_[i]->Value().IsTranslation() &&
349 !keyframes_[i]->Value().IsIdentity())
350 return false;
352 return true;
355 bool KeyframedTransformAnimationCurve::MaximumScale(float* max_scale) const {
356 DCHECK_GE(keyframes_.size(), 2ul);
357 *max_scale = 0.f;
358 for (size_t i = 1; i < keyframes_.size(); ++i) {
359 float min_progress = 0.f;
360 float max_progress = 1.f;
361 if (keyframes_[i - 1]->timing_function())
362 keyframes_[i - 1]->timing_function()->Range(&min_progress, &max_progress);
364 float max_scale_for_segment = 0.f;
365 if (!keyframes_[i]->Value().MaximumScale(keyframes_[i - 1]->Value(),
366 min_progress,
367 max_progress,
368 &max_scale_for_segment))
369 return false;
371 *max_scale = std::max(*max_scale, max_scale_for_segment);
373 return true;
376 scoped_ptr<KeyframedFilterAnimationCurve> KeyframedFilterAnimationCurve::
377 Create() {
378 return make_scoped_ptr(new KeyframedFilterAnimationCurve);
381 KeyframedFilterAnimationCurve::KeyframedFilterAnimationCurve() {}
383 KeyframedFilterAnimationCurve::~KeyframedFilterAnimationCurve() {}
385 void KeyframedFilterAnimationCurve::AddKeyframe(
386 scoped_ptr<FilterKeyframe> keyframe) {
387 InsertKeyframe(keyframe.Pass(), keyframes_);
390 double KeyframedFilterAnimationCurve::Duration() const {
391 return keyframes_.back()->Time() - keyframes_.front()->Time();
394 scoped_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const {
395 scoped_ptr<KeyframedFilterAnimationCurve> to_return(
396 KeyframedFilterAnimationCurve::Create());
397 for (size_t i = 0; i < keyframes_.size(); ++i)
398 to_return->AddKeyframe(keyframes_[i]->Clone());
399 return to_return.PassAs<AnimationCurve>();
402 FilterOperations KeyframedFilterAnimationCurve::GetValue(double t) const {
403 if (t <= keyframes_.front()->Time())
404 return keyframes_.front()->Value();
406 if (t >= keyframes_.back()->Time())
407 return keyframes_.back()->Value();
409 return GetCurveValue<FilterOperations, FilterKeyframe>(&keyframes_, t);
412 bool KeyframedFilterAnimationCurve::HasFilterThatMovesPixels() const {
413 for (size_t i = 0; i < keyframes_.size(); ++i) {
414 if (keyframes_[i]->Value().HasFilterThatMovesPixels()) {
415 return true;
418 return false;
421 } // namespace cc