layer_animation_element.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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::TransformValueBetween(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::RectValueBetween(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::FloatValueBetween(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::FloatValueBetween(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::FloatValueBetween(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(SkColorSetARGB(
349        gfx::Tween::IntValueBetween(t,
350                                    static_cast<int>(SkColorGetA(start_)),
351                                    static_cast<int>(SkColorGetA(target_))),
352        gfx::Tween::IntValueBetween(t,
353                                    static_cast<int>(SkColorGetR(start_)),
354                                    static_cast<int>(SkColorGetR(target_))),
355        gfx::Tween::IntValueBetween(t,
356                                    static_cast<int>(SkColorGetG(start_)),
357                                    static_cast<int>(SkColorGetG(target_))),
358        gfx::Tween::IntValueBetween(t,
359                                    static_cast<int>(SkColorGetB(start_)),
360                                    static_cast<int>(SkColorGetB(target_)))));
361    return true;
362  }
363
364  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
365    target->color = target_;
366  }
367
368  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {}
369
370 private:
371  static AnimatableProperties GetProperties() {
372    AnimatableProperties properties;
373    properties.insert(LayerAnimationElement::COLOR);
374    return properties;
375  }
376
377  SkColor start_;
378  const SkColor target_;
379
380  DISALLOW_COPY_AND_ASSIGN(ColorTransition);
381};
382
383// ThreadedLayerAnimationElement -----------------------------------------------
384
385class ThreadedLayerAnimationElement : public LayerAnimationElement {
386 public:
387  ThreadedLayerAnimationElement(const AnimatableProperties& properties,
388                                base::TimeDelta duration)
389      : LayerAnimationElement(properties, duration) {
390  }
391  virtual ~ThreadedLayerAnimationElement() {}
392
393  virtual bool IsThreaded() const OVERRIDE {
394    return (duration() != base::TimeDelta());
395  }
396
397 protected:
398  explicit ThreadedLayerAnimationElement(const LayerAnimationElement& element)
399    : LayerAnimationElement(element) {
400  }
401
402  virtual bool OnProgress(double t,
403                          LayerAnimationDelegate* delegate) OVERRIDE {
404    if (t < 1.0)
405      return false;
406
407    if (Started()) {
408      delegate->RemoveThreadedAnimation(animation_id());
409    }
410
411    OnEnd(delegate);
412    return true;
413  }
414
415  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {
416    if (delegate && Started()) {
417      delegate->RemoveThreadedAnimation(animation_id());
418    }
419  }
420
421  virtual void RequestEffectiveStart(
422      LayerAnimationDelegate* delegate) OVERRIDE {
423    DCHECK(animation_group_id());
424    if (duration() == base::TimeDelta()) {
425      set_effective_start_time(requested_start_time());
426      return;
427    }
428    set_effective_start_time(base::TimeTicks());
429    scoped_ptr<cc::Animation> animation = CreateCCAnimation();
430    animation->set_needs_synchronized_start_time(true);
431    delegate->AddThreadedAnimation(animation.Pass());
432  }
433
434  virtual void OnEnd(LayerAnimationDelegate* delegate) = 0;
435
436  virtual scoped_ptr<cc::Animation> CreateCCAnimation() = 0;
437
438 private:
439  DISALLOW_COPY_AND_ASSIGN(ThreadedLayerAnimationElement);
440};
441
442// ThreadedOpacityTransition ---------------------------------------------------
443
444class ThreadedOpacityTransition : public ThreadedLayerAnimationElement {
445 public:
446  ThreadedOpacityTransition(float target, base::TimeDelta duration)
447      : ThreadedLayerAnimationElement(GetProperties(), duration),
448        start_(0.0f),
449        target_(target) {
450  }
451  virtual ~ThreadedOpacityTransition() {}
452
453 protected:
454  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
455    start_ = delegate->GetOpacityForAnimation();
456  }
457
458  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {
459    if (delegate && Started()) {
460      ThreadedLayerAnimationElement::OnAbort(delegate);
461      delegate->SetOpacityFromAnimation(gfx::Tween::FloatValueBetween(
462          gfx::Tween::CalculateValue(tween_type(), last_progressed_fraction()),
463              start_,
464              target_));
465    }
466  }
467
468  virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE {
469    delegate->SetOpacityFromAnimation(target_);
470  }
471
472  virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE {
473    scoped_ptr<cc::AnimationCurve> animation_curve(
474        new FloatAnimationCurveAdapter(tween_type(),
475                                       start_,
476                                       target_,
477                                       duration()));
478    scoped_ptr<cc::Animation> animation(
479        cc::Animation::Create(animation_curve.Pass(),
480                              animation_id(),
481                              animation_group_id(),
482                              cc::Animation::Opacity));
483    return animation.Pass();
484  }
485
486  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
487    target->opacity = target_;
488  }
489
490 private:
491  static AnimatableProperties GetProperties() {
492    AnimatableProperties properties;
493    properties.insert(LayerAnimationElement::OPACITY);
494    return properties;
495  }
496
497  float start_;
498  const float target_;
499
500  DISALLOW_COPY_AND_ASSIGN(ThreadedOpacityTransition);
501};
502
503// ThreadedTransformTransition -------------------------------------------------
504
505class ThreadedTransformTransition : public ThreadedLayerAnimationElement {
506 public:
507  ThreadedTransformTransition(const gfx::Transform& target,
508                              base::TimeDelta duration)
509      : ThreadedLayerAnimationElement(GetProperties(), duration),
510        target_(target) {
511  }
512  virtual ~ThreadedTransformTransition() {}
513
514 protected:
515  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
516    start_ = delegate->GetTransformForAnimation();
517    float device_scale_factor = delegate->GetDeviceScaleFactor();
518    cc_start_ = Layer::ConvertTransformToCCTransform(start_,
519                                                     device_scale_factor);
520    cc_target_ = Layer::ConvertTransformToCCTransform(target_,
521                                                      device_scale_factor);
522  }
523
524  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {
525    if (delegate && Started()) {
526      ThreadedLayerAnimationElement::OnAbort(delegate);
527      delegate->SetTransformFromAnimation(gfx::Tween::TransformValueBetween(
528          gfx::Tween::CalculateValue(tween_type(), last_progressed_fraction()),
529          start_,
530          target_));
531    }
532  }
533
534  virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE {
535    delegate->SetTransformFromAnimation(target_);
536  }
537
538  virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE {
539    scoped_ptr<cc::AnimationCurve> animation_curve(
540        new TransformAnimationCurveAdapter(tween_type(),
541                                           cc_start_,
542                                           cc_target_,
543                                           duration()));
544    scoped_ptr<cc::Animation> animation(
545        cc::Animation::Create(animation_curve.Pass(),
546                              animation_id(),
547                              animation_group_id(),
548                              cc::Animation::Transform));
549    return animation.Pass();
550  }
551
552  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
553    target->transform = target_;
554  }
555
556 private:
557  static AnimatableProperties GetProperties() {
558    AnimatableProperties properties;
559    properties.insert(LayerAnimationElement::TRANSFORM);
560    return properties;
561  }
562
563  gfx::Transform start_;
564  gfx::Transform cc_start_;
565  const gfx::Transform target_;
566  gfx::Transform cc_target_;
567
568  DISALLOW_COPY_AND_ASSIGN(ThreadedTransformTransition);
569};
570
571// InverseTransformTransision --------------------------------------------------
572
573class InverseTransformTransition : public ThreadedLayerAnimationElement {
574 public:
575  InverseTransformTransition(const gfx::Transform& base_transform,
576                             const LayerAnimationElement* uninverted_transition)
577      : ThreadedLayerAnimationElement(*uninverted_transition),
578        base_transform_(base_transform),
579        uninverted_transition_(
580            CheckAndCast<const ThreadedTransformTransition*>(
581              uninverted_transition)) {
582  }
583  virtual ~InverseTransformTransition() {}
584
585  static InverseTransformTransition* Clone(const LayerAnimationElement* other) {
586    const InverseTransformTransition* other_inverse =
587      CheckAndCast<const InverseTransformTransition*>(other);
588    return new InverseTransformTransition(
589        other_inverse->base_transform_, other_inverse->uninverted_transition_);
590  }
591
592 protected:
593  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
594    gfx::Transform start(delegate->GetTransformForAnimation());
595    effective_start_ = base_transform_ * start;
596
597    TargetValue target;
598    uninverted_transition_->GetTargetValue(&target);
599    base_target_ = target.transform;
600
601    set_tween_type(uninverted_transition_->tween_type());
602
603    float device_scale_factor = delegate->GetDeviceScaleFactor();
604    const gfx::Transform cc_base_start = Layer::ConvertTransformToCCTransform(
605        base_transform_,
606        device_scale_factor);
607    const gfx::Transform cc_base_target = Layer::ConvertTransformToCCTransform(
608        base_target_,
609        device_scale_factor);
610    TransformAnimationCurveAdapter base_curve(tween_type(),
611                                              cc_base_start,
612                                              cc_base_target,
613                                              duration());
614
615    const gfx::Transform cc_start = Layer::ConvertTransformToCCTransform(
616        start, device_scale_factor);
617    animation_curve_.reset(new InverseTransformCurveAdapter(
618        base_curve, cc_start, duration()));
619    computed_target_transform_ = ComputeWithBaseTransform(effective_start_,
620                                                          base_target_);
621  }
622
623  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {
624    if (delegate && Started()) {
625      ThreadedLayerAnimationElement::OnAbort(delegate);
626      delegate->SetTransformFromAnimation(ComputeCurrentTransform());
627    }
628  }
629
630  virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE {
631    delegate->SetTransformFromAnimation(computed_target_transform_);
632  }
633
634  virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE {
635    scoped_ptr<cc::Animation> animation(
636        cc::Animation::Create(animation_curve_->Clone(),
637                              animation_id(),
638                              animation_group_id(),
639                              cc::Animation::Transform));
640    return animation.Pass();
641  }
642
643  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
644    target->transform = computed_target_transform_;
645  }
646
647 private:
648  gfx::Transform ComputeCurrentTransform() const {
649    gfx::Transform base_current = gfx::Tween::TransformValueBetween(
650        gfx::Tween::CalculateValue(tween_type(), last_progressed_fraction()),
651        base_transform_,
652        base_target_);
653    return ComputeWithBaseTransform(effective_start_, base_current);
654  }
655
656  gfx::Transform ComputeWithBaseTransform(gfx::Transform start,
657                                          gfx::Transform target) const {
658    gfx::Transform to_return(gfx::Transform::kSkipInitialization);
659    bool success = target.GetInverse(&to_return);
660    DCHECK(success) << "Target transform must be invertible.";
661
662    to_return.PreconcatTransform(start);
663    return to_return;
664  }
665
666  static AnimatableProperties GetProperties() {
667    AnimatableProperties properties;
668    properties.insert(LayerAnimationElement::TRANSFORM);
669    return properties;
670  }
671
672  template <typename T>
673  static T CheckAndCast(const LayerAnimationElement* element) {
674    const AnimatableProperties& properties = element->properties();
675    DCHECK(properties.find(TRANSFORM) != properties.end());
676    return static_cast<T>(element);
677  }
678
679  gfx::Transform effective_start_;
680  gfx::Transform computed_target_transform_;
681
682  const gfx::Transform base_transform_;
683  gfx::Transform base_target_;
684
685  scoped_ptr<cc::AnimationCurve> animation_curve_;
686
687  const ThreadedTransformTransition* const uninverted_transition_;
688
689  DISALLOW_COPY_AND_ASSIGN(InverseTransformTransition);
690};
691
692}  // namespace
693
694// LayerAnimationElement::TargetValue ------------------------------------------
695
696LayerAnimationElement::TargetValue::TargetValue()
697    : opacity(0.0f),
698      visibility(false),
699      brightness(0.0f),
700      grayscale(0.0f),
701      color(SK_ColorBLACK) {
702}
703
704LayerAnimationElement::TargetValue::TargetValue(
705    const LayerAnimationDelegate* delegate)
706    : bounds(delegate ? delegate->GetBoundsForAnimation() : gfx::Rect()),
707      transform(delegate ?
708                delegate->GetTransformForAnimation() : gfx::Transform()),
709      opacity(delegate ? delegate->GetOpacityForAnimation() : 0.0f),
710      visibility(delegate ? delegate->GetVisibilityForAnimation() : false),
711      brightness(delegate ? delegate->GetBrightnessForAnimation() : 0.0f),
712      grayscale(delegate ? delegate->GetGrayscaleForAnimation() : 0.0f),
713      color(delegate ? delegate->GetColorForAnimation() : 0.0f) {
714}
715
716// LayerAnimationElement -------------------------------------------------------
717
718LayerAnimationElement::LayerAnimationElement(
719    const AnimatableProperties& properties,
720    base::TimeDelta duration)
721    : first_frame_(true),
722      properties_(properties),
723      duration_(GetEffectiveDuration(duration)),
724      tween_type_(gfx::Tween::LINEAR),
725      animation_id_(cc::AnimationIdProvider::NextAnimationId()),
726      animation_group_id_(0),
727      last_progressed_fraction_(0.0),
728      weak_ptr_factory_(this) {
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      weak_ptr_factory_(this) {
741}
742
743LayerAnimationElement::~LayerAnimationElement() {
744}
745
746void LayerAnimationElement::Start(LayerAnimationDelegate* delegate,
747                                  int animation_group_id) {
748  DCHECK(requested_start_time_ != base::TimeTicks());
749  DCHECK(first_frame_);
750  animation_group_id_ = animation_group_id;
751  last_progressed_fraction_ = 0.0;
752  OnStart(delegate);
753  RequestEffectiveStart(delegate);
754  first_frame_ = false;
755}
756
757bool LayerAnimationElement::Progress(base::TimeTicks now,
758                                     LayerAnimationDelegate* delegate) {
759  DCHECK(requested_start_time_ != base::TimeTicks());
760  DCHECK(!first_frame_);
761
762  bool need_draw;
763  double t = 1.0;
764
765  if ((effective_start_time_ == base::TimeTicks()) ||
766      (now < effective_start_time_))  {
767    // This hasn't actually started yet.
768    need_draw = false;
769    last_progressed_fraction_ = 0.0;
770    return need_draw;
771  }
772
773  base::TimeDelta elapsed = now - effective_start_time_;
774  if ((duration_ > base::TimeDelta()) && (elapsed < duration_))
775    t = elapsed.InMillisecondsF() / duration_.InMillisecondsF();
776  base::WeakPtr<LayerAnimationElement> alive(weak_ptr_factory_.GetWeakPtr());
777  need_draw = OnProgress(gfx::Tween::CalculateValue(tween_type_, t), delegate);
778  if (!alive)
779    return need_draw;
780  first_frame_ = t == 1.0;
781  last_progressed_fraction_ = t;
782  return need_draw;
783}
784
785bool LayerAnimationElement::IsFinished(base::TimeTicks time,
786                                       base::TimeDelta* total_duration) {
787  // If an effective start has been requested but the effective start time
788  // hasn't yet been set, the animation is not finished, regardless of the
789  // value of |time|.
790  if (!first_frame_ && (effective_start_time_ == base::TimeTicks()))
791    return false;
792
793  base::TimeDelta queueing_delay;
794  if (!first_frame_)
795    queueing_delay = effective_start_time_ - requested_start_time_;
796
797  base::TimeDelta elapsed = time - requested_start_time_;
798  if (elapsed >= duration_ + queueing_delay) {
799    *total_duration = duration_ + queueing_delay;
800    return true;
801  }
802  return false;
803}
804
805bool LayerAnimationElement::ProgressToEnd(LayerAnimationDelegate* delegate) {
806  if (first_frame_)
807    OnStart(delegate);
808  base::WeakPtr<LayerAnimationElement> alive(weak_ptr_factory_.GetWeakPtr());
809  bool need_draw = OnProgress(1.0, delegate);
810  if (!alive)
811    return need_draw;
812  last_progressed_fraction_ = 1.0;
813  first_frame_ = true;
814  return need_draw;
815}
816
817void LayerAnimationElement::GetTargetValue(TargetValue* target) const {
818  OnGetTarget(target);
819}
820
821bool LayerAnimationElement::IsThreaded() const {
822  return false;
823}
824
825void LayerAnimationElement::Abort(LayerAnimationDelegate* delegate) {
826  OnAbort(delegate);
827  first_frame_ = true;
828}
829
830void LayerAnimationElement::RequestEffectiveStart(
831    LayerAnimationDelegate* delegate) {
832  DCHECK(requested_start_time_ != base::TimeTicks());
833  effective_start_time_ = requested_start_time_;
834}
835
836// static
837LayerAnimationElement::AnimatableProperty
838LayerAnimationElement::ToAnimatableProperty(
839    cc::Animation::TargetProperty property) {
840  switch (property) {
841    case cc::Animation::Transform:
842      return TRANSFORM;
843    case cc::Animation::Opacity:
844      return OPACITY;
845    default:
846      NOTREACHED();
847      return AnimatableProperty();
848  }
849}
850
851// static
852base::TimeDelta LayerAnimationElement::GetEffectiveDuration(
853    const base::TimeDelta& duration) {
854  switch (ScopedAnimationDurationScaleMode::duration_scale_mode()) {
855    case ScopedAnimationDurationScaleMode::NORMAL_DURATION:
856      return duration;
857    case ScopedAnimationDurationScaleMode::FAST_DURATION:
858      return duration / kFastDurationScaleFactor;
859    case ScopedAnimationDurationScaleMode::SLOW_DURATION:
860      return duration * kSlowDurationScaleFactor;
861    case ScopedAnimationDurationScaleMode::ZERO_DURATION:
862      return base::TimeDelta();
863    default:
864      NOTREACHED();
865      return base::TimeDelta();
866  }
867}
868
869// static
870LayerAnimationElement* LayerAnimationElement::CreateTransformElement(
871    const gfx::Transform& transform,
872    base::TimeDelta duration) {
873  return new ThreadedTransformTransition(transform, duration);
874}
875
876// static
877LayerAnimationElement* LayerAnimationElement::CreateInverseTransformElement(
878    const gfx::Transform& base_transform,
879    const LayerAnimationElement* uninverted_transition) {
880  return new InverseTransformTransition(base_transform, uninverted_transition);
881}
882
883// static
884LayerAnimationElement* LayerAnimationElement::CloneInverseTransformElement(
885    const LayerAnimationElement* other) {
886  return InverseTransformTransition::Clone(other);
887}
888
889// static
890LayerAnimationElement*
891LayerAnimationElement::CreateInterpolatedTransformElement(
892    InterpolatedTransform* interpolated_transform,
893    base::TimeDelta duration) {
894  return new InterpolatedTransformTransition(interpolated_transform, duration);
895}
896
897// static
898LayerAnimationElement* LayerAnimationElement::CreateBoundsElement(
899    const gfx::Rect& bounds,
900    base::TimeDelta duration) {
901  return new BoundsTransition(bounds, duration);
902}
903
904// static
905LayerAnimationElement* LayerAnimationElement::CreateOpacityElement(
906    float opacity,
907    base::TimeDelta duration) {
908  return new ThreadedOpacityTransition(opacity, duration);
909}
910
911// static
912LayerAnimationElement* LayerAnimationElement::CreateVisibilityElement(
913    bool visibility,
914    base::TimeDelta duration) {
915  return new VisibilityTransition(visibility, duration);
916}
917
918// static
919LayerAnimationElement* LayerAnimationElement::CreateBrightnessElement(
920    float brightness,
921    base::TimeDelta duration) {
922  return new BrightnessTransition(brightness, duration);
923}
924
925// static
926LayerAnimationElement* LayerAnimationElement::CreateGrayscaleElement(
927    float grayscale,
928    base::TimeDelta duration) {
929  return new GrayscaleTransition(grayscale, duration);
930}
931
932// static
933LayerAnimationElement* LayerAnimationElement::CreatePauseElement(
934    const AnimatableProperties& properties,
935    base::TimeDelta duration) {
936  return new Pause(properties, duration);
937}
938
939// static
940LayerAnimationElement* LayerAnimationElement::CreateColorElement(
941    SkColor color,
942    base::TimeDelta duration) {
943  return new ColorTransition(color, duration);
944}
945
946}  // namespace ui
947