Index: cc/layers/viewport.cc |
diff --git a/cc/layers/viewport.cc b/cc/layers/viewport.cc |
index 1b3cfe574a8a724da38c3b2997fc525c80b77ea9..ddaac14197ab43ed69d72f426dbc4df046080874 100644 |
--- a/cc/layers/viewport.cc |
+++ b/cc/layers/viewport.cc |
@@ -64,6 +64,68 @@ Viewport::ScrollResult Viewport::ScrollBy(const gfx::Vector2dF& delta, |
return result; |
} |
+bool Viewport::ShouldAnimateViewport(const gfx::Vector2dF& viewport_delta, |
+ const gfx::Vector2dF& pending_delta) { |
+ float max_dim_viewport_delta = |
+ std::abs(viewport_delta.x()) > std::abs(viewport_delta.y()) |
+ ? viewport_delta.x() |
+ : viewport_delta.y(); |
+ float max_dim_pending_delta = |
+ std::abs(pending_delta.x()) > std::abs(pending_delta.y()) |
+ ? pending_delta.x() |
+ : pending_delta.y(); |
+ return std::abs(max_dim_viewport_delta) > std::abs(max_dim_pending_delta); |
bokan
2016/04/06 13:35:52
If you want to animate the viewport which will scr
ymalik
2016/04/06 15:33:45
I think the animation duration is determined by th
bokan
2016/04/06 19:38:23
Ok, this is fine then. IMO, std::max(viewport_delt
|
+} |
+ |
+gfx::Vector2dF Viewport::ScrollAnimated(const gfx::Vector2dF& delta) { |
+ ScrollTree& scroll_tree = |
+ host_impl_->active_tree()->property_trees()->scroll_tree; |
+ |
+ float scale_factor = host_impl_->active_tree()->current_page_scale_factor(); |
+ gfx::Vector2dF scaled_delta = delta; |
+ scaled_delta.Scale(1.f / scale_factor); |
+ |
+ ScrollNode* inner_node = |
+ scroll_tree.Node(InnerScrollLayer()->scroll_tree_index()); |
+ LayerTreeHostImpl::ScrollAmount inner_scroll = |
+ host_impl_->ComputeScrollDelta(inner_node, delta); |
+ |
+ // Animate the viewport to which the majority of scroll delta will be applied. |
+ // The animation system only supports running one scroll offset animation. |
+ gfx::Vector2dF pending_delta = scaled_delta - inner_scroll.delta; |
+ bool animating_inner_viewport = |
+ ShouldAnimateViewport(inner_scroll.delta, pending_delta); |
bokan
2016/04/06 13:35:52
Shouldn't this compare inner_scroll.delta to outer
ymalik
2016/04/06 15:33:45
Yes, you're right! Done.
|
+ pending_delta.Scale(scale_factor); |
+ |
+ ScrollNode* outer_node = |
+ scroll_tree.Node(OuterScrollLayer()->scroll_tree_index()); |
+ LayerTreeHostImpl::ScrollAmount outer_scroll = |
+ host_impl_->ComputeScrollDelta(outer_node, pending_delta); |
+ |
+ if (inner_scroll.delta.IsZero() && outer_scroll.delta.IsZero()) |
+ return gfx::Vector2dF(0, 0); |
+ |
+ bool will_animate = false; |
+ if (animating_inner_viewport) { |
+ scroll_tree.ScrollBy(outer_node, outer_scroll.delta, |
bokan
2016/04/06 13:35:52
Won't this cause a visible "jump"? I would guess t
ymalik
2016/04/06 15:33:45
The jump doesn't look terribly bad IMO. It also on
bokan
2016/04/06 19:38:23
Acknowledged.
|
+ host_impl_->active_tree()); |
+ will_animate = host_impl_->ScrollAnimationCreate(inner_node, inner_scroll); |
+ } else { |
+ scroll_tree.ScrollBy(inner_node, inner_scroll.delta, |
+ host_impl_->active_tree()); |
+ will_animate = host_impl_->ScrollAnimationCreate(outer_node, outer_scroll); |
+ } |
+ |
+ if (will_animate) { |
+ // Consume entire scroll delta as long as we are starting an animation. |
+ return delta; |
+ } |
+ |
+ pending_delta = scaled_delta - inner_scroll.delta - outer_scroll.delta; |
+ pending_delta.Scale(scale_factor); |
+ return pending_delta; |
+} |
+ |
void Viewport::SnapPinchAnchorIfWithinMargin(const gfx::Point& anchor) { |
gfx::SizeF viewport_size = gfx::SizeF( |
host_impl_->active_tree()->InnerViewportContainerLayer()->bounds()); |