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