Index: ui/compositor/layer_animation_element.cc |
diff --git a/ui/compositor/layer_animation_element.cc b/ui/compositor/layer_animation_element.cc |
index f70c1084a1db9e134227c54e7a883c83fc2e6433..51a1c48c3533f62c47ec3f686ab4fc7c4ae36b91 100644 |
--- a/ui/compositor/layer_animation_element.cc |
+++ b/ui/compositor/layer_animation_element.cc |
@@ -394,6 +394,10 @@ class ThreadedLayerAnimationElement : public LayerAnimationElement { |
} |
protected: |
+ explicit ThreadedLayerAnimationElement(const LayerAnimationElement& element) |
+ : LayerAnimationElement(element) { |
+ } |
+ |
virtual bool OnProgress(double t, |
LayerAnimationDelegate* delegate) OVERRIDE { |
if (t < 1.0) |
@@ -563,6 +567,117 @@ class ThreadedTransformTransition : public ThreadedLayerAnimationElement { |
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(uninverted_transition)) { |
+ } |
+ virtual ~InverseTransformTransition() {} |
+ |
+ 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 = Tween::ValueBetween( |
+ 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); |
+ DCHECK(target.GetInverse(&to_return)); |
+ |
+ to_return.PreconcatTransform(start); |
+ return to_return; |
+ } |
+ |
+ static AnimatableProperties GetProperties() { |
+ AnimatableProperties properties; |
+ properties.insert(LayerAnimationElement::TRANSFORM); |
+ return properties; |
+ } |
+ |
+ static const ThreadedTransformTransition* CheckAndCast( |
+ const LayerAnimationElement* element) { |
+ const AnimatableProperties& properties = element->properties(); |
+ DCHECK(properties.find(TRANSFORM) != properties.end()); |
+ return static_cast<const ThreadedTransformTransition*>(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 ------------------------------------------ |
@@ -601,6 +716,17 @@ LayerAnimationElement::LayerAnimationElement( |
last_progressed_fraction_(0.0) { |
} |
+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_) { |
+} |
+ |
LayerAnimationElement::~LayerAnimationElement() { |
} |
@@ -729,6 +855,13 @@ LayerAnimationElement* LayerAnimationElement::CreateTransformElement( |
} |
// static |
+LayerAnimationElement* LayerAnimationElement::CreateInverseTransformElement( |
+ const gfx::Transform& base_transform, |
+ const LayerAnimationElement* uninverted_transition) { |
+ return new InverseTransformTransition(base_transform, uninverted_transition); |
+} |
+ |
+// static |
LayerAnimationElement* |
LayerAnimationElement::CreateInterpolatedTransformElement( |
InterpolatedTransform* interpolated_transform, |