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.
5 #include "ui/compositor/layer_animation_element.h"
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"
23 // The factor by which duration is scaled up or down when using
24 // ScopedAnimationDurationScaleMode.
25 const int kSlowDurationScaleMultiplier
= 4;
26 const int kFastDurationScaleDivisor
= 4;
27 const int kNonZeroDurationScaleDivisor
= 20;
29 // Pause -----------------------------------------------------------------------
30 class Pause
: public LayerAnimationElement
{
32 Pause(AnimatableProperties properties
, base::TimeDelta duration
)
33 : LayerAnimationElement(properties
, duration
) {
38 void OnStart(LayerAnimationDelegate
* delegate
) override
{}
39 bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) override
{
42 void OnGetTarget(TargetValue
* target
) const override
{}
43 void OnAbort(LayerAnimationDelegate
* delegate
) override
{}
45 DISALLOW_COPY_AND_ASSIGN(Pause
);
48 // TransformTransition ---------------------------------------------------------
50 class TransformTransition
: public LayerAnimationElement
{
52 TransformTransition(const gfx::Transform
& target
, base::TimeDelta duration
)
53 : LayerAnimationElement(TRANSFORM
, duration
),
56 ~TransformTransition() override
{}
59 void OnStart(LayerAnimationDelegate
* delegate
) override
{
60 start_
= delegate
->GetTransformForAnimation();
63 bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) override
{
64 delegate
->SetTransformFromAnimation(
65 gfx::Tween::TransformValueBetween(t
, start_
, target_
));
69 void OnGetTarget(TargetValue
* target
) const override
{
70 target
->transform
= target_
;
73 void OnAbort(LayerAnimationDelegate
* delegate
) override
{}
76 gfx::Transform start_
;
77 const gfx::Transform target_
;
79 DISALLOW_COPY_AND_ASSIGN(TransformTransition
);
82 // InterpolatedTransformTransition ---------------------------------------------
84 class InterpolatedTransformTransition
: public LayerAnimationElement
{
86 InterpolatedTransformTransition(InterpolatedTransform
* interpolated_transform
,
87 base::TimeDelta duration
)
88 : LayerAnimationElement(TRANSFORM
, duration
),
89 interpolated_transform_(interpolated_transform
) {
91 ~InterpolatedTransformTransition() override
{}
94 void OnStart(LayerAnimationDelegate
* delegate
) override
{}
96 bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) override
{
97 delegate
->SetTransformFromAnimation(
98 interpolated_transform_
->Interpolate(static_cast<float>(t
)));
102 void OnGetTarget(TargetValue
* target
) const override
{
103 target
->transform
= interpolated_transform_
->Interpolate(1.0f
);
106 void OnAbort(LayerAnimationDelegate
* delegate
) override
{}
109 scoped_ptr
<InterpolatedTransform
> interpolated_transform_
;
111 DISALLOW_COPY_AND_ASSIGN(InterpolatedTransformTransition
);
114 // BoundsTransition ------------------------------------------------------------
116 class BoundsTransition
: public LayerAnimationElement
{
118 BoundsTransition(const gfx::Rect
& target
, base::TimeDelta duration
)
119 : LayerAnimationElement(BOUNDS
, duration
),
122 ~BoundsTransition() override
{}
125 void OnStart(LayerAnimationDelegate
* delegate
) override
{
126 start_
= delegate
->GetBoundsForAnimation();
129 bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) override
{
130 delegate
->SetBoundsFromAnimation(
131 gfx::Tween::RectValueBetween(t
, start_
, target_
));
135 void OnGetTarget(TargetValue
* target
) const override
{
136 target
->bounds
= target_
;
139 void OnAbort(LayerAnimationDelegate
* delegate
) override
{}
143 const gfx::Rect target_
;
145 DISALLOW_COPY_AND_ASSIGN(BoundsTransition
);
148 // OpacityTransition -----------------------------------------------------------
150 class OpacityTransition
: public LayerAnimationElement
{
152 OpacityTransition(float target
, base::TimeDelta duration
)
153 : LayerAnimationElement(OPACITY
, duration
),
157 ~OpacityTransition() override
{}
160 void OnStart(LayerAnimationDelegate
* delegate
) override
{
161 start_
= delegate
->GetOpacityForAnimation();
164 bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) override
{
165 delegate
->SetOpacityFromAnimation(
166 gfx::Tween::FloatValueBetween(t
, start_
, target_
));
170 void OnGetTarget(TargetValue
* target
) const override
{
171 target
->opacity
= target_
;
174 void OnAbort(LayerAnimationDelegate
* delegate
) override
{}
180 DISALLOW_COPY_AND_ASSIGN(OpacityTransition
);
183 // VisibilityTransition --------------------------------------------------------
185 class VisibilityTransition
: public LayerAnimationElement
{
187 VisibilityTransition(bool target
, base::TimeDelta duration
)
188 : LayerAnimationElement(VISIBILITY
, duration
),
192 ~VisibilityTransition() override
{}
195 void OnStart(LayerAnimationDelegate
* delegate
) override
{
196 start_
= delegate
->GetVisibilityForAnimation();
199 bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) override
{
200 delegate
->SetVisibilityFromAnimation(t
== 1.0 ? target_
: start_
);
204 void OnGetTarget(TargetValue
* target
) const override
{
205 target
->visibility
= target_
;
208 void OnAbort(LayerAnimationDelegate
* delegate
) override
{}
214 DISALLOW_COPY_AND_ASSIGN(VisibilityTransition
);
217 // BrightnessTransition --------------------------------------------------------
219 class BrightnessTransition
: public LayerAnimationElement
{
221 BrightnessTransition(float target
, base::TimeDelta duration
)
222 : LayerAnimationElement(BRIGHTNESS
, duration
),
226 ~BrightnessTransition() override
{}
229 void OnStart(LayerAnimationDelegate
* delegate
) override
{
230 start_
= delegate
->GetBrightnessForAnimation();
233 bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) override
{
234 delegate
->SetBrightnessFromAnimation(
235 gfx::Tween::FloatValueBetween(t
, start_
, target_
));
239 void OnGetTarget(TargetValue
* target
) const override
{
240 target
->brightness
= target_
;
243 void OnAbort(LayerAnimationDelegate
* delegate
) override
{}
249 DISALLOW_COPY_AND_ASSIGN(BrightnessTransition
);
252 // GrayscaleTransition ---------------------------------------------------------
254 class GrayscaleTransition
: public LayerAnimationElement
{
256 GrayscaleTransition(float target
, base::TimeDelta duration
)
257 : LayerAnimationElement(GRAYSCALE
, duration
),
261 ~GrayscaleTransition() override
{}
264 void OnStart(LayerAnimationDelegate
* delegate
) override
{
265 start_
= delegate
->GetGrayscaleForAnimation();
268 bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) override
{
269 delegate
->SetGrayscaleFromAnimation(
270 gfx::Tween::FloatValueBetween(t
, start_
, target_
));
274 void OnGetTarget(TargetValue
* target
) const override
{
275 target
->grayscale
= target_
;
278 void OnAbort(LayerAnimationDelegate
* delegate
) override
{}
284 DISALLOW_COPY_AND_ASSIGN(GrayscaleTransition
);
287 // ColorTransition -------------------------------------------------------------
289 class ColorTransition
: public LayerAnimationElement
{
291 ColorTransition(SkColor target
, base::TimeDelta duration
)
292 : LayerAnimationElement(COLOR
, duration
),
293 start_(SK_ColorBLACK
),
296 ~ColorTransition() override
{}
299 void OnStart(LayerAnimationDelegate
* delegate
) override
{
300 start_
= delegate
->GetColorForAnimation();
303 bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) override
{
304 delegate
->SetColorFromAnimation(
305 gfx::Tween::ColorValueBetween(t
, start_
, target_
));
309 void OnGetTarget(TargetValue
* target
) const override
{
310 target
->color
= target_
;
313 void OnAbort(LayerAnimationDelegate
* delegate
) override
{}
317 const SkColor target_
;
319 DISALLOW_COPY_AND_ASSIGN(ColorTransition
);
322 // ThreadedLayerAnimationElement -----------------------------------------------
324 class ThreadedLayerAnimationElement
: public LayerAnimationElement
{
326 ThreadedLayerAnimationElement(AnimatableProperties properties
,
327 base::TimeDelta duration
)
328 : LayerAnimationElement(properties
, duration
) {
330 ~ThreadedLayerAnimationElement() override
{}
332 bool IsThreaded() const override
{ return (duration() != base::TimeDelta()); }
335 explicit ThreadedLayerAnimationElement(const LayerAnimationElement
& element
)
336 : LayerAnimationElement(element
) {
339 bool OnProgress(double t
, LayerAnimationDelegate
* delegate
) override
{
344 delegate
->RemoveThreadedAnimation(animation_id());
351 void OnAbort(LayerAnimationDelegate
* delegate
) override
{
352 if (delegate
&& Started()) {
353 delegate
->RemoveThreadedAnimation(animation_id());
357 void RequestEffectiveStart(LayerAnimationDelegate
* delegate
) override
{
358 DCHECK(animation_group_id());
359 if (duration() == base::TimeDelta()) {
360 set_effective_start_time(requested_start_time());
363 set_effective_start_time(base::TimeTicks());
364 scoped_ptr
<cc::Animation
> animation
= CreateCCAnimation();
365 animation
->set_needs_synchronized_start_time(true);
366 delegate
->AddThreadedAnimation(animation
.Pass());
369 virtual void OnEnd(LayerAnimationDelegate
* delegate
) = 0;
371 virtual scoped_ptr
<cc::Animation
> CreateCCAnimation() = 0;
374 DISALLOW_COPY_AND_ASSIGN(ThreadedLayerAnimationElement
);
377 // ThreadedOpacityTransition ---------------------------------------------------
379 class ThreadedOpacityTransition
: public ThreadedLayerAnimationElement
{
381 ThreadedOpacityTransition(float target
, base::TimeDelta duration
)
382 : ThreadedLayerAnimationElement(OPACITY
, duration
),
386 ~ThreadedOpacityTransition() override
{}
389 void OnStart(LayerAnimationDelegate
* delegate
) override
{
390 start_
= delegate
->GetOpacityForAnimation();
393 void OnAbort(LayerAnimationDelegate
* delegate
) override
{
394 if (delegate
&& Started()) {
395 ThreadedLayerAnimationElement::OnAbort(delegate
);
396 delegate
->SetOpacityFromAnimation(gfx::Tween::FloatValueBetween(
397 gfx::Tween::CalculateValue(tween_type(), last_progressed_fraction()),
403 void OnEnd(LayerAnimationDelegate
* delegate
) override
{
404 delegate
->SetOpacityFromAnimation(target_
);
407 scoped_ptr
<cc::Animation
> CreateCCAnimation() override
{
408 scoped_ptr
<cc::AnimationCurve
> animation_curve(
409 new FloatAnimationCurveAdapter(tween_type(),
413 scoped_ptr
<cc::Animation
> animation(
414 cc::Animation::Create(animation_curve
.Pass(), animation_id(),
415 animation_group_id(), cc::Animation::OPACITY
));
416 return animation
.Pass();
419 void OnGetTarget(TargetValue
* target
) const override
{
420 target
->opacity
= target_
;
427 DISALLOW_COPY_AND_ASSIGN(ThreadedOpacityTransition
);
430 // ThreadedTransformTransition -------------------------------------------------
432 class ThreadedTransformTransition
: public ThreadedLayerAnimationElement
{
434 ThreadedTransformTransition(const gfx::Transform
& target
,
435 base::TimeDelta duration
)
436 : ThreadedLayerAnimationElement(TRANSFORM
, duration
),
439 ~ThreadedTransformTransition() override
{}
442 void OnStart(LayerAnimationDelegate
* delegate
) override
{
443 start_
= delegate
->GetTransformForAnimation();
446 void OnAbort(LayerAnimationDelegate
* delegate
) override
{
447 if (delegate
&& Started()) {
448 ThreadedLayerAnimationElement::OnAbort(delegate
);
449 delegate
->SetTransformFromAnimation(gfx::Tween::TransformValueBetween(
450 gfx::Tween::CalculateValue(tween_type(), last_progressed_fraction()),
456 void OnEnd(LayerAnimationDelegate
* delegate
) override
{
457 delegate
->SetTransformFromAnimation(target_
);
460 scoped_ptr
<cc::Animation
> CreateCCAnimation() override
{
461 scoped_ptr
<cc::AnimationCurve
> animation_curve(
462 new TransformAnimationCurveAdapter(tween_type(),
466 scoped_ptr
<cc::Animation
> animation(
467 cc::Animation::Create(animation_curve
.Pass(), animation_id(),
468 animation_group_id(), cc::Animation::TRANSFORM
));
469 return animation
.Pass();
472 void OnGetTarget(TargetValue
* target
) const override
{
473 target
->transform
= target_
;
477 gfx::Transform start_
;
478 const gfx::Transform target_
;
480 DISALLOW_COPY_AND_ASSIGN(ThreadedTransformTransition
);
483 // InverseTransformTransision --------------------------------------------------
485 class InverseTransformTransition
: public ThreadedLayerAnimationElement
{
487 InverseTransformTransition(const gfx::Transform
& base_transform
,
488 const LayerAnimationElement
* uninverted_transition
)
489 : ThreadedLayerAnimationElement(*uninverted_transition
),
490 base_transform_(base_transform
),
491 uninverted_transition_(
492 CheckAndCast
<const ThreadedTransformTransition
*>(
493 uninverted_transition
)) {
495 ~InverseTransformTransition() override
{}
497 static InverseTransformTransition
* Clone(const LayerAnimationElement
* other
) {
498 const InverseTransformTransition
* other_inverse
=
499 CheckAndCast
<const InverseTransformTransition
*>(other
);
500 return new InverseTransformTransition(
501 other_inverse
->base_transform_
, other_inverse
->uninverted_transition_
);
505 void OnStart(LayerAnimationDelegate
* delegate
) override
{
506 gfx::Transform
start(delegate
->GetTransformForAnimation());
507 effective_start_
= base_transform_
* start
;
510 uninverted_transition_
->GetTargetValue(&target
);
511 base_target_
= target
.transform
;
513 set_tween_type(uninverted_transition_
->tween_type());
515 TransformAnimationCurveAdapter
base_curve(tween_type(),
520 animation_curve_
.reset(new InverseTransformCurveAdapter(
521 base_curve
, start
, duration()));
522 computed_target_transform_
= ComputeWithBaseTransform(effective_start_
,
526 void OnAbort(LayerAnimationDelegate
* delegate
) override
{
527 if (delegate
&& Started()) {
528 ThreadedLayerAnimationElement::OnAbort(delegate
);
529 delegate
->SetTransformFromAnimation(ComputeCurrentTransform());
533 void OnEnd(LayerAnimationDelegate
* delegate
) override
{
534 delegate
->SetTransformFromAnimation(computed_target_transform_
);
537 scoped_ptr
<cc::Animation
> CreateCCAnimation() override
{
538 scoped_ptr
<cc::Animation
> animation(
539 cc::Animation::Create(animation_curve_
->Clone(), animation_id(),
540 animation_group_id(), cc::Animation::TRANSFORM
));
541 return animation
.Pass();
544 void OnGetTarget(TargetValue
* target
) const override
{
545 target
->transform
= computed_target_transform_
;
549 gfx::Transform
ComputeCurrentTransform() const {
550 gfx::Transform base_current
= gfx::Tween::TransformValueBetween(
551 gfx::Tween::CalculateValue(tween_type(), last_progressed_fraction()),
554 return ComputeWithBaseTransform(effective_start_
, base_current
);
557 gfx::Transform
ComputeWithBaseTransform(gfx::Transform start
,
558 gfx::Transform target
) const {
559 gfx::Transform
to_return(gfx::Transform::kSkipInitialization
);
560 bool success
= target
.GetInverse(&to_return
);
561 DCHECK(success
) << "Target transform must be invertible.";
563 to_return
.PreconcatTransform(start
);
567 template <typename T
>
568 static T
CheckAndCast(const LayerAnimationElement
* element
) {
569 AnimatableProperties properties
= element
->properties();
570 DCHECK(properties
& TRANSFORM
);
571 return static_cast<T
>(element
);
574 gfx::Transform effective_start_
;
575 gfx::Transform computed_target_transform_
;
577 const gfx::Transform base_transform_
;
578 gfx::Transform base_target_
;
580 scoped_ptr
<cc::AnimationCurve
> animation_curve_
;
582 const ThreadedTransformTransition
* const uninverted_transition_
;
584 DISALLOW_COPY_AND_ASSIGN(InverseTransformTransition
);
589 // LayerAnimationElement::TargetValue ------------------------------------------
591 LayerAnimationElement::TargetValue::TargetValue()
596 color(SK_ColorBLACK
) {
599 LayerAnimationElement::TargetValue::TargetValue(
600 const LayerAnimationDelegate
* delegate
)
601 : bounds(delegate
? delegate
->GetBoundsForAnimation() : gfx::Rect()),
603 delegate
->GetTransformForAnimation() : gfx::Transform()),
604 opacity(delegate
? delegate
->GetOpacityForAnimation() : 0.0f
),
605 visibility(delegate
? delegate
->GetVisibilityForAnimation() : false),
606 brightness(delegate
? delegate
->GetBrightnessForAnimation() : 0.0f
),
607 grayscale(delegate
? delegate
->GetGrayscaleForAnimation() : 0.0f
),
608 color(delegate
? delegate
->GetColorForAnimation() : 0.0f
) {
611 // LayerAnimationElement -------------------------------------------------------
613 LayerAnimationElement::LayerAnimationElement(
614 AnimatableProperties properties
, base::TimeDelta duration
)
615 : first_frame_(true),
616 properties_(properties
),
617 duration_(GetEffectiveDuration(duration
)),
618 tween_type_(gfx::Tween::LINEAR
),
619 animation_id_(cc::AnimationIdProvider::NextAnimationId()),
620 animation_group_id_(0),
621 last_progressed_fraction_(0.0),
622 weak_ptr_factory_(this) {
625 LayerAnimationElement::LayerAnimationElement(
626 const LayerAnimationElement
&element
)
627 : first_frame_(element
.first_frame_
),
628 properties_(element
.properties_
),
629 duration_(element
.duration_
),
630 tween_type_(element
.tween_type_
),
631 animation_id_(cc::AnimationIdProvider::NextAnimationId()),
632 animation_group_id_(element
.animation_group_id_
),
633 last_progressed_fraction_(element
.last_progressed_fraction_
),
634 weak_ptr_factory_(this) {
637 LayerAnimationElement::~LayerAnimationElement() {
640 void LayerAnimationElement::Start(LayerAnimationDelegate
* delegate
,
641 int animation_group_id
) {
642 DCHECK(requested_start_time_
!= base::TimeTicks());
643 DCHECK(first_frame_
);
644 animation_group_id_
= animation_group_id
;
645 last_progressed_fraction_
= 0.0;
647 RequestEffectiveStart(delegate
);
648 first_frame_
= false;
651 bool LayerAnimationElement::Progress(base::TimeTicks now
,
652 LayerAnimationDelegate
* delegate
) {
653 DCHECK(requested_start_time_
!= base::TimeTicks());
654 DCHECK(!first_frame_
);
659 if ((effective_start_time_
== base::TimeTicks()) ||
660 (now
< effective_start_time_
)) {
661 // This hasn't actually started yet.
663 last_progressed_fraction_
= 0.0;
667 base::TimeDelta elapsed
= now
- effective_start_time_
;
668 if ((duration_
> base::TimeDelta()) && (elapsed
< duration_
))
669 t
= elapsed
.InMillisecondsF() / duration_
.InMillisecondsF();
670 base::WeakPtr
<LayerAnimationElement
> alive(weak_ptr_factory_
.GetWeakPtr());
671 need_draw
= OnProgress(gfx::Tween::CalculateValue(tween_type_
, t
), delegate
);
674 first_frame_
= t
== 1.0;
675 last_progressed_fraction_
= t
;
679 bool LayerAnimationElement::IsFinished(base::TimeTicks time
,
680 base::TimeDelta
* total_duration
) {
681 // If an effective start has been requested but the effective start time
682 // hasn't yet been set, the animation is not finished, regardless of the
684 if (!first_frame_
&& (effective_start_time_
== base::TimeTicks()))
687 base::TimeDelta queueing_delay
;
689 queueing_delay
= effective_start_time_
- requested_start_time_
;
691 base::TimeDelta elapsed
= time
- requested_start_time_
;
692 if (elapsed
>= duration_
+ queueing_delay
) {
693 *total_duration
= duration_
+ queueing_delay
;
699 bool LayerAnimationElement::ProgressToEnd(LayerAnimationDelegate
* delegate
) {
702 base::WeakPtr
<LayerAnimationElement
> alive(weak_ptr_factory_
.GetWeakPtr());
703 bool need_draw
= OnProgress(1.0, delegate
);
706 last_progressed_fraction_
= 1.0;
711 void LayerAnimationElement::GetTargetValue(TargetValue
* target
) const {
715 bool LayerAnimationElement::IsThreaded() const {
719 void LayerAnimationElement::Abort(LayerAnimationDelegate
* delegate
) {
724 void LayerAnimationElement::RequestEffectiveStart(
725 LayerAnimationDelegate
* delegate
) {
726 DCHECK(requested_start_time_
!= base::TimeTicks());
727 effective_start_time_
= requested_start_time_
;
731 LayerAnimationElement::AnimatableProperty
732 LayerAnimationElement::ToAnimatableProperty(
733 cc::Animation::TargetProperty property
) {
735 case cc::Animation::TRANSFORM
:
737 case cc::Animation::OPACITY
:
741 return AnimatableProperty();
746 base::TimeDelta
LayerAnimationElement::GetEffectiveDuration(
747 const base::TimeDelta
& duration
) {
748 switch (ScopedAnimationDurationScaleMode::duration_scale_mode()) {
749 case ScopedAnimationDurationScaleMode::NORMAL_DURATION
:
751 case ScopedAnimationDurationScaleMode::FAST_DURATION
:
752 return duration
/ kFastDurationScaleDivisor
;
753 case ScopedAnimationDurationScaleMode::SLOW_DURATION
:
754 return duration
* kSlowDurationScaleMultiplier
;
755 case ScopedAnimationDurationScaleMode::NON_ZERO_DURATION
:
756 return duration
/ kNonZeroDurationScaleDivisor
;
757 case ScopedAnimationDurationScaleMode::ZERO_DURATION
:
758 return base::TimeDelta();
761 return base::TimeDelta();
766 LayerAnimationElement
* LayerAnimationElement::CreateTransformElement(
767 const gfx::Transform
& transform
,
768 base::TimeDelta duration
) {
769 return new ThreadedTransformTransition(transform
, duration
);
773 LayerAnimationElement
* LayerAnimationElement::CreateInverseTransformElement(
774 const gfx::Transform
& base_transform
,
775 const LayerAnimationElement
* uninverted_transition
) {
776 return new InverseTransformTransition(base_transform
, uninverted_transition
);
780 LayerAnimationElement
* LayerAnimationElement::CloneInverseTransformElement(
781 const LayerAnimationElement
* other
) {
782 return InverseTransformTransition::Clone(other
);
786 LayerAnimationElement
*
787 LayerAnimationElement::CreateInterpolatedTransformElement(
788 InterpolatedTransform
* interpolated_transform
,
789 base::TimeDelta duration
) {
790 return new InterpolatedTransformTransition(interpolated_transform
, duration
);
794 LayerAnimationElement
* LayerAnimationElement::CreateBoundsElement(
795 const gfx::Rect
& bounds
,
796 base::TimeDelta duration
) {
797 return new BoundsTransition(bounds
, duration
);
801 LayerAnimationElement
* LayerAnimationElement::CreateOpacityElement(
803 base::TimeDelta duration
) {
804 return new ThreadedOpacityTransition(opacity
, duration
);
808 LayerAnimationElement
* LayerAnimationElement::CreateVisibilityElement(
810 base::TimeDelta duration
) {
811 return new VisibilityTransition(visibility
, duration
);
815 LayerAnimationElement
* LayerAnimationElement::CreateBrightnessElement(
817 base::TimeDelta duration
) {
818 return new BrightnessTransition(brightness
, duration
);
822 LayerAnimationElement
* LayerAnimationElement::CreateGrayscaleElement(
824 base::TimeDelta duration
) {
825 return new GrayscaleTransition(grayscale
, duration
);
829 LayerAnimationElement
* LayerAnimationElement::CreatePauseElement(
830 AnimatableProperties properties
,
831 base::TimeDelta duration
) {
832 return new Pause(properties
, duration
);
836 LayerAnimationElement
* LayerAnimationElement::CreateColorElement(
838 base::TimeDelta duration
) {
839 return new ColorTransition(color
, duration
);