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(),
416 animation_group_id(),
417 cc::Animation::Opacity
));
418 return animation
.Pass();
421 void OnGetTarget(TargetValue
* target
) const override
{
422 target
->opacity
= target_
;
429 DISALLOW_COPY_AND_ASSIGN(ThreadedOpacityTransition
);
432 // ThreadedTransformTransition -------------------------------------------------
434 class ThreadedTransformTransition
: public ThreadedLayerAnimationElement
{
436 ThreadedTransformTransition(const gfx::Transform
& target
,
437 base::TimeDelta duration
)
438 : ThreadedLayerAnimationElement(TRANSFORM
, duration
),
441 ~ThreadedTransformTransition() override
{}
444 void OnStart(LayerAnimationDelegate
* delegate
) override
{
445 start_
= delegate
->GetTransformForAnimation();
448 void OnAbort(LayerAnimationDelegate
* delegate
) override
{
449 if (delegate
&& Started()) {
450 ThreadedLayerAnimationElement::OnAbort(delegate
);
451 delegate
->SetTransformFromAnimation(gfx::Tween::TransformValueBetween(
452 gfx::Tween::CalculateValue(tween_type(), last_progressed_fraction()),
458 void OnEnd(LayerAnimationDelegate
* delegate
) override
{
459 delegate
->SetTransformFromAnimation(target_
);
462 scoped_ptr
<cc::Animation
> CreateCCAnimation() override
{
463 scoped_ptr
<cc::AnimationCurve
> animation_curve(
464 new TransformAnimationCurveAdapter(tween_type(),
468 scoped_ptr
<cc::Animation
> animation(
469 cc::Animation::Create(animation_curve
.Pass(),
471 animation_group_id(),
472 cc::Animation::Transform
));
473 return animation
.Pass();
476 void OnGetTarget(TargetValue
* target
) const override
{
477 target
->transform
= target_
;
481 gfx::Transform start_
;
482 const gfx::Transform target_
;
484 DISALLOW_COPY_AND_ASSIGN(ThreadedTransformTransition
);
487 // InverseTransformTransision --------------------------------------------------
489 class InverseTransformTransition
: public ThreadedLayerAnimationElement
{
491 InverseTransformTransition(const gfx::Transform
& base_transform
,
492 const LayerAnimationElement
* uninverted_transition
)
493 : ThreadedLayerAnimationElement(*uninverted_transition
),
494 base_transform_(base_transform
),
495 uninverted_transition_(
496 CheckAndCast
<const ThreadedTransformTransition
*>(
497 uninverted_transition
)) {
499 ~InverseTransformTransition() override
{}
501 static InverseTransformTransition
* Clone(const LayerAnimationElement
* other
) {
502 const InverseTransformTransition
* other_inverse
=
503 CheckAndCast
<const InverseTransformTransition
*>(other
);
504 return new InverseTransformTransition(
505 other_inverse
->base_transform_
, other_inverse
->uninverted_transition_
);
509 void OnStart(LayerAnimationDelegate
* delegate
) override
{
510 gfx::Transform
start(delegate
->GetTransformForAnimation());
511 effective_start_
= base_transform_
* start
;
514 uninverted_transition_
->GetTargetValue(&target
);
515 base_target_
= target
.transform
;
517 set_tween_type(uninverted_transition_
->tween_type());
519 TransformAnimationCurveAdapter
base_curve(tween_type(),
524 animation_curve_
.reset(new InverseTransformCurveAdapter(
525 base_curve
, start
, duration()));
526 computed_target_transform_
= ComputeWithBaseTransform(effective_start_
,
530 void OnAbort(LayerAnimationDelegate
* delegate
) override
{
531 if (delegate
&& Started()) {
532 ThreadedLayerAnimationElement::OnAbort(delegate
);
533 delegate
->SetTransformFromAnimation(ComputeCurrentTransform());
537 void OnEnd(LayerAnimationDelegate
* delegate
) override
{
538 delegate
->SetTransformFromAnimation(computed_target_transform_
);
541 scoped_ptr
<cc::Animation
> CreateCCAnimation() override
{
542 scoped_ptr
<cc::Animation
> animation(
543 cc::Animation::Create(animation_curve_
->Clone(),
545 animation_group_id(),
546 cc::Animation::Transform
));
547 return animation
.Pass();
550 void OnGetTarget(TargetValue
* target
) const override
{
551 target
->transform
= computed_target_transform_
;
555 gfx::Transform
ComputeCurrentTransform() const {
556 gfx::Transform base_current
= gfx::Tween::TransformValueBetween(
557 gfx::Tween::CalculateValue(tween_type(), last_progressed_fraction()),
560 return ComputeWithBaseTransform(effective_start_
, base_current
);
563 gfx::Transform
ComputeWithBaseTransform(gfx::Transform start
,
564 gfx::Transform target
) const {
565 gfx::Transform
to_return(gfx::Transform::kSkipInitialization
);
566 bool success
= target
.GetInverse(&to_return
);
567 DCHECK(success
) << "Target transform must be invertible.";
569 to_return
.PreconcatTransform(start
);
573 template <typename T
>
574 static T
CheckAndCast(const LayerAnimationElement
* element
) {
575 AnimatableProperties properties
= element
->properties();
576 DCHECK(properties
& TRANSFORM
);
577 return static_cast<T
>(element
);
580 gfx::Transform effective_start_
;
581 gfx::Transform computed_target_transform_
;
583 const gfx::Transform base_transform_
;
584 gfx::Transform base_target_
;
586 scoped_ptr
<cc::AnimationCurve
> animation_curve_
;
588 const ThreadedTransformTransition
* const uninverted_transition_
;
590 DISALLOW_COPY_AND_ASSIGN(InverseTransformTransition
);
595 // LayerAnimationElement::TargetValue ------------------------------------------
597 LayerAnimationElement::TargetValue::TargetValue()
602 color(SK_ColorBLACK
) {
605 LayerAnimationElement::TargetValue::TargetValue(
606 const LayerAnimationDelegate
* delegate
)
607 : bounds(delegate
? delegate
->GetBoundsForAnimation() : gfx::Rect()),
609 delegate
->GetTransformForAnimation() : gfx::Transform()),
610 opacity(delegate
? delegate
->GetOpacityForAnimation() : 0.0f
),
611 visibility(delegate
? delegate
->GetVisibilityForAnimation() : false),
612 brightness(delegate
? delegate
->GetBrightnessForAnimation() : 0.0f
),
613 grayscale(delegate
? delegate
->GetGrayscaleForAnimation() : 0.0f
),
614 color(delegate
? delegate
->GetColorForAnimation() : 0.0f
) {
617 // LayerAnimationElement -------------------------------------------------------
619 LayerAnimationElement::LayerAnimationElement(
620 AnimatableProperties properties
, base::TimeDelta duration
)
621 : first_frame_(true),
622 properties_(properties
),
623 duration_(GetEffectiveDuration(duration
)),
624 tween_type_(gfx::Tween::LINEAR
),
625 animation_id_(cc::AnimationIdProvider::NextAnimationId()),
626 animation_group_id_(0),
627 last_progressed_fraction_(0.0),
628 weak_ptr_factory_(this) {
631 LayerAnimationElement::LayerAnimationElement(
632 const LayerAnimationElement
&element
)
633 : first_frame_(element
.first_frame_
),
634 properties_(element
.properties_
),
635 duration_(element
.duration_
),
636 tween_type_(element
.tween_type_
),
637 animation_id_(cc::AnimationIdProvider::NextAnimationId()),
638 animation_group_id_(element
.animation_group_id_
),
639 last_progressed_fraction_(element
.last_progressed_fraction_
),
640 weak_ptr_factory_(this) {
643 LayerAnimationElement::~LayerAnimationElement() {
646 void LayerAnimationElement::Start(LayerAnimationDelegate
* delegate
,
647 int animation_group_id
) {
648 DCHECK(requested_start_time_
!= base::TimeTicks());
649 DCHECK(first_frame_
);
650 animation_group_id_
= animation_group_id
;
651 last_progressed_fraction_
= 0.0;
653 RequestEffectiveStart(delegate
);
654 first_frame_
= false;
657 bool LayerAnimationElement::Progress(base::TimeTicks now
,
658 LayerAnimationDelegate
* delegate
) {
659 DCHECK(requested_start_time_
!= base::TimeTicks());
660 DCHECK(!first_frame_
);
665 if ((effective_start_time_
== base::TimeTicks()) ||
666 (now
< effective_start_time_
)) {
667 // This hasn't actually started yet.
669 last_progressed_fraction_
= 0.0;
673 base::TimeDelta elapsed
= now
- effective_start_time_
;
674 if ((duration_
> base::TimeDelta()) && (elapsed
< duration_
))
675 t
= elapsed
.InMillisecondsF() / duration_
.InMillisecondsF();
676 base::WeakPtr
<LayerAnimationElement
> alive(weak_ptr_factory_
.GetWeakPtr());
677 need_draw
= OnProgress(gfx::Tween::CalculateValue(tween_type_
, t
), delegate
);
680 first_frame_
= t
== 1.0;
681 last_progressed_fraction_
= t
;
685 bool LayerAnimationElement::IsFinished(base::TimeTicks time
,
686 base::TimeDelta
* total_duration
) {
687 // If an effective start has been requested but the effective start time
688 // hasn't yet been set, the animation is not finished, regardless of the
690 if (!first_frame_
&& (effective_start_time_
== base::TimeTicks()))
693 base::TimeDelta queueing_delay
;
695 queueing_delay
= effective_start_time_
- requested_start_time_
;
697 base::TimeDelta elapsed
= time
- requested_start_time_
;
698 if (elapsed
>= duration_
+ queueing_delay
) {
699 *total_duration
= duration_
+ queueing_delay
;
705 bool LayerAnimationElement::ProgressToEnd(LayerAnimationDelegate
* delegate
) {
708 base::WeakPtr
<LayerAnimationElement
> alive(weak_ptr_factory_
.GetWeakPtr());
709 bool need_draw
= OnProgress(1.0, delegate
);
712 last_progressed_fraction_
= 1.0;
717 void LayerAnimationElement::GetTargetValue(TargetValue
* target
) const {
721 bool LayerAnimationElement::IsThreaded() const {
725 void LayerAnimationElement::Abort(LayerAnimationDelegate
* delegate
) {
730 void LayerAnimationElement::RequestEffectiveStart(
731 LayerAnimationDelegate
* delegate
) {
732 DCHECK(requested_start_time_
!= base::TimeTicks());
733 effective_start_time_
= requested_start_time_
;
737 LayerAnimationElement::AnimatableProperty
738 LayerAnimationElement::ToAnimatableProperty(
739 cc::Animation::TargetProperty property
) {
741 case cc::Animation::Transform
:
743 case cc::Animation::Opacity
:
747 return AnimatableProperty();
752 base::TimeDelta
LayerAnimationElement::GetEffectiveDuration(
753 const base::TimeDelta
& duration
) {
754 switch (ScopedAnimationDurationScaleMode::duration_scale_mode()) {
755 case ScopedAnimationDurationScaleMode::NORMAL_DURATION
:
757 case ScopedAnimationDurationScaleMode::FAST_DURATION
:
758 return duration
/ kFastDurationScaleDivisor
;
759 case ScopedAnimationDurationScaleMode::SLOW_DURATION
:
760 return duration
* kSlowDurationScaleMultiplier
;
761 case ScopedAnimationDurationScaleMode::NON_ZERO_DURATION
:
762 return duration
/ kNonZeroDurationScaleDivisor
;
763 case ScopedAnimationDurationScaleMode::ZERO_DURATION
:
764 return base::TimeDelta();
767 return base::TimeDelta();
772 LayerAnimationElement
* LayerAnimationElement::CreateTransformElement(
773 const gfx::Transform
& transform
,
774 base::TimeDelta duration
) {
775 return new ThreadedTransformTransition(transform
, duration
);
779 LayerAnimationElement
* LayerAnimationElement::CreateInverseTransformElement(
780 const gfx::Transform
& base_transform
,
781 const LayerAnimationElement
* uninverted_transition
) {
782 return new InverseTransformTransition(base_transform
, uninverted_transition
);
786 LayerAnimationElement
* LayerAnimationElement::CloneInverseTransformElement(
787 const LayerAnimationElement
* other
) {
788 return InverseTransformTransition::Clone(other
);
792 LayerAnimationElement
*
793 LayerAnimationElement::CreateInterpolatedTransformElement(
794 InterpolatedTransform
* interpolated_transform
,
795 base::TimeDelta duration
) {
796 return new InterpolatedTransformTransition(interpolated_transform
, duration
);
800 LayerAnimationElement
* LayerAnimationElement::CreateBoundsElement(
801 const gfx::Rect
& bounds
,
802 base::TimeDelta duration
) {
803 return new BoundsTransition(bounds
, duration
);
807 LayerAnimationElement
* LayerAnimationElement::CreateOpacityElement(
809 base::TimeDelta duration
) {
810 return new ThreadedOpacityTransition(opacity
, duration
);
814 LayerAnimationElement
* LayerAnimationElement::CreateVisibilityElement(
816 base::TimeDelta duration
) {
817 return new VisibilityTransition(visibility
, duration
);
821 LayerAnimationElement
* LayerAnimationElement::CreateBrightnessElement(
823 base::TimeDelta duration
) {
824 return new BrightnessTransition(brightness
, duration
);
828 LayerAnimationElement
* LayerAnimationElement::CreateGrayscaleElement(
830 base::TimeDelta duration
) {
831 return new GrayscaleTransition(grayscale
, duration
);
835 LayerAnimationElement
* LayerAnimationElement::CreatePauseElement(
836 AnimatableProperties properties
,
837 base::TimeDelta duration
) {
838 return new Pause(properties
, duration
);
842 LayerAnimationElement
* LayerAnimationElement::CreateColorElement(
844 base::TimeDelta duration
) {
845 return new ColorTransition(color
, duration
);