layer_animation_element.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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  virtual bool OnProgress(double t,
398                          LayerAnimationDelegate* delegate) OVERRIDE {
399    if (t < 1.0)
400      return false;
401
402    if (Started()) {
403      delegate->RemoveThreadedAnimation(animation_id());
404    }
405
406    OnEnd(delegate);
407    return true;
408  }
409
410  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {
411    if (delegate && Started()) {
412      delegate->RemoveThreadedAnimation(animation_id());
413    }
414  }
415
416  virtual void RequestEffectiveStart(
417      LayerAnimationDelegate* delegate) OVERRIDE {
418    DCHECK(animation_group_id());
419    if (duration() == base::TimeDelta()) {
420      set_effective_start_time(requested_start_time());
421      return;
422    }
423    set_effective_start_time(base::TimeTicks());
424    scoped_ptr<cc::Animation> animation = CreateCCAnimation();
425    animation->set_needs_synchronized_start_time(true);
426    delegate->AddThreadedAnimation(animation.Pass());
427  }
428
429  virtual void OnEnd(LayerAnimationDelegate* delegate) = 0;
430
431  virtual scoped_ptr<cc::Animation> CreateCCAnimation() = 0;
432
433 private:
434  DISALLOW_COPY_AND_ASSIGN(ThreadedLayerAnimationElement);
435};
436
437// ThreadedOpacityTransition ---------------------------------------------------
438
439class ThreadedOpacityTransition : public ThreadedLayerAnimationElement {
440 public:
441  ThreadedOpacityTransition(float target, base::TimeDelta duration)
442      : ThreadedLayerAnimationElement(GetProperties(), duration),
443        start_(0.0f),
444        target_(target) {
445  }
446  virtual ~ThreadedOpacityTransition() {}
447
448 protected:
449  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
450    start_ = delegate->GetOpacityForAnimation();
451  }
452
453  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {
454    if (delegate && Started()) {
455      ThreadedLayerAnimationElement::OnAbort(delegate);
456      delegate->SetOpacityFromAnimation(Tween::ValueBetween(
457            Tween::CalculateValue(tween_type(), last_progressed_fraction()),
458            start_,
459            target_));
460    }
461  }
462
463  virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE {
464    delegate->SetOpacityFromAnimation(target_);
465  }
466
467  virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE {
468    scoped_ptr<cc::AnimationCurve> animation_curve(
469        new FloatAnimationCurveAdapter(tween_type(),
470                                       start_,
471                                       target_,
472                                       duration()));
473    scoped_ptr<cc::Animation> animation(
474        cc::Animation::Create(animation_curve.Pass(),
475                              animation_id(),
476                              animation_group_id(),
477                              cc::Animation::Opacity));
478    return animation.Pass();
479  }
480
481  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
482    target->opacity = target_;
483  }
484
485 private:
486  static AnimatableProperties GetProperties() {
487    AnimatableProperties properties;
488    properties.insert(LayerAnimationElement::OPACITY);
489    return properties;
490  }
491
492  float start_;
493  const float target_;
494
495  DISALLOW_COPY_AND_ASSIGN(ThreadedOpacityTransition);
496};
497
498// ThreadedTransformTransition -------------------------------------------------
499
500class ThreadedTransformTransition : public ThreadedLayerAnimationElement {
501 public:
502  ThreadedTransformTransition(const gfx::Transform& target,
503                              base::TimeDelta duration)
504      : ThreadedLayerAnimationElement(GetProperties(), duration),
505        target_(target) {
506  }
507  virtual ~ThreadedTransformTransition() {}
508
509 protected:
510  virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
511    start_ = delegate->GetTransformForAnimation();
512    float device_scale_factor = delegate->GetDeviceScaleFactor();
513    cc_start_ = Layer::ConvertTransformToCCTransform(start_,
514                                                     device_scale_factor);
515    cc_target_ = Layer::ConvertTransformToCCTransform(target_,
516                                                      device_scale_factor);
517  }
518
519  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {
520    if (delegate && animation_id()) {
521      ThreadedLayerAnimationElement::OnAbort(delegate);
522      delegate->SetTransformFromAnimation(Tween::ValueBetween(
523          Tween::CalculateValue(tween_type(), last_progressed_fraction()),
524          start_,
525          target_));
526    }
527  }
528
529  virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE {
530    delegate->SetTransformFromAnimation(target_);
531  }
532
533  virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE {
534    scoped_ptr<cc::AnimationCurve> animation_curve(
535        new TransformAnimationCurveAdapter(tween_type(),
536                                           cc_start_,
537                                           cc_target_,
538                                           duration()));
539    scoped_ptr<cc::Animation> animation(
540        cc::Animation::Create(animation_curve.Pass(),
541                              animation_id(),
542                              animation_group_id(),
543                              cc::Animation::Transform));
544    return animation.Pass();
545  }
546
547  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
548    target->transform = target_;
549  }
550
551 private:
552  static AnimatableProperties GetProperties() {
553    AnimatableProperties properties;
554    properties.insert(LayerAnimationElement::TRANSFORM);
555    return properties;
556  }
557
558  gfx::Transform start_;
559  gfx::Transform cc_start_;
560  const gfx::Transform target_;
561  gfx::Transform cc_target_;
562
563  DISALLOW_COPY_AND_ASSIGN(ThreadedTransformTransition);
564};
565
566}  // namespace
567
568// LayerAnimationElement::TargetValue ------------------------------------------
569
570LayerAnimationElement::TargetValue::TargetValue()
571    : opacity(0.0f),
572      visibility(false),
573      brightness(0.0f),
574      grayscale(0.0f),
575      color(SK_ColorBLACK) {
576}
577
578LayerAnimationElement::TargetValue::TargetValue(
579    const LayerAnimationDelegate* delegate)
580    : bounds(delegate ? delegate->GetBoundsForAnimation() : gfx::Rect()),
581      transform(delegate ?
582                delegate->GetTransformForAnimation() : gfx::Transform()),
583      opacity(delegate ? delegate->GetOpacityForAnimation() : 0.0f),
584      visibility(delegate ? delegate->GetVisibilityForAnimation() : false),
585      brightness(delegate ? delegate->GetBrightnessForAnimation() : 0.0f),
586      grayscale(delegate ? delegate->GetGrayscaleForAnimation() : 0.0f),
587      color(delegate ? delegate->GetColorForAnimation() : 0.0f) {
588}
589
590// LayerAnimationElement -------------------------------------------------------
591
592LayerAnimationElement::LayerAnimationElement(
593    const AnimatableProperties& properties,
594    base::TimeDelta duration)
595    : first_frame_(true),
596      properties_(properties),
597      duration_(GetEffectiveDuration(duration)),
598      tween_type_(Tween::LINEAR),
599      animation_id_(cc::AnimationIdProvider::NextAnimationId()),
600      animation_group_id_(0),
601      last_progressed_fraction_(0.0) {
602}
603
604LayerAnimationElement::~LayerAnimationElement() {
605}
606
607void LayerAnimationElement::Start(LayerAnimationDelegate* delegate,
608                                  int animation_group_id) {
609  DCHECK(requested_start_time_ != base::TimeTicks());
610  DCHECK(first_frame_);
611  animation_group_id_ = animation_group_id;
612  last_progressed_fraction_ = 0.0;
613  OnStart(delegate);
614  RequestEffectiveStart(delegate);
615  first_frame_ = false;
616}
617
618bool LayerAnimationElement::Progress(base::TimeTicks now,
619                                     LayerAnimationDelegate* delegate) {
620  DCHECK(requested_start_time_ != base::TimeTicks());
621  DCHECK(!first_frame_);
622
623  bool need_draw;
624  double t = 1.0;
625
626  if ((effective_start_time_ == base::TimeTicks()) ||
627      (now < effective_start_time_))  {
628    // This hasn't actually started yet.
629    need_draw = false;
630    last_progressed_fraction_ = 0.0;
631    return need_draw;
632  }
633
634  base::TimeDelta elapsed = now - effective_start_time_;
635  if ((duration_ > base::TimeDelta()) && (elapsed < duration_))
636    t = elapsed.InMillisecondsF() / duration_.InMillisecondsF();
637  need_draw = OnProgress(Tween::CalculateValue(tween_type_, t), delegate);
638  first_frame_ = t == 1.0;
639  last_progressed_fraction_ = t;
640  return need_draw;
641}
642
643bool LayerAnimationElement::IsFinished(base::TimeTicks time,
644                                       base::TimeDelta* total_duration) {
645  // If an effective start has been requested but the effective start time
646  // hasn't yet been set, the animation is not finished, regardless of the
647  // value of |time|.
648  if (!first_frame_ && (effective_start_time_ == base::TimeTicks()))
649    return false;
650
651  base::TimeDelta queueing_delay;
652  if (!first_frame_)
653    queueing_delay = effective_start_time_ - requested_start_time_;
654
655  base::TimeDelta elapsed = time - requested_start_time_;
656  if (elapsed >= duration_ + queueing_delay) {
657    *total_duration = duration_ + queueing_delay;
658    return true;
659  }
660  return false;
661}
662
663bool LayerAnimationElement::ProgressToEnd(LayerAnimationDelegate* delegate) {
664  if (first_frame_)
665    OnStart(delegate);
666  bool need_draw = OnProgress(1.0, delegate);
667  last_progressed_fraction_ = 1.0;
668  first_frame_ = true;
669  return need_draw;
670}
671
672void LayerAnimationElement::GetTargetValue(TargetValue* target) const {
673  OnGetTarget(target);
674}
675
676bool LayerAnimationElement::IsThreaded() const {
677  return false;
678}
679
680void LayerAnimationElement::Abort(LayerAnimationDelegate* delegate) {
681  OnAbort(delegate);
682  first_frame_ = true;
683}
684
685void LayerAnimationElement::RequestEffectiveStart(
686    LayerAnimationDelegate* delegate) {
687  DCHECK(requested_start_time_ != base::TimeTicks());
688  effective_start_time_ = requested_start_time_;
689}
690
691// static
692LayerAnimationElement::AnimatableProperty
693LayerAnimationElement::ToAnimatableProperty(
694    cc::Animation::TargetProperty property) {
695  switch (property) {
696    case cc::Animation::Transform:
697      return TRANSFORM;
698    case cc::Animation::Opacity:
699      return OPACITY;
700    default:
701      NOTREACHED();
702      return AnimatableProperty();
703  }
704}
705
706// static
707base::TimeDelta LayerAnimationElement::GetEffectiveDuration(
708    const base::TimeDelta& duration) {
709  switch (ScopedAnimationDurationScaleMode::duration_scale_mode()) {
710    case ScopedAnimationDurationScaleMode::NORMAL_DURATION:
711      return duration;
712    case ScopedAnimationDurationScaleMode::FAST_DURATION:
713      return duration / kFastDurationScaleFactor;
714    case ScopedAnimationDurationScaleMode::SLOW_DURATION:
715      return duration * kSlowDurationScaleFactor;
716    case ScopedAnimationDurationScaleMode::ZERO_DURATION:
717      return base::TimeDelta();
718    default:
719      NOTREACHED();
720      return base::TimeDelta();
721  }
722}
723
724// static
725LayerAnimationElement* LayerAnimationElement::CreateTransformElement(
726    const gfx::Transform& transform,
727    base::TimeDelta duration) {
728  return new ThreadedTransformTransition(transform, duration);
729}
730
731// static
732LayerAnimationElement*
733LayerAnimationElement::CreateInterpolatedTransformElement(
734    InterpolatedTransform* interpolated_transform,
735    base::TimeDelta duration) {
736  return new InterpolatedTransformTransition(interpolated_transform, duration);
737}
738
739// static
740LayerAnimationElement* LayerAnimationElement::CreateBoundsElement(
741    const gfx::Rect& bounds,
742    base::TimeDelta duration) {
743  return new BoundsTransition(bounds, duration);
744}
745
746// static
747LayerAnimationElement* LayerAnimationElement::CreateOpacityElement(
748    float opacity,
749    base::TimeDelta duration) {
750  return new ThreadedOpacityTransition(opacity, duration);
751}
752
753// static
754LayerAnimationElement* LayerAnimationElement::CreateVisibilityElement(
755    bool visibility,
756    base::TimeDelta duration) {
757  return new VisibilityTransition(visibility, duration);
758}
759
760// static
761LayerAnimationElement* LayerAnimationElement::CreateBrightnessElement(
762    float brightness,
763    base::TimeDelta duration) {
764  return new BrightnessTransition(brightness, duration);
765}
766
767// static
768LayerAnimationElement* LayerAnimationElement::CreateGrayscaleElement(
769    float grayscale,
770    base::TimeDelta duration) {
771  return new GrayscaleTransition(grayscale, duration);
772}
773
774// static
775LayerAnimationElement* LayerAnimationElement::CreatePauseElement(
776    const AnimatableProperties& properties,
777    base::TimeDelta duration) {
778  return new Pause(properties, duration);
779}
780
781// static
782LayerAnimationElement* LayerAnimationElement::CreateColorElement(
783    SkColor color,
784    base::TimeDelta duration) {
785  return new ColorTransition(color, duration);
786}
787
788}  // namespace ui
789