layer_animation_element.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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    gfx::Rect bounds = delegate->GetBoundsForAnimation();
513    float device_scale_factor = delegate->GetDeviceScaleFactor();
514    cc_start_ = Layer::ConvertTransformToCCTransform(start_,
515                                                     bounds,
516                                                     device_scale_factor);
517    cc_target_ = Layer::ConvertTransformToCCTransform(target_,
518                                                      bounds,
519                                                      device_scale_factor);
520  }
521
522  virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {
523    if (delegate && animation_id()) {
524      ThreadedLayerAnimationElement::OnAbort(delegate);
525      delegate->SetTransformFromAnimation(Tween::ValueBetween(
526          Tween::CalculateValue(tween_type(), last_progressed_fraction()),
527          start_,
528          target_));
529    }
530  }
531
532  virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE {
533    delegate->SetTransformFromAnimation(target_);
534  }
535
536  virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE {
537    scoped_ptr<cc::AnimationCurve> animation_curve(
538        new TransformAnimationCurveAdapter(tween_type(),
539                                           cc_start_,
540                                           cc_target_,
541                                           duration()));
542    scoped_ptr<cc::Animation> animation(
543        cc::Animation::Create(animation_curve.Pass(),
544                              animation_id(),
545                              animation_group_id(),
546                              cc::Animation::Transform));
547    return animation.Pass();
548  }
549
550  virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
551    target->transform = target_;
552  }
553
554 private:
555  static AnimatableProperties GetProperties() {
556    AnimatableProperties properties;
557    properties.insert(LayerAnimationElement::TRANSFORM);
558    return properties;
559  }
560
561  gfx::Transform start_;
562  gfx::Transform cc_start_;
563  const gfx::Transform target_;
564  gfx::Transform cc_target_;
565
566  DISALLOW_COPY_AND_ASSIGN(ThreadedTransformTransition);
567};
568
569}  // namespace
570
571// LayerAnimationElement::TargetValue ------------------------------------------
572
573LayerAnimationElement::TargetValue::TargetValue()
574    : opacity(0.0f),
575      visibility(false),
576      brightness(0.0f),
577      grayscale(0.0f),
578      color(SK_ColorBLACK) {
579}
580
581LayerAnimationElement::TargetValue::TargetValue(
582    const LayerAnimationDelegate* delegate)
583    : bounds(delegate ? delegate->GetBoundsForAnimation() : gfx::Rect()),
584      transform(delegate ?
585                delegate->GetTransformForAnimation() : gfx::Transform()),
586      opacity(delegate ? delegate->GetOpacityForAnimation() : 0.0f),
587      visibility(delegate ? delegate->GetVisibilityForAnimation() : false),
588      brightness(delegate ? delegate->GetBrightnessForAnimation() : 0.0f),
589      grayscale(delegate ? delegate->GetGrayscaleForAnimation() : 0.0f),
590      color(delegate ? delegate->GetColorForAnimation() : 0.0f) {
591}
592
593// LayerAnimationElement -------------------------------------------------------
594
595LayerAnimationElement::LayerAnimationElement(
596    const AnimatableProperties& properties,
597    base::TimeDelta duration)
598    : first_frame_(true),
599      properties_(properties),
600      duration_(GetEffectiveDuration(duration)),
601      tween_type_(Tween::LINEAR),
602      animation_id_(cc::AnimationIdProvider::NextAnimationId()),
603      animation_group_id_(0),
604      last_progressed_fraction_(0.0) {
605}
606
607LayerAnimationElement::~LayerAnimationElement() {
608}
609
610void LayerAnimationElement::Start(LayerAnimationDelegate* delegate,
611                                  int animation_group_id) {
612  DCHECK(requested_start_time_ != base::TimeTicks());
613  DCHECK(first_frame_);
614  animation_group_id_ = animation_group_id;
615  last_progressed_fraction_ = 0.0;
616  OnStart(delegate);
617  RequestEffectiveStart(delegate);
618  first_frame_ = false;
619}
620
621bool LayerAnimationElement::Progress(base::TimeTicks now,
622                                     LayerAnimationDelegate* delegate) {
623  DCHECK(requested_start_time_ != base::TimeTicks());
624  DCHECK(!first_frame_);
625
626  bool need_draw;
627  double t = 1.0;
628
629  if (effective_start_time_ == base::TimeTicks()) {
630    // This hasn't actually started yet.
631    need_draw = false;
632    last_progressed_fraction_ = 0.0;
633    return need_draw;
634  }
635
636  base::TimeDelta elapsed = now - effective_start_time_;
637  if ((duration_ > base::TimeDelta()) && (elapsed < duration_))
638    t = elapsed.InMillisecondsF() / duration_.InMillisecondsF();
639  need_draw = OnProgress(Tween::CalculateValue(tween_type_, t), delegate);
640  first_frame_ = t == 1.0;
641  last_progressed_fraction_ = t;
642  return need_draw;
643}
644
645bool LayerAnimationElement::IsFinished(base::TimeTicks time,
646                                       base::TimeDelta* total_duration) {
647  // If an effective start has been requested but the effective start time
648  // hasn't yet been set, the animation is not finished, regardless of the
649  // value of |time|.
650  if (!first_frame_ && (effective_start_time_ == base::TimeTicks()))
651    return false;
652
653  base::TimeDelta queueing_delay;
654  if (!first_frame_)
655    queueing_delay = effective_start_time_ - requested_start_time_;
656
657  base::TimeDelta elapsed = time - requested_start_time_;
658  if (elapsed >= duration_ + queueing_delay) {
659    *total_duration = duration_ + queueing_delay;
660    return true;
661  }
662  return false;
663}
664
665bool LayerAnimationElement::ProgressToEnd(LayerAnimationDelegate* delegate) {
666  if (first_frame_)
667    OnStart(delegate);
668  bool need_draw = OnProgress(1.0, delegate);
669  last_progressed_fraction_ = 1.0;
670  first_frame_ = true;
671  return need_draw;
672}
673
674void LayerAnimationElement::GetTargetValue(TargetValue* target) const {
675  OnGetTarget(target);
676}
677
678bool LayerAnimationElement::IsThreaded() const {
679  return false;
680}
681
682void LayerAnimationElement::Abort(LayerAnimationDelegate* delegate) {
683  OnAbort(delegate);
684  first_frame_ = true;
685}
686
687void LayerAnimationElement::RequestEffectiveStart(
688    LayerAnimationDelegate* delegate) {
689  DCHECK(requested_start_time_ != base::TimeTicks());
690  effective_start_time_ = requested_start_time_;
691}
692
693// static
694LayerAnimationElement::AnimatableProperty
695LayerAnimationElement::ToAnimatableProperty(
696    cc::Animation::TargetProperty property) {
697  switch (property) {
698    case cc::Animation::Transform:
699      return TRANSFORM;
700    case cc::Animation::Opacity:
701      return OPACITY;
702    default:
703      NOTREACHED();
704      return AnimatableProperty();
705  }
706}
707
708// static
709base::TimeDelta LayerAnimationElement::GetEffectiveDuration(
710    const base::TimeDelta& duration) {
711  switch (ScopedAnimationDurationScaleMode::duration_scale_mode()) {
712    case ScopedAnimationDurationScaleMode::NORMAL_DURATION:
713      return duration;
714    case ScopedAnimationDurationScaleMode::FAST_DURATION:
715      return duration / kFastDurationScaleFactor;
716    case ScopedAnimationDurationScaleMode::SLOW_DURATION:
717      return duration * kSlowDurationScaleFactor;
718    case ScopedAnimationDurationScaleMode::ZERO_DURATION:
719      return base::TimeDelta();
720    default:
721      NOTREACHED();
722      return base::TimeDelta();
723  }
724}
725
726// static
727LayerAnimationElement* LayerAnimationElement::CreateTransformElement(
728    const gfx::Transform& transform,
729    base::TimeDelta duration) {
730  return new ThreadedTransformTransition(transform, duration);
731}
732
733// static
734LayerAnimationElement*
735LayerAnimationElement::CreateInterpolatedTransformElement(
736    InterpolatedTransform* interpolated_transform,
737    base::TimeDelta duration) {
738  return new InterpolatedTransformTransition(interpolated_transform, duration);
739}
740
741// static
742LayerAnimationElement* LayerAnimationElement::CreateBoundsElement(
743    const gfx::Rect& bounds,
744    base::TimeDelta duration) {
745  return new BoundsTransition(bounds, duration);
746}
747
748// static
749LayerAnimationElement* LayerAnimationElement::CreateOpacityElement(
750    float opacity,
751    base::TimeDelta duration) {
752  return new ThreadedOpacityTransition(opacity, duration);
753}
754
755// static
756LayerAnimationElement* LayerAnimationElement::CreateVisibilityElement(
757    bool visibility,
758    base::TimeDelta duration) {
759  return new VisibilityTransition(visibility, duration);
760}
761
762// static
763LayerAnimationElement* LayerAnimationElement::CreateBrightnessElement(
764    float brightness,
765    base::TimeDelta duration) {
766  return new BrightnessTransition(brightness, duration);
767}
768
769// static
770LayerAnimationElement* LayerAnimationElement::CreateGrayscaleElement(
771    float grayscale,
772    base::TimeDelta duration) {
773  return new GrayscaleTransition(grayscale, duration);
774}
775
776// static
777LayerAnimationElement* LayerAnimationElement::CreatePauseElement(
778    const AnimatableProperties& properties,
779    base::TimeDelta duration) {
780  return new Pause(properties, duration);
781}
782
783// static
784LayerAnimationElement* LayerAnimationElement::CreateColorElement(
785    SkColor color,
786    base::TimeDelta duration) {
787  return new ColorTransition(color, duration);
788}
789
790}  // namespace ui
791