layer_animation_element.cc revision 58537e28ecd584eab876aee8be7156509866d23a
1// Copyright (c) 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 "ui/compositor/layer_animation_element.h"
6
7#include "base/compiler_specific.h"
8#include "cc/animation/animation.h"
9#include "cc/animation/animation_id_provider.h"
10#include "ui/base/animation/tween.h"
11#include "ui/compositor/float_animation_curve_adapter.h"
12#include "ui/compositor/layer.h"
13#include "ui/compositor/layer_animation_delegate.h"
14#include "ui/compositor/layer_animator.h"
15#include "ui/compositor/scoped_animation_duration_scale_mode.h"
16#include "ui/compositor/transform_animation_curve_adapter.h"
17#include "ui/gfx/interpolated_transform.h"
18
19namespace ui {
20
21namespace {
22
23// The factor by which duration is scaled up or down when
24// ScopedAnimationDurationScaleMode::duration_scale_mode() is SLOW_DURATION or
25// FAST_DURATION.
26const int kSlowDurationScaleFactor = 4;
27const int kFastDurationScaleFactor = 4;
28
29// Pause -----------------------------------------------------------------------
30class Pause : public LayerAnimationElement {
31 public:
32  Pause(const AnimatableProperties& properties, base::TimeDelta duration)
33      : LayerAnimationElement(properties, duration) {
34  }
35  virtual ~Pause() {}
36
37 private:
38  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {}
39  virtual bool OnProgress(double t,
40                          LayerAnimationDelegate* delegate) OVERRIDE {
41    return false;
42  }
43  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {}
44  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
45
46  DISALLOW_COPY_AND_ASSIGN(Pause);
47};
48
49// TransformTransition ---------------------------------------------------------
50
51class TransformTransition : public LayerAnimationElement {
52 public:
53    TransformTransition(const gfx::Transform& target, base::TimeDelta duration)
54      : LayerAnimationElement(GetProperties(), duration),
55        target_(target) {
56  }
57  virtual ~TransformTransition() {}
58
59 protected:
60  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
61    start_ = delegate->GetTransformForAnimation();
62  }
63
64  virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
65    delegate->SetTransformFromAnimation(
66        Tween::ValueBetween(t, start_, target_));
67    return true;
68  }
69
70  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
71    target->transform = target_;
72  }
73
74  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
75
76 private:
77  static AnimatableProperties GetProperties() {
78    AnimatableProperties properties;
79    properties.insert(LayerAnimationElement::TRANSFORM);
80    return properties;
81  }
82
83  gfx::Transform start_;
84  const gfx::Transform target_;
85
86  DISALLOW_COPY_AND_ASSIGN(TransformTransition);
87};
88
89// InterpolatedTransformTransition ---------------------------------------------
90
91class InterpolatedTransformTransition : public LayerAnimationElement {
92 public:
93  InterpolatedTransformTransition(InterpolatedTransform* interpolated_transform,
94                                  base::TimeDelta duration)
95      : LayerAnimationElement(GetProperties(), duration),
96        interpolated_transform_(interpolated_transform) {
97  }
98  virtual ~InterpolatedTransformTransition() {}
99
100 protected:
101  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
102  }
103
104  virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
105    delegate->SetTransformFromAnimation(
106        interpolated_transform_->Interpolate(static_cast<float>(t)));
107    return true;
108  }
109
110  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
111    target->transform = interpolated_transform_->Interpolate(1.0f);
112  }
113
114  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
115
116 private:
117  static AnimatableProperties GetProperties() {
118    AnimatableProperties properties;
119    properties.insert(LayerAnimationElement::TRANSFORM);
120    return properties;
121  }
122
123  scoped_ptr<InterpolatedTransform> interpolated_transform_;
124
125  DISALLOW_COPY_AND_ASSIGN(InterpolatedTransformTransition);
126};
127
128// BoundsTransition ------------------------------------------------------------
129
130class BoundsTransition : public LayerAnimationElement {
131 public:
132  BoundsTransition(const gfx::Rect& target, base::TimeDelta duration)
133      : LayerAnimationElement(GetProperties(), duration),
134        target_(target) {
135  }
136  virtual ~BoundsTransition() {}
137
138 protected:
139  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
140    start_ = delegate->GetBoundsForAnimation();
141  }
142
143  virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
144    delegate->SetBoundsFromAnimation(Tween::ValueBetween(t, start_, target_));
145    return true;
146  }
147
148  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
149    target->bounds = target_;
150  }
151
152  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
153
154 private:
155  static AnimatableProperties GetProperties() {
156    AnimatableProperties properties;
157    properties.insert(LayerAnimationElement::BOUNDS);
158    return properties;
159  }
160
161  gfx::Rect start_;
162  const gfx::Rect target_;
163
164  DISALLOW_COPY_AND_ASSIGN(BoundsTransition);
165};
166
167// OpacityTransition -----------------------------------------------------------
168
169class OpacityTransition : public LayerAnimationElement {
170 public:
171  OpacityTransition(float target, base::TimeDelta duration)
172      : LayerAnimationElement(GetProperties(), duration),
173        start_(0.0f),
174        target_(target) {
175  }
176  virtual ~OpacityTransition() {}
177
178 protected:
179  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
180    start_ = delegate->GetOpacityForAnimation();
181  }
182
183  virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
184    delegate->SetOpacityFromAnimation(Tween::ValueBetween(t, start_, target_));
185    return true;
186  }
187
188  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
189    target->opacity = target_;
190  }
191
192  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
193
194 private:
195  static AnimatableProperties GetProperties() {
196    AnimatableProperties properties;
197    properties.insert(LayerAnimationElement::OPACITY);
198    return properties;
199  }
200
201  float start_;
202  const float target_;
203
204  DISALLOW_COPY_AND_ASSIGN(OpacityTransition);
205};
206
207// VisibilityTransition --------------------------------------------------------
208
209class VisibilityTransition : public LayerAnimationElement {
210 public:
211  VisibilityTransition(bool target, base::TimeDelta duration)
212      : LayerAnimationElement(GetProperties(), duration),
213        start_(false),
214        target_(target) {
215  }
216  virtual ~VisibilityTransition() {}
217
218 protected:
219  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
220    start_ = delegate->GetVisibilityForAnimation();
221  }
222
223  virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
224    delegate->SetVisibilityFromAnimation(t == 1.0 ? target_ : start_);
225    return t == 1.0;
226  }
227
228  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
229    target->visibility = target_;
230  }
231
232  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
233
234 private:
235  static AnimatableProperties GetProperties() {
236    AnimatableProperties properties;
237    properties.insert(LayerAnimationElement::VISIBILITY);
238    return properties;
239  }
240
241  bool start_;
242  const bool target_;
243
244  DISALLOW_COPY_AND_ASSIGN(VisibilityTransition);
245};
246
247// BrightnessTransition --------------------------------------------------------
248
249class BrightnessTransition : public LayerAnimationElement {
250 public:
251  BrightnessTransition(float target, base::TimeDelta duration)
252      : LayerAnimationElement(GetProperties(), duration),
253        start_(0.0f),
254        target_(target) {
255  }
256  virtual ~BrightnessTransition() {}
257
258 protected:
259  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
260    start_ = delegate->GetBrightnessForAnimation();
261  }
262
263  virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
264    delegate->SetBrightnessFromAnimation(
265        Tween::ValueBetween(t, start_, target_));
266    return true;
267  }
268
269  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
270    target->brightness = target_;
271  }
272
273  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
274
275 private:
276  static AnimatableProperties GetProperties() {
277    AnimatableProperties properties;
278    properties.insert(LayerAnimationElement::BRIGHTNESS);
279    return properties;
280  }
281
282  float start_;
283  const float target_;
284
285  DISALLOW_COPY_AND_ASSIGN(BrightnessTransition);
286};
287
288// GrayscaleTransition ---------------------------------------------------------
289
290class GrayscaleTransition : public LayerAnimationElement {
291 public:
292  GrayscaleTransition(float target, base::TimeDelta duration)
293      : LayerAnimationElement(GetProperties(), duration),
294        start_(0.0f),
295        target_(target) {
296  }
297  virtual ~GrayscaleTransition() {}
298
299 protected:
300  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
301    start_ = delegate->GetGrayscaleForAnimation();
302  }
303
304  virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
305    delegate->SetGrayscaleFromAnimation(
306        Tween::ValueBetween(t, start_, target_));
307    return true;
308  }
309
310  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
311    target->grayscale = target_;
312  }
313
314  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
315
316 private:
317  static AnimatableProperties GetProperties() {
318    AnimatableProperties properties;
319    properties.insert(LayerAnimationElement::GRAYSCALE);
320    return properties;
321  }
322
323  float start_;
324  const float target_;
325
326  DISALLOW_COPY_AND_ASSIGN(GrayscaleTransition);
327};
328
329// ColorTransition -------------------------------------------------------------
330
331class ColorTransition : public LayerAnimationElement {
332 public:
333  ColorTransition(SkColor target, base::TimeDelta duration)
334      : LayerAnimationElement(GetProperties(), duration),
335        start_(SK_ColorBLACK),
336        target_(target) {
337  }
338  virtual ~ColorTransition() {}
339
340 protected:
341  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
342    start_ = delegate->GetColorForAnimation();
343  }
344
345  virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
346    delegate->SetColorFromAnimation(
347        SkColorSetARGB(
348            Tween::ValueBetween(t,
349                                static_cast<int>(SkColorGetA(start_)),
350                                static_cast<int>(SkColorGetA(target_))),
351            Tween::ValueBetween(t,
352                                static_cast<int>(SkColorGetR(start_)),
353                                static_cast<int>(SkColorGetR(target_))),
354            Tween::ValueBetween(t,
355                                static_cast<int>(SkColorGetG(start_)),
356                                static_cast<int>(SkColorGetG(target_))),
357            Tween::ValueBetween(t,
358                                static_cast<int>(SkColorGetB(start_)),
359                                static_cast<int>(SkColorGetB(target_)))));
360    return true;
361  }
362
363  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
364    target->color = target_;
365  }
366
367  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
368
369 private:
370  static AnimatableProperties GetProperties() {
371    AnimatableProperties properties;
372    properties.insert(LayerAnimationElement::COLOR);
373    return properties;
374  }
375
376  SkColor start_;
377  const SkColor target_;
378
379  DISALLOW_COPY_AND_ASSIGN(ColorTransition);
380};
381
382// ThreadedLayerAnimationElement -----------------------------------------------
383
384class ThreadedLayerAnimationElement : public LayerAnimationElement {
385 public:
386  ThreadedLayerAnimationElement(const AnimatableProperties& properties,
387                                base::TimeDelta duration)
388      : LayerAnimationElement(properties, duration) {
389  }
390  virtual ~ThreadedLayerAnimationElement() {}
391
392  virtual bool IsThreaded() const OVERRIDE {
393    return (duration() != base::TimeDelta());
394  }
395
396 protected:
397  explicit ThreadedLayerAnimationElement(const LayerAnimationElement& element)
398    : LayerAnimationElement(element) {
399  }
400
401  virtual bool OnProgress(double t,
402                          LayerAnimationDelegate* delegate) OVERRIDE {
403    if (t < 1.0)
404      return false;
405
406    if (Started()) {
407      delegate->RemoveThreadedAnimation(animation_id());
408    }
409
410    OnEnd(delegate);
411    return true;
412  }
413
414  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {
415    if (delegate && Started()) {
416      delegate->RemoveThreadedAnimation(animation_id());
417    }
418  }
419
420  virtual void RequestEffectiveStart(
421      LayerAnimationDelegate* delegate) OVERRIDE {
422    DCHECK(animation_group_id());
423    if (duration() == base::TimeDelta()) {
424      set_effective_start_time(requested_start_time());
425      return;
426    }
427    set_effective_start_time(base::TimeTicks());
428    scoped_ptr<cc::Animation> animation = CreateCCAnimation();
429    animation->set_needs_synchronized_start_time(true);
430    delegate->AddThreadedAnimation(animation.Pass());
431  }
432
433  virtual void OnEnd(LayerAnimationDelegate* delegate) = 0;
434
435  virtual scoped_ptr<cc::Animation> CreateCCAnimation() = 0;
436
437 private:
438  DISALLOW_COPY_AND_ASSIGN(ThreadedLayerAnimationElement);
439};
440
441// ThreadedOpacityTransition ---------------------------------------------------
442
443class ThreadedOpacityTransition : public ThreadedLayerAnimationElement {
444 public:
445  ThreadedOpacityTransition(float target, base::TimeDelta duration)
446      : ThreadedLayerAnimationElement(GetProperties(), duration),
447        start_(0.0f),
448        target_(target) {
449  }
450  virtual ~ThreadedOpacityTransition() {}
451
452 protected:
453  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
454    start_ = delegate->GetOpacityForAnimation();
455  }
456
457  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {
458    if (delegate && Started()) {
459      ThreadedLayerAnimationElement::OnAbort(delegate);
460      delegate->SetOpacityFromAnimation(Tween::ValueBetween(
461            Tween::CalculateValue(tween_type(), last_progressed_fraction()),
462            start_,
463            target_));
464    }
465  }
466
467  virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE {
468    delegate->SetOpacityFromAnimation(target_);
469  }
470
471  virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE {
472    scoped_ptr<cc::AnimationCurve> animation_curve(
473        new FloatAnimationCurveAdapter(tween_type(),
474                                       start_,
475                                       target_,
476                                       duration()));
477    scoped_ptr<cc::Animation> animation(
478        cc::Animation::Create(animation_curve.Pass(),
479                              animation_id(),
480                              animation_group_id(),
481                              cc::Animation::Opacity));
482    return animation.Pass();
483  }
484
485  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
486    target->opacity = target_;
487  }
488
489 private:
490  static AnimatableProperties GetProperties() {
491    AnimatableProperties properties;
492    properties.insert(LayerAnimationElement::OPACITY);
493    return properties;
494  }
495
496  float start_;
497  const float target_;
498
499  DISALLOW_COPY_AND_ASSIGN(ThreadedOpacityTransition);
500};
501
502// ThreadedTransformTransition -------------------------------------------------
503
504class ThreadedTransformTransition : public ThreadedLayerAnimationElement {
505 public:
506  ThreadedTransformTransition(const gfx::Transform& target,
507                              base::TimeDelta duration)
508      : ThreadedLayerAnimationElement(GetProperties(), duration),
509        target_(target) {
510  }
511  virtual ~ThreadedTransformTransition() {}
512
513 protected:
514  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
515    start_ = delegate->GetTransformForAnimation();
516    float device_scale_factor = delegate->GetDeviceScaleFactor();
517    cc_start_ = Layer::ConvertTransformToCCTransform(start_,
518                                                     device_scale_factor);
519    cc_target_ = Layer::ConvertTransformToCCTransform(target_,
520                                                      device_scale_factor);
521  }
522
523  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {
524    if (delegate && Started()) {
525      ThreadedLayerAnimationElement::OnAbort(delegate);
526      delegate->SetTransformFromAnimation(Tween::ValueBetween(
527          Tween::CalculateValue(tween_type(), last_progressed_fraction()),
528          start_,
529          target_));
530    }
531  }
532
533  virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE {
534    delegate->SetTransformFromAnimation(target_);
535  }
536
537  virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE {
538    scoped_ptr<cc::AnimationCurve> animation_curve(
539        new TransformAnimationCurveAdapter(tween_type(),
540                                           cc_start_,
541                                           cc_target_,
542                                           duration()));
543    scoped_ptr<cc::Animation> animation(
544        cc::Animation::Create(animation_curve.Pass(),
545                              animation_id(),
546                              animation_group_id(),
547                              cc::Animation::Transform));
548    return animation.Pass();
549  }
550
551  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
552    target->transform = target_;
553  }
554
555 private:
556  static AnimatableProperties GetProperties() {
557    AnimatableProperties properties;
558    properties.insert(LayerAnimationElement::TRANSFORM);
559    return properties;
560  }
561
562  gfx::Transform start_;
563  gfx::Transform cc_start_;
564  const gfx::Transform target_;
565  gfx::Transform cc_target_;
566
567  DISALLOW_COPY_AND_ASSIGN(ThreadedTransformTransition);
568};
569
570// InverseTransformTransision --------------------------------------------------
571
572class InverseTransformTransition : public ThreadedLayerAnimationElement {
573 public:
574  InverseTransformTransition(const gfx::Transform& base_transform,
575                             const LayerAnimationElement* uninverted_transition)
576      : ThreadedLayerAnimationElement(*uninverted_transition),
577        base_transform_(base_transform),
578        uninverted_transition_(CheckAndCast(uninverted_transition)) {
579  }
580  virtual ~InverseTransformTransition() {}
581
582 protected:
583  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
584    gfx::Transform start(delegate->GetTransformForAnimation());
585    effective_start_ = base_transform_ * start;
586
587    TargetValue target;
588    uninverted_transition_->GetTargetValue(&target);
589    base_target_ = target.transform;
590
591    set_tween_type(uninverted_transition_->tween_type());
592
593    float device_scale_factor = delegate->GetDeviceScaleFactor();
594    const gfx::Transform cc_base_start = Layer::ConvertTransformToCCTransform(
595        base_transform_,
596        device_scale_factor);
597    const gfx::Transform cc_base_target = Layer::ConvertTransformToCCTransform(
598        base_target_,
599        device_scale_factor);
600    TransformAnimationCurveAdapter base_curve(tween_type(),
601                                              cc_base_start,
602                                              cc_base_target,
603                                              duration());
604
605    const gfx::Transform cc_start = Layer::ConvertTransformToCCTransform(
606        start, device_scale_factor);
607    animation_curve_.reset(new InverseTransformCurveAdapter(
608        base_curve, cc_start, duration()));
609    computed_target_transform_ = ComputeWithBaseTransform(effective_start_,
610                                                          base_target_);
611  }
612
613  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {
614    if (delegate && Started()) {
615      ThreadedLayerAnimationElement::OnAbort(delegate);
616      delegate->SetTransformFromAnimation(ComputeCurrentTransform());
617    }
618  }
619
620  virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE {
621    delegate->SetTransformFromAnimation(computed_target_transform_);
622  }
623
624  virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE {
625    scoped_ptr<cc::Animation> animation(
626        cc::Animation::Create(animation_curve_->Clone(),
627                              animation_id(),
628                              animation_group_id(),
629                              cc::Animation::Transform));
630    return animation.Pass();
631  }
632
633  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
634    target->transform = computed_target_transform_;
635  }
636
637 private:
638  gfx::Transform ComputeCurrentTransform() const {
639    gfx::Transform base_current = Tween::ValueBetween(
640        Tween::CalculateValue(tween_type(), last_progressed_fraction()),
641        base_transform_,
642        base_target_);
643    return ComputeWithBaseTransform(effective_start_, base_current);
644  }
645
646  gfx::Transform ComputeWithBaseTransform(gfx::Transform start,
647                                          gfx::Transform target) const {
648    gfx::Transform to_return(gfx::Transform::kSkipInitialization);
649    DCHECK(target.GetInverse(&to_return));
650
651    to_return.PreconcatTransform(start);
652    return to_return;
653  }
654
655  static AnimatableProperties GetProperties() {
656    AnimatableProperties properties;
657    properties.insert(LayerAnimationElement::TRANSFORM);
658    return properties;
659  }
660
661  static const ThreadedTransformTransition* CheckAndCast(
662      const LayerAnimationElement* element) {
663    const AnimatableProperties& properties = element->properties();
664    DCHECK(properties.find(TRANSFORM) != properties.end());
665    return static_cast<const ThreadedTransformTransition*>(element);
666  }
667
668  gfx::Transform effective_start_;
669  gfx::Transform computed_target_transform_;
670
671  const gfx::Transform base_transform_;
672  gfx::Transform base_target_;
673
674  scoped_ptr<cc::AnimationCurve> animation_curve_;
675
676  const ThreadedTransformTransition* const uninverted_transition_;
677
678  DISALLOW_COPY_AND_ASSIGN(InverseTransformTransition);
679};
680
681}  // namespace
682
683// LayerAnimationElement::TargetValue ------------------------------------------
684
685LayerAnimationElement::TargetValue::TargetValue()
686    : opacity(0.0f),
687      visibility(false),
688      brightness(0.0f),
689      grayscale(0.0f),
690      color(SK_ColorBLACK) {
691}
692
693LayerAnimationElement::TargetValue::TargetValue(
694    const LayerAnimationDelegate* delegate)
695    : bounds(delegate ? delegate->GetBoundsForAnimation() : gfx::Rect()),
696      transform(delegate ?
697                delegate->GetTransformForAnimation() : gfx::Transform()),
698      opacity(delegate ? delegate->GetOpacityForAnimation() : 0.0f),
699      visibility(delegate ? delegate->GetVisibilityForAnimation() : false),
700      brightness(delegate ? delegate->GetBrightnessForAnimation() : 0.0f),
701      grayscale(delegate ? delegate->GetGrayscaleForAnimation() : 0.0f),
702      color(delegate ? delegate->GetColorForAnimation() : 0.0f) {
703}
704
705// LayerAnimationElement -------------------------------------------------------
706
707LayerAnimationElement::LayerAnimationElement(
708    const AnimatableProperties& properties,
709    base::TimeDelta duration)
710    : first_frame_(true),
711      properties_(properties),
712      duration_(GetEffectiveDuration(duration)),
713      tween_type_(Tween::LINEAR),
714      animation_id_(cc::AnimationIdProvider::NextAnimationId()),
715      animation_group_id_(0),
716      last_progressed_fraction_(0.0) {
717}
718
719LayerAnimationElement::LayerAnimationElement(
720    const LayerAnimationElement &element)
721    : first_frame_(element.first_frame_),
722      properties_(element.properties_),
723      duration_(element.duration_),
724      tween_type_(element.tween_type_),
725      animation_id_(cc::AnimationIdProvider::NextAnimationId()),
726      animation_group_id_(element.animation_group_id_),
727      last_progressed_fraction_(element.last_progressed_fraction_) {
728}
729
730LayerAnimationElement::~LayerAnimationElement() {
731}
732
733void LayerAnimationElement::Start(LayerAnimationDelegate* delegate,
734                                  int animation_group_id) {
735  DCHECK(requested_start_time_ != base::TimeTicks());
736  DCHECK(first_frame_);
737  animation_group_id_ = animation_group_id;
738  last_progressed_fraction_ = 0.0;
739  OnStart(delegate);
740  RequestEffectiveStart(delegate);
741  first_frame_ = false;
742}
743
744bool LayerAnimationElement::Progress(base::TimeTicks now,
745                                     LayerAnimationDelegate* delegate) {
746  DCHECK(requested_start_time_ != base::TimeTicks());
747  DCHECK(!first_frame_);
748
749  bool need_draw;
750  double t = 1.0;
751
752  if ((effective_start_time_ == base::TimeTicks()) ||
753      (now < effective_start_time_))  {
754    // This hasn't actually started yet.
755    need_draw = false;
756    last_progressed_fraction_ = 0.0;
757    return need_draw;
758  }
759
760  base::TimeDelta elapsed = now - effective_start_time_;
761  if ((duration_ > base::TimeDelta()) && (elapsed < duration_))
762    t = elapsed.InMillisecondsF() / duration_.InMillisecondsF();
763  need_draw = OnProgress(Tween::CalculateValue(tween_type_, t), delegate);
764  first_frame_ = t == 1.0;
765  last_progressed_fraction_ = t;
766  return need_draw;
767}
768
769bool LayerAnimationElement::IsFinished(base::TimeTicks time,
770                                       base::TimeDelta* total_duration) {
771  // If an effective start has been requested but the effective start time
772  // hasn't yet been set, the animation is not finished, regardless of the
773  // value of |time|.
774  if (!first_frame_ && (effective_start_time_ == base::TimeTicks()))
775    return false;
776
777  base::TimeDelta queueing_delay;
778  if (!first_frame_)
779    queueing_delay = effective_start_time_ - requested_start_time_;
780
781  base::TimeDelta elapsed = time - requested_start_time_;
782  if (elapsed >= duration_ + queueing_delay) {
783    *total_duration = duration_ + queueing_delay;
784    return true;
785  }
786  return false;
787}
788
789bool LayerAnimationElement::ProgressToEnd(LayerAnimationDelegate* delegate) {
790  if (first_frame_)
791    OnStart(delegate);
792  bool need_draw = OnProgress(1.0, delegate);
793  last_progressed_fraction_ = 1.0;
794  first_frame_ = true;
795  return need_draw;
796}
797
798void LayerAnimationElement::GetTargetValue(TargetValue* target) const {
799  OnGetTarget(target);
800}
801
802bool LayerAnimationElement::IsThreaded() const {
803  return false;
804}
805
806void LayerAnimationElement::Abort(LayerAnimationDelegate* delegate) {
807  OnAbort(delegate);
808  first_frame_ = true;
809}
810
811void LayerAnimationElement::RequestEffectiveStart(
812    LayerAnimationDelegate* delegate) {
813  DCHECK(requested_start_time_ != base::TimeTicks());
814  effective_start_time_ = requested_start_time_;
815}
816
817// static
818LayerAnimationElement::AnimatableProperty
819LayerAnimationElement::ToAnimatableProperty(
820    cc::Animation::TargetProperty property) {
821  switch (property) {
822    case cc::Animation::Transform:
823      return TRANSFORM;
824    case cc::Animation::Opacity:
825      return OPACITY;
826    default:
827      NOTREACHED();
828      return AnimatableProperty();
829  }
830}
831
832// static
833base::TimeDelta LayerAnimationElement::GetEffectiveDuration(
834    const base::TimeDelta& duration) {
835  switch (ScopedAnimationDurationScaleMode::duration_scale_mode()) {
836    case ScopedAnimationDurationScaleMode::NORMAL_DURATION:
837      return duration;
838    case ScopedAnimationDurationScaleMode::FAST_DURATION:
839      return duration / kFastDurationScaleFactor;
840    case ScopedAnimationDurationScaleMode::SLOW_DURATION:
841      return duration * kSlowDurationScaleFactor;
842    case ScopedAnimationDurationScaleMode::ZERO_DURATION:
843      return base::TimeDelta();
844    default:
845      NOTREACHED();
846      return base::TimeDelta();
847  }
848}
849
850// static
851LayerAnimationElement* LayerAnimationElement::CreateTransformElement(
852    const gfx::Transform& transform,
853    base::TimeDelta duration) {
854  return new ThreadedTransformTransition(transform, duration);
855}
856
857// static
858LayerAnimationElement* LayerAnimationElement::CreateInverseTransformElement(
859    const gfx::Transform& base_transform,
860    const LayerAnimationElement* uninverted_transition) {
861  return new InverseTransformTransition(base_transform, uninverted_transition);
862}
863
864// static
865LayerAnimationElement*
866LayerAnimationElement::CreateInterpolatedTransformElement(
867    InterpolatedTransform* interpolated_transform,
868    base::TimeDelta duration) {
869  return new InterpolatedTransformTransition(interpolated_transform, duration);
870}
871
872// static
873LayerAnimationElement* LayerAnimationElement::CreateBoundsElement(
874    const gfx::Rect& bounds,
875    base::TimeDelta duration) {
876  return new BoundsTransition(bounds, duration);
877}
878
879// static
880LayerAnimationElement* LayerAnimationElement::CreateOpacityElement(
881    float opacity,
882    base::TimeDelta duration) {
883  return new ThreadedOpacityTransition(opacity, duration);
884}
885
886// static
887LayerAnimationElement* LayerAnimationElement::CreateVisibilityElement(
888    bool visibility,
889    base::TimeDelta duration) {
890  return new VisibilityTransition(visibility, duration);
891}
892
893// static
894LayerAnimationElement* LayerAnimationElement::CreateBrightnessElement(
895    float brightness,
896    base::TimeDelta duration) {
897  return new BrightnessTransition(brightness, duration);
898}
899
900// static
901LayerAnimationElement* LayerAnimationElement::CreateGrayscaleElement(
902    float grayscale,
903    base::TimeDelta duration) {
904  return new GrayscaleTransition(grayscale, duration);
905}
906
907// static
908LayerAnimationElement* LayerAnimationElement::CreatePauseElement(
909    const AnimatableProperties& properties,
910    base::TimeDelta duration) {
911  return new Pause(properties, duration);
912}
913
914// static
915LayerAnimationElement* LayerAnimationElement::CreateColorElement(
916    SkColor color,
917    base::TimeDelta duration) {
918  return new ColorTransition(color, duration);
919}
920
921}  // namespace ui
922