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..c8fce1ee3f6482fae789701e9b3df7a4cb2167f3 100644 |
--- a/ui/compositor/layer_animation_element.cc |
+++ b/ui/compositor/layer_animation_element.cc |
@@ -563,6 +563,104 @@ class ThreadedTransformTransition : public ThreadedLayerAnimationElement { |
DISALLOW_COPY_AND_ASSIGN(ThreadedTransformTransition); |
}; |
+// ChildCounterTransformTransition --------------------------------------------- |
+ |
+class ChildCounterTransformTransition : public ThreadedLayerAnimationElement { |
+ public: |
+ ChildCounterTransformTransition(const gfx::Transform& parent_start, |
+ const gfx::Transform& parent_target, |
+ base::TimeDelta duration) |
+ : ThreadedLayerAnimationElement(GetProperties(), duration), |
+ parent_start_(parent_start), |
+ parent_target_(parent_target) { |
+ } |
+ virtual ~ChildCounterTransformTransition() {} |
+ |
+ protected: |
+ virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE { |
+ start_ = delegate->GetTransformForAnimation(); |
+ effective_start_ = parent_start_ * start_; |
+ float device_scale_factor = delegate->GetDeviceScaleFactor(); |
+ cc_start_ = Layer::ConvertTransformToCCTransform(start_, |
+ device_scale_factor); |
+ cc_parent_start_ = Layer::ConvertTransformToCCTransform( |
+ parent_start_, |
+ device_scale_factor); |
+ cc_parent_target_ = Layer::ConvertTransformToCCTransform( |
+ parent_target_, |
+ device_scale_factor); |
+ } |
+ |
+ virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE { |
+ if (delegate && Started()) { |
+ ThreadedLayerAnimationElement::OnAbort(delegate); |
+ delegate->SetTransformFromAnimation(ComputeCurrentTransform()); |
+ } |
+ } |
+ |
+ virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE { |
+ delegate->SetTransformFromAnimation( |
+ ComputeWithParentTransform(effective_start_, parent_target_)); |
+ } |
+ |
+ virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE { |
+ TransformAnimationCurveAdapter parent_curve(tween_type(), |
+ cc_parent_start_, |
+ cc_parent_target_, |
+ duration()); |
+ scoped_ptr<cc::AnimationCurve> animation_curve( |
+ new CounterTransformCurveAdapter(parent_curve, |
+ cc_start_, |
+ 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 = ComputeWithParentTransform(effective_start_, |
+ parent_target_); |
+ } |
+ |
+ private: |
+ gfx::Transform ComputeCurrentTransform() const { |
+ gfx::Transform parent_current = Tween::ValueBetween( |
+ Tween::CalculateValue(tween_type(), last_progressed_fraction()), |
+ parent_start_, |
+ parent_target_); |
+ return ComputeWithParentTransform(effective_start_, parent_current); |
+ } |
+ |
+ gfx::Transform ComputeWithParentTransform(gfx::Transform start, |
+ gfx::Transform parent) const { |
+ gfx::Transform to_return(gfx::Transform::kSkipInitialization); |
+ DCHECK(parent.GetInverse(&to_return)); |
+ |
+ to_return.PreconcatTransform(start); |
+ return to_return; |
+ } |
+ |
+ static AnimatableProperties GetProperties() { |
+ AnimatableProperties properties; |
+ properties.insert(LayerAnimationElement::TRANSFORM); |
+ return properties; |
+ } |
+ |
+ gfx::Transform start_; |
+ gfx::Transform cc_start_; |
+ gfx::Transform effective_start_; |
+ |
+ const gfx::Transform parent_start_; |
+ gfx::Transform cc_parent_start_; |
+ const gfx::Transform parent_target_; |
+ gfx::Transform cc_parent_target_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ChildCounterTransformTransition); |
+}; |
+ |
} // namespace |
// LayerAnimationElement::TargetValue ------------------------------------------ |
@@ -729,6 +827,16 @@ LayerAnimationElement* LayerAnimationElement::CreateTransformElement( |
} |
// static |
+LayerAnimationElement* LayerAnimationElement::CreateInverseTransformElement( |
+ const gfx::Transform& parent_start, |
+ const gfx::Transform& parent_end, |
+ base::TimeDelta duration) { |
+ return new ChildCounterTransformTransition(parent_start, |
+ parent_end, |
+ duration); |
+} |
+ |
+// static |
LayerAnimationElement* |
LayerAnimationElement::CreateInterpolatedTransformElement( |
InterpolatedTransform* interpolated_transform, |