// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/compositor/layer_animation_element.h" #include "base/compiler_specific.h" #include "cc/animation/animation.h" #include "cc/animation/animation_id_provider.h" #include "ui/compositor/float_animation_curve_adapter.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_animation_delegate.h" #include "ui/compositor/layer_animator.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/compositor/transform_animation_curve_adapter.h" #include "ui/gfx/animation/tween.h" #include "ui/gfx/interpolated_transform.h" namespace ui { namespace { // The factor by which duration is scaled up or down when // ScopedAnimationDurationScaleMode::duration_scale_mode() is SLOW_DURATION or // FAST_DURATION. const int kSlowDurationScaleFactor = 4; const int kFastDurationScaleFactor = 4; // Pause ----------------------------------------------------------------------- class Pause : public LayerAnimationElement { public: Pause(const AnimatableProperties& properties, base::TimeDelta duration) : LayerAnimationElement(properties, duration) { } virtual ~Pause() {} private: virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {} virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE { return false; } virtual void OnGetTarget(TargetValue* target) const OVERRIDE {} virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} DISALLOW_COPY_AND_ASSIGN(Pause); }; // TransformTransition --------------------------------------------------------- class TransformTransition : public LayerAnimationElement { public: TransformTransition(const gfx::Transform& target, base::TimeDelta duration) : LayerAnimationElement(GetProperties(), duration), target_(target) { } virtual ~TransformTransition() {} protected: virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE { start_ = delegate->GetTransformForAnimation(); } virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE { delegate->SetTransformFromAnimation( gfx::Tween::TransformValueBetween(t, start_, target_)); return true; } virtual void OnGetTarget(TargetValue* target) const OVERRIDE { target->transform = target_; } virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} private: static AnimatableProperties GetProperties() { AnimatableProperties properties; properties.insert(LayerAnimationElement::TRANSFORM); return properties; } gfx::Transform start_; const gfx::Transform target_; DISALLOW_COPY_AND_ASSIGN(TransformTransition); }; // InterpolatedTransformTransition --------------------------------------------- class InterpolatedTransformTransition : public LayerAnimationElement { public: InterpolatedTransformTransition(InterpolatedTransform* interpolated_transform, base::TimeDelta duration) : LayerAnimationElement(GetProperties(), duration), interpolated_transform_(interpolated_transform) { } virtual ~InterpolatedTransformTransition() {} protected: virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE { } virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE { delegate->SetTransformFromAnimation( interpolated_transform_->Interpolate(static_cast<float>(t))); return true; } virtual void OnGetTarget(TargetValue* target) const OVERRIDE { target->transform = interpolated_transform_->Interpolate(1.0f); } virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} private: static AnimatableProperties GetProperties() { AnimatableProperties properties; properties.insert(LayerAnimationElement::TRANSFORM); return properties; } scoped_ptr<InterpolatedTransform> interpolated_transform_; DISALLOW_COPY_AND_ASSIGN(InterpolatedTransformTransition); }; // BoundsTransition ------------------------------------------------------------ class BoundsTransition : public LayerAnimationElement { public: BoundsTransition(const gfx::Rect& target, base::TimeDelta duration) : LayerAnimationElement(GetProperties(), duration), target_(target) { } virtual ~BoundsTransition() {} protected: virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE { start_ = delegate->GetBoundsForAnimation(); } virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE { delegate->SetBoundsFromAnimation( gfx::Tween::RectValueBetween(t, start_, target_)); return true; } virtual void OnGetTarget(TargetValue* target) const OVERRIDE { target->bounds = target_; } virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} private: static AnimatableProperties GetProperties() { AnimatableProperties properties; properties.insert(LayerAnimationElement::BOUNDS); return properties; } gfx::Rect start_; const gfx::Rect target_; DISALLOW_COPY_AND_ASSIGN(BoundsTransition); }; // OpacityTransition ----------------------------------------------------------- class OpacityTransition : public LayerAnimationElement { public: OpacityTransition(float target, base::TimeDelta duration) : LayerAnimationElement(GetProperties(), duration), start_(0.0f), target_(target) { } virtual ~OpacityTransition() {} protected: virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE { start_ = delegate->GetOpacityForAnimation(); } virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE { delegate->SetOpacityFromAnimation( gfx::Tween::FloatValueBetween(t, start_, target_)); return true; } virtual void OnGetTarget(TargetValue* target) const OVERRIDE { target->opacity = target_; } virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} private: static AnimatableProperties GetProperties() { AnimatableProperties properties; properties.insert(LayerAnimationElement::OPACITY); return properties; } float start_; const float target_; DISALLOW_COPY_AND_ASSIGN(OpacityTransition); }; // VisibilityTransition -------------------------------------------------------- class VisibilityTransition : public LayerAnimationElement { public: VisibilityTransition(bool target, base::TimeDelta duration) : LayerAnimationElement(GetProperties(), duration), start_(false), target_(target) { } virtual ~VisibilityTransition() {} protected: virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE { start_ = delegate->GetVisibilityForAnimation(); } virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE { delegate->SetVisibilityFromAnimation(t == 1.0 ? target_ : start_); return t == 1.0; } virtual void OnGetTarget(TargetValue* target) const OVERRIDE { target->visibility = target_; } virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} private: static AnimatableProperties GetProperties() { AnimatableProperties properties; properties.insert(LayerAnimationElement::VISIBILITY); return properties; } bool start_; const bool target_; DISALLOW_COPY_AND_ASSIGN(VisibilityTransition); }; // BrightnessTransition -------------------------------------------------------- class BrightnessTransition : public LayerAnimationElement { public: BrightnessTransition(float target, base::TimeDelta duration) : LayerAnimationElement(GetProperties(), duration), start_(0.0f), target_(target) { } virtual ~BrightnessTransition() {} protected: virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE { start_ = delegate->GetBrightnessForAnimation(); } virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE { delegate->SetBrightnessFromAnimation( gfx::Tween::FloatValueBetween(t, start_, target_)); return true; } virtual void OnGetTarget(TargetValue* target) const OVERRIDE { target->brightness = target_; } virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} private: static AnimatableProperties GetProperties() { AnimatableProperties properties; properties.insert(LayerAnimationElement::BRIGHTNESS); return properties; } float start_; const float target_; DISALLOW_COPY_AND_ASSIGN(BrightnessTransition); }; // GrayscaleTransition --------------------------------------------------------- class GrayscaleTransition : public LayerAnimationElement { public: GrayscaleTransition(float target, base::TimeDelta duration) : LayerAnimationElement(GetProperties(), duration), start_(0.0f), target_(target) { } virtual ~GrayscaleTransition() {} protected: virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE { start_ = delegate->GetGrayscaleForAnimation(); } virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE { delegate->SetGrayscaleFromAnimation( gfx::Tween::FloatValueBetween(t, start_, target_)); return true; } virtual void OnGetTarget(TargetValue* target) const OVERRIDE { target->grayscale = target_; } virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} private: static AnimatableProperties GetProperties() { AnimatableProperties properties; properties.insert(LayerAnimationElement::GRAYSCALE); return properties; } float start_; const float target_; DISALLOW_COPY_AND_ASSIGN(GrayscaleTransition); }; // ColorTransition ------------------------------------------------------------- class ColorTransition : public LayerAnimationElement { public: ColorTransition(SkColor target, base::TimeDelta duration) : LayerAnimationElement(GetProperties(), duration), start_(SK_ColorBLACK), target_(target) { } virtual ~ColorTransition() {} protected: virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE { start_ = delegate->GetColorForAnimation(); } virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE { delegate->SetColorFromAnimation( gfx::Tween::ColorValueBetween(t, start_, target_)); return true; } virtual void OnGetTarget(TargetValue* target) const OVERRIDE { target->color = target_; } virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} private: static AnimatableProperties GetProperties() { AnimatableProperties properties; properties.insert(LayerAnimationElement::COLOR); return properties; } SkColor start_; const SkColor target_; DISALLOW_COPY_AND_ASSIGN(ColorTransition); }; // ThreadedLayerAnimationElement ----------------------------------------------- class ThreadedLayerAnimationElement : public LayerAnimationElement { public: ThreadedLayerAnimationElement(const AnimatableProperties& properties, base::TimeDelta duration) : LayerAnimationElement(properties, duration) { } virtual ~ThreadedLayerAnimationElement() {} virtual bool IsThreaded() const OVERRIDE { return (duration() != base::TimeDelta()); } protected: explicit ThreadedLayerAnimationElement(const LayerAnimationElement& element) : LayerAnimationElement(element) { } virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE { if (t < 1.0) return false; if (Started()) { delegate->RemoveThreadedAnimation(animation_id()); } OnEnd(delegate); return true; } virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE { if (delegate && Started()) { delegate->RemoveThreadedAnimation(animation_id()); } } virtual void RequestEffectiveStart( LayerAnimationDelegate* delegate) OVERRIDE { DCHECK(animation_group_id()); if (duration() == base::TimeDelta()) { set_effective_start_time(requested_start_time()); return; } set_effective_start_time(base::TimeTicks()); scoped_ptr<cc::Animation> animation = CreateCCAnimation(); animation->set_needs_synchronized_start_time(true); delegate->AddThreadedAnimation(animation.Pass()); } virtual void OnEnd(LayerAnimationDelegate* delegate) = 0; virtual scoped_ptr<cc::Animation> CreateCCAnimation() = 0; private: DISALLOW_COPY_AND_ASSIGN(ThreadedLayerAnimationElement); }; // ThreadedOpacityTransition --------------------------------------------------- class ThreadedOpacityTransition : public ThreadedLayerAnimationElement { public: ThreadedOpacityTransition(float target, base::TimeDelta duration) : ThreadedLayerAnimationElement(GetProperties(), duration), start_(0.0f), target_(target) { } virtual ~ThreadedOpacityTransition() {} protected: virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE { start_ = delegate->GetOpacityForAnimation(); } virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE { if (delegate && Started()) { ThreadedLayerAnimationElement::OnAbort(delegate); delegate->SetOpacityFromAnimation(gfx::Tween::FloatValueBetween( gfx::Tween::CalculateValue(tween_type(), last_progressed_fraction()), start_, target_)); } } virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE { delegate->SetOpacityFromAnimation(target_); } virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE { scoped_ptr<cc::AnimationCurve> animation_curve( new FloatAnimationCurveAdapter(tween_type(), start_, target_, duration())); scoped_ptr<cc::Animation> animation( cc::Animation::Create(animation_curve.Pass(), animation_id(), animation_group_id(), cc::Animation::Opacity)); return animation.Pass(); } virtual void OnGetTarget(TargetValue* target) const OVERRIDE { target->opacity = target_; } private: static AnimatableProperties GetProperties() { AnimatableProperties properties; properties.insert(LayerAnimationElement::OPACITY); return properties; } float start_; const float target_; DISALLOW_COPY_AND_ASSIGN(ThreadedOpacityTransition); }; // ThreadedTransformTransition ------------------------------------------------- class ThreadedTransformTransition : public ThreadedLayerAnimationElement { public: ThreadedTransformTransition(const gfx::Transform& target, base::TimeDelta duration) : ThreadedLayerAnimationElement(GetProperties(), duration), target_(target) { } virtual ~ThreadedTransformTransition() {} protected: virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE { start_ = delegate->GetTransformForAnimation(); float device_scale_factor = delegate->GetDeviceScaleFactor(); cc_start_ = Layer::ConvertTransformToCCTransform(start_, device_scale_factor); cc_target_ = Layer::ConvertTransformToCCTransform(target_, device_scale_factor); } virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE { if (delegate && Started()) { ThreadedLayerAnimationElement::OnAbort(delegate); delegate->SetTransformFromAnimation(gfx::Tween::TransformValueBetween( gfx::Tween::CalculateValue(tween_type(), last_progressed_fraction()), start_, target_)); } } virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE { delegate->SetTransformFromAnimation(target_); } virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE { scoped_ptr<cc::AnimationCurve> animation_curve( new TransformAnimationCurveAdapter(tween_type(), cc_start_, cc_target_, duration())); scoped_ptr<cc::Animation> animation( cc::Animation::Create(animation_curve.Pass(), animation_id(), animation_group_id(), cc::Animation::Transform)); return animation.Pass(); } virtual void OnGetTarget(TargetValue* target) const OVERRIDE { target->transform = target_; } private: static AnimatableProperties GetProperties() { AnimatableProperties properties; properties.insert(LayerAnimationElement::TRANSFORM); return properties; } gfx::Transform start_; gfx::Transform cc_start_; const gfx::Transform target_; gfx::Transform cc_target_; DISALLOW_COPY_AND_ASSIGN(ThreadedTransformTransition); }; // InverseTransformTransision -------------------------------------------------- class InverseTransformTransition : public ThreadedLayerAnimationElement { public: InverseTransformTransition(const gfx::Transform& base_transform, const LayerAnimationElement* uninverted_transition) : ThreadedLayerAnimationElement(*uninverted_transition), base_transform_(base_transform), uninverted_transition_( CheckAndCast<const ThreadedTransformTransition*>( uninverted_transition)) { } virtual ~InverseTransformTransition() {} static InverseTransformTransition* Clone(const LayerAnimationElement* other) { const InverseTransformTransition* other_inverse = CheckAndCast<const InverseTransformTransition*>(other); return new InverseTransformTransition( other_inverse->base_transform_, other_inverse->uninverted_transition_); } protected: virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE { gfx::Transform start(delegate->GetTransformForAnimation()); effective_start_ = base_transform_ * start; TargetValue target; uninverted_transition_->GetTargetValue(&target); base_target_ = target.transform; set_tween_type(uninverted_transition_->tween_type()); float device_scale_factor = delegate->GetDeviceScaleFactor(); const gfx::Transform cc_base_start = Layer::ConvertTransformToCCTransform( base_transform_, device_scale_factor); const gfx::Transform cc_base_target = Layer::ConvertTransformToCCTransform( base_target_, device_scale_factor); TransformAnimationCurveAdapter base_curve(tween_type(), cc_base_start, cc_base_target, duration()); const gfx::Transform cc_start = Layer::ConvertTransformToCCTransform( start, device_scale_factor); animation_curve_.reset(new InverseTransformCurveAdapter( base_curve, cc_start, duration())); computed_target_transform_ = ComputeWithBaseTransform(effective_start_, base_target_); } virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE { if (delegate && Started()) { ThreadedLayerAnimationElement::OnAbort(delegate); delegate->SetTransformFromAnimation(ComputeCurrentTransform()); } } virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE { delegate->SetTransformFromAnimation(computed_target_transform_); } virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE { scoped_ptr<cc::Animation> animation( cc::Animation::Create(animation_curve_->Clone(), animation_id(), animation_group_id(), cc::Animation::Transform)); return animation.Pass(); } virtual void OnGetTarget(TargetValue* target) const OVERRIDE { target->transform = computed_target_transform_; } private: gfx::Transform ComputeCurrentTransform() const { gfx::Transform base_current = gfx::Tween::TransformValueBetween( gfx::Tween::CalculateValue(tween_type(), last_progressed_fraction()), base_transform_, base_target_); return ComputeWithBaseTransform(effective_start_, base_current); } gfx::Transform ComputeWithBaseTransform(gfx::Transform start, gfx::Transform target) const { gfx::Transform to_return(gfx::Transform::kSkipInitialization); bool success = target.GetInverse(&to_return); DCHECK(success) << "Target transform must be invertible."; to_return.PreconcatTransform(start); return to_return; } static AnimatableProperties GetProperties() { AnimatableProperties properties; properties.insert(LayerAnimationElement::TRANSFORM); return properties; } template <typename T> static T CheckAndCast(const LayerAnimationElement* element) { const AnimatableProperties& properties = element->properties(); DCHECK(properties.find(TRANSFORM) != properties.end()); return static_cast<T>(element); } gfx::Transform effective_start_; gfx::Transform computed_target_transform_; const gfx::Transform base_transform_; gfx::Transform base_target_; scoped_ptr<cc::AnimationCurve> animation_curve_; const ThreadedTransformTransition* const uninverted_transition_; DISALLOW_COPY_AND_ASSIGN(InverseTransformTransition); }; } // namespace // LayerAnimationElement::TargetValue ------------------------------------------ LayerAnimationElement::TargetValue::TargetValue() : opacity(0.0f), visibility(false), brightness(0.0f), grayscale(0.0f), color(SK_ColorBLACK) { } LayerAnimationElement::TargetValue::TargetValue( const LayerAnimationDelegate* delegate) : bounds(delegate ? delegate->GetBoundsForAnimation() : gfx::Rect()), transform(delegate ? delegate->GetTransformForAnimation() : gfx::Transform()), opacity(delegate ? delegate->GetOpacityForAnimation() : 0.0f), visibility(delegate ? delegate->GetVisibilityForAnimation() : false), brightness(delegate ? delegate->GetBrightnessForAnimation() : 0.0f), grayscale(delegate ? delegate->GetGrayscaleForAnimation() : 0.0f), color(delegate ? delegate->GetColorForAnimation() : 0.0f) { } // LayerAnimationElement ------------------------------------------------------- LayerAnimationElement::LayerAnimationElement( const AnimatableProperties& properties, base::TimeDelta duration) : first_frame_(true), properties_(properties), duration_(GetEffectiveDuration(duration)), tween_type_(gfx::Tween::LINEAR), animation_id_(cc::AnimationIdProvider::NextAnimationId()), animation_group_id_(0), last_progressed_fraction_(0.0), weak_ptr_factory_(this) { } LayerAnimationElement::LayerAnimationElement( const LayerAnimationElement &element) : first_frame_(element.first_frame_), properties_(element.properties_), duration_(element.duration_), tween_type_(element.tween_type_), animation_id_(cc::AnimationIdProvider::NextAnimationId()), animation_group_id_(element.animation_group_id_), last_progressed_fraction_(element.last_progressed_fraction_), weak_ptr_factory_(this) { } LayerAnimationElement::~LayerAnimationElement() { } void LayerAnimationElement::Start(LayerAnimationDelegate* delegate, int animation_group_id) { DCHECK(requested_start_time_ != base::TimeTicks()); DCHECK(first_frame_); animation_group_id_ = animation_group_id; last_progressed_fraction_ = 0.0; OnStart(delegate); RequestEffectiveStart(delegate); first_frame_ = false; } bool LayerAnimationElement::Progress(base::TimeTicks now, LayerAnimationDelegate* delegate) { DCHECK(requested_start_time_ != base::TimeTicks()); DCHECK(!first_frame_); bool need_draw; double t = 1.0; if ((effective_start_time_ == base::TimeTicks()) || (now < effective_start_time_)) { // This hasn't actually started yet. need_draw = false; last_progressed_fraction_ = 0.0; return need_draw; } base::TimeDelta elapsed = now - effective_start_time_; if ((duration_ > base::TimeDelta()) && (elapsed < duration_)) t = elapsed.InMillisecondsF() / duration_.InMillisecondsF(); base::WeakPtr<LayerAnimationElement> alive(weak_ptr_factory_.GetWeakPtr()); need_draw = OnProgress(gfx::Tween::CalculateValue(tween_type_, t), delegate); if (!alive) return need_draw; first_frame_ = t == 1.0; last_progressed_fraction_ = t; return need_draw; } bool LayerAnimationElement::IsFinished(base::TimeTicks time, base::TimeDelta* total_duration) { // If an effective start has been requested but the effective start time // hasn't yet been set, the animation is not finished, regardless of the // value of |time|. if (!first_frame_ && (effective_start_time_ == base::TimeTicks())) return false; base::TimeDelta queueing_delay; if (!first_frame_) queueing_delay = effective_start_time_ - requested_start_time_; base::TimeDelta elapsed = time - requested_start_time_; if (elapsed >= duration_ + queueing_delay) { *total_duration = duration_ + queueing_delay; return true; } return false; } bool LayerAnimationElement::ProgressToEnd(LayerAnimationDelegate* delegate) { if (first_frame_) OnStart(delegate); base::WeakPtr<LayerAnimationElement> alive(weak_ptr_factory_.GetWeakPtr()); bool need_draw = OnProgress(1.0, delegate); if (!alive) return need_draw; last_progressed_fraction_ = 1.0; first_frame_ = true; return need_draw; } void LayerAnimationElement::GetTargetValue(TargetValue* target) const { OnGetTarget(target); } bool LayerAnimationElement::IsThreaded() const { return false; } void LayerAnimationElement::Abort(LayerAnimationDelegate* delegate) { OnAbort(delegate); first_frame_ = true; } void LayerAnimationElement::RequestEffectiveStart( LayerAnimationDelegate* delegate) { DCHECK(requested_start_time_ != base::TimeTicks()); effective_start_time_ = requested_start_time_; } // static LayerAnimationElement::AnimatableProperty LayerAnimationElement::ToAnimatableProperty( cc::Animation::TargetProperty property) { switch (property) { case cc::Animation::Transform: return TRANSFORM; case cc::Animation::Opacity: return OPACITY; default: NOTREACHED(); return AnimatableProperty(); } } // static base::TimeDelta LayerAnimationElement::GetEffectiveDuration( const base::TimeDelta& duration) { switch (ScopedAnimationDurationScaleMode::duration_scale_mode()) { case ScopedAnimationDurationScaleMode::NORMAL_DURATION: return duration; case ScopedAnimationDurationScaleMode::FAST_DURATION: return duration / kFastDurationScaleFactor; case ScopedAnimationDurationScaleMode::SLOW_DURATION: return duration * kSlowDurationScaleFactor; case ScopedAnimationDurationScaleMode::ZERO_DURATION: return base::TimeDelta(); default: NOTREACHED(); return base::TimeDelta(); } } // static LayerAnimationElement* LayerAnimationElement::CreateTransformElement( const gfx::Transform& transform, base::TimeDelta duration) { return new ThreadedTransformTransition(transform, duration); } // static LayerAnimationElement* LayerAnimationElement::CreateInverseTransformElement( const gfx::Transform& base_transform, const LayerAnimationElement* uninverted_transition) { return new InverseTransformTransition(base_transform, uninverted_transition); } // static LayerAnimationElement* LayerAnimationElement::CloneInverseTransformElement( const LayerAnimationElement* other) { return InverseTransformTransition::Clone(other); } // static LayerAnimationElement* LayerAnimationElement::CreateInterpolatedTransformElement( InterpolatedTransform* interpolated_transform, base::TimeDelta duration) { return new InterpolatedTransformTransition(interpolated_transform, duration); } // static LayerAnimationElement* LayerAnimationElement::CreateBoundsElement( const gfx::Rect& bounds, base::TimeDelta duration) { return new BoundsTransition(bounds, duration); } // static LayerAnimationElement* LayerAnimationElement::CreateOpacityElement( float opacity, base::TimeDelta duration) { return new ThreadedOpacityTransition(opacity, duration); } // static LayerAnimationElement* LayerAnimationElement::CreateVisibilityElement( bool visibility, base::TimeDelta duration) { return new VisibilityTransition(visibility, duration); } // static LayerAnimationElement* LayerAnimationElement::CreateBrightnessElement( float brightness, base::TimeDelta duration) { return new BrightnessTransition(brightness, duration); } // static LayerAnimationElement* LayerAnimationElement::CreateGrayscaleElement( float grayscale, base::TimeDelta duration) { return new GrayscaleTransition(grayscale, duration); } // static LayerAnimationElement* LayerAnimationElement::CreatePauseElement( const AnimatableProperties& properties, base::TimeDelta duration) { return new Pause(properties, duration); } // static LayerAnimationElement* LayerAnimationElement::CreateColorElement( SkColor color, base::TimeDelta duration) { return new ColorTransition(color, duration); } } // namespace ui