OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stddef.h> | 5 #include <stddef.h> |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
341 CombineTransformsBetween(dest_id, source_id, &dest_to_source); | 341 CombineTransformsBetween(dest_id, source_id, &dest_to_source); |
342 gfx::Transform source_to_dest; | 342 gfx::Transform source_to_dest; |
343 bool all_are_invertible = dest_to_source.GetInverse(&source_to_dest); | 343 bool all_are_invertible = dest_to_source.GetInverse(&source_to_dest); |
344 transform->PreconcatTransform(source_to_dest); | 344 transform->PreconcatTransform(source_to_dest); |
345 return all_are_invertible; | 345 return all_are_invertible; |
346 } | 346 } |
347 | 347 |
348 gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) { | 348 gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) { |
349 if (node->sticky_position_constraint_id == -1) | 349 if (node->sticky_position_constraint_id == -1) |
350 return gfx::Vector2dF(); | 350 return gfx::Vector2dF(); |
351 const StickyPositionNodeData* sticky_data = | 351 StickyPositionNodeData* sticky_data = tree->StickyPositionData(node->id); |
352 tree->StickyPositionData(node->id); | |
353 const LayerStickyPositionConstraint& constraint = sticky_data->constraints; | 352 const LayerStickyPositionConstraint& constraint = sticky_data->constraints; |
354 ScrollNode* scroll_node = | 353 ScrollNode* scroll_node = |
355 tree->property_trees()->scroll_tree.Node(sticky_data->scroll_ancestor); | 354 tree->property_trees()->scroll_tree.Node(sticky_data->scroll_ancestor); |
356 gfx::ScrollOffset scroll_offset = | 355 gfx::ScrollOffset scroll_offset = |
357 tree->property_trees()->scroll_tree.current_scroll_offset( | 356 tree->property_trees()->scroll_tree.current_scroll_offset( |
358 scroll_node->owning_layer_id); | 357 scroll_node->owning_layer_id); |
359 gfx::PointF scroll_position(scroll_offset.x(), scroll_offset.y()); | 358 gfx::PointF scroll_position(scroll_offset.x(), scroll_offset.y()); |
360 TransformNode* scroll_ancestor_transform_node = | 359 TransformNode* scroll_ancestor_transform_node = |
361 tree->Node(scroll_node->transform_id); | 360 tree->Node(scroll_node->transform_id); |
362 if (scroll_ancestor_transform_node->scrolls) { | 361 if (scroll_ancestor_transform_node->scrolls) { |
363 // The scroll position does not include snapping which shifts the scroll | 362 // The scroll position does not include snapping which shifts the scroll |
364 // offset to align to a pixel boundary, we need to manually include it here. | 363 // offset to align to a pixel boundary, we need to manually include it here. |
365 // In this case, snapping is caused by a scroll. | 364 // In this case, snapping is caused by a scroll. |
366 scroll_position -= scroll_ancestor_transform_node->snap_amount; | 365 scroll_position -= scroll_ancestor_transform_node->snap_amount; |
367 } | 366 } |
368 | 367 |
369 gfx::RectF clip( | 368 gfx::RectF clip( |
370 scroll_position, | 369 scroll_position, |
371 gfx::SizeF(tree->property_trees()->scroll_tree.scroll_clip_layer_bounds( | 370 gfx::SizeF(tree->property_trees()->scroll_tree.scroll_clip_layer_bounds( |
372 scroll_node->id))); | 371 scroll_node->id))); |
373 gfx::Vector2dF sticky_offset( | |
374 constraint.scroll_container_relative_sticky_box_rect.OffsetFromOrigin()); | |
375 gfx::Vector2dF layer_offset(sticky_data->main_thread_offset); | 372 gfx::Vector2dF layer_offset(sticky_data->main_thread_offset); |
376 | 373 |
374 gfx::Vector2dF ancestor_sticky_box_offset; | |
375 if (sticky_data->nearest_node_shifting_sticky_box != | |
376 TransformTree::kInvalidNodeId) { | |
377 ancestor_sticky_box_offset = | |
378 tree->StickyPositionData(sticky_data->nearest_node_shifting_sticky_box) | |
379 ->total_sticky_box_sticky_offset; | |
380 } | |
381 | |
382 gfx::Vector2dF ancestor_containing_block_offset; | |
383 if (sticky_data->nearest_node_shifting_containing_block != | |
384 TransformTree::kInvalidNodeId) { | |
385 ancestor_containing_block_offset = | |
386 tree->StickyPositionData( | |
387 sticky_data->nearest_node_shifting_containing_block) | |
388 ->total_containing_block_sticky_offset; | |
389 } | |
390 | |
391 // Compute the current position of the constraint rects based on the original | |
392 // positions and the offsets from ancestor sticky elements. | |
393 gfx::RectF sticky_box_rect = | |
394 gfx::RectF(constraint.scroll_container_relative_sticky_box_rect) + | |
395 ancestor_sticky_box_offset + ancestor_containing_block_offset; | |
396 gfx::RectF containing_block_rect = | |
397 gfx::RectF(constraint.scroll_container_relative_containing_block_rect) + | |
398 ancestor_containing_block_offset; | |
chrishtr
2017/03/21 23:26:05
Your code adds on an offset from the ancestor stic
smcgruer
2017/03/22 15:15:03
If I understand correctly, you are asking about an
| |
399 | |
400 gfx::Vector2dF sticky_offset(sticky_box_rect.OffsetFromOrigin()); | |
401 | |
377 // In each of the following cases, we measure the limit which is the point | 402 // In each of the following cases, we measure the limit which is the point |
378 // that the element should stick to, clamping on one side to 0 (because sticky | 403 // that the element should stick to, clamping on one side to 0 (because sticky |
379 // only pushes elements in one direction). Then we clamp to how far we can | 404 // only pushes elements in one direction). Then we clamp to how far we can |
380 // push the element in that direction without being pushed outside of its | 405 // push the element in that direction without being pushed outside of its |
381 // containing block. | 406 // containing block. |
382 // | 407 // |
383 // Note: The order of applying the sticky constraints is applied such that | 408 // Note: The order of applying the sticky constraints is applied such that |
384 // left offset takes precedence over right offset, and top takes precedence | 409 // left offset takes precedence over right offset, and top takes precedence |
385 // over bottom offset. | 410 // over bottom offset. |
386 if (constraint.is_anchored_right) { | 411 if (constraint.is_anchored_right) { |
387 float right_limit = clip.right() - constraint.right_offset; | 412 float right_limit = clip.right() - constraint.right_offset; |
388 float right_delta = std::min<float>( | 413 float right_delta = |
389 0, right_limit - | 414 std::min<float>(0, right_limit - sticky_box_rect.right()); |
390 constraint.scroll_container_relative_sticky_box_rect.right()); | 415 float available_space = |
391 float available_space = std::min<float>( | 416 std::min<float>(0, containing_block_rect.x() - sticky_box_rect.x()); |
392 0, constraint.scroll_container_relative_containing_block_rect.x() - | |
393 constraint.scroll_container_relative_sticky_box_rect.x()); | |
394 if (right_delta < available_space) | 417 if (right_delta < available_space) |
395 right_delta = available_space; | 418 right_delta = available_space; |
396 sticky_offset.set_x(sticky_offset.x() + right_delta); | 419 sticky_offset.set_x(sticky_offset.x() + right_delta); |
397 } | 420 } |
398 if (constraint.is_anchored_left) { | 421 if (constraint.is_anchored_left) { |
399 float left_limit = clip.x() + constraint.left_offset; | 422 float left_limit = clip.x() + constraint.left_offset; |
400 float left_delta = std::max<float>( | 423 float left_delta = std::max<float>(0, left_limit - sticky_box_rect.x()); |
401 0, | |
402 left_limit - constraint.scroll_container_relative_sticky_box_rect.x()); | |
403 float available_space = std::max<float>( | 424 float available_space = std::max<float>( |
404 0, constraint.scroll_container_relative_containing_block_rect.right() - | 425 0, containing_block_rect.right() - sticky_box_rect.right()); |
405 constraint.scroll_container_relative_sticky_box_rect.right()); | |
406 if (left_delta > available_space) | 426 if (left_delta > available_space) |
407 left_delta = available_space; | 427 left_delta = available_space; |
408 sticky_offset.set_x(sticky_offset.x() + left_delta); | 428 sticky_offset.set_x(sticky_offset.x() + left_delta); |
409 } | 429 } |
410 if (constraint.is_anchored_bottom) { | 430 if (constraint.is_anchored_bottom) { |
411 float bottom_limit = clip.bottom() - constraint.bottom_offset; | 431 float bottom_limit = clip.bottom() - constraint.bottom_offset; |
412 float bottom_delta = std::min<float>( | 432 float bottom_delta = |
413 0, bottom_limit - | 433 std::min<float>(0, bottom_limit - sticky_box_rect.bottom()); |
414 constraint.scroll_container_relative_sticky_box_rect.bottom()); | 434 float available_space = |
415 float available_space = std::min<float>( | 435 std::min<float>(0, containing_block_rect.y() - sticky_box_rect.y()); |
416 0, constraint.scroll_container_relative_containing_block_rect.y() - | |
417 constraint.scroll_container_relative_sticky_box_rect.y()); | |
418 if (bottom_delta < available_space) | 436 if (bottom_delta < available_space) |
419 bottom_delta = available_space; | 437 bottom_delta = available_space; |
420 sticky_offset.set_y(sticky_offset.y() + bottom_delta); | 438 sticky_offset.set_y(sticky_offset.y() + bottom_delta); |
421 } | 439 } |
422 if (constraint.is_anchored_top) { | 440 if (constraint.is_anchored_top) { |
423 float top_limit = clip.y() + constraint.top_offset; | 441 float top_limit = clip.y() + constraint.top_offset; |
424 float top_delta = std::max<float>( | 442 float top_delta = std::max<float>(0, top_limit - sticky_box_rect.y()); |
425 0, | |
426 top_limit - constraint.scroll_container_relative_sticky_box_rect.y()); | |
427 float available_space = std::max<float>( | 443 float available_space = std::max<float>( |
428 0, constraint.scroll_container_relative_containing_block_rect.bottom() - | 444 0, containing_block_rect.bottom() - sticky_box_rect.bottom()); |
429 constraint.scroll_container_relative_sticky_box_rect.bottom()); | |
430 if (top_delta > available_space) | 445 if (top_delta > available_space) |
431 top_delta = available_space; | 446 top_delta = available_space; |
432 sticky_offset.set_y(sticky_offset.y() + top_delta); | 447 sticky_offset.set_y(sticky_offset.y() + top_delta); |
433 } | 448 } |
449 | |
450 sticky_data->total_sticky_box_sticky_offset = | |
451 ancestor_sticky_box_offset + sticky_offset - | |
452 sticky_box_rect.OffsetFromOrigin(); | |
453 sticky_data->total_containing_block_sticky_offset = | |
454 ancestor_sticky_box_offset + ancestor_containing_block_offset + | |
455 sticky_offset - sticky_box_rect.OffsetFromOrigin(); | |
456 | |
434 return sticky_offset - layer_offset - node->source_to_parent - | 457 return sticky_offset - layer_offset - node->source_to_parent - |
435 constraint.scroll_container_relative_sticky_box_rect | 458 sticky_box_rect.OffsetFromOrigin(); |
436 .OffsetFromOrigin(); | |
437 } | 459 } |
438 | 460 |
439 void TransformTree::UpdateLocalTransform(TransformNode* node) { | 461 void TransformTree::UpdateLocalTransform(TransformNode* node) { |
440 gfx::Transform transform = node->post_local; | 462 gfx::Transform transform = node->post_local; |
441 if (NeedsSourceToParentUpdate(node)) { | 463 if (NeedsSourceToParentUpdate(node)) { |
442 gfx::Transform to_parent; | 464 gfx::Transform to_parent; |
443 ComputeTranslation(node->source_node_id, node->parent_id, &to_parent); | 465 ComputeTranslation(node->source_node_id, node->parent_id, &to_parent); |
444 gfx::Vector2dF unsnapping; | 466 gfx::Vector2dF unsnapping; |
445 TransformNode* current; | 467 TransformNode* current; |
446 TransformNode* parent_node; | 468 TransformNode* parent_node; |
(...skipping 1635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2082 const EffectNode* effect_node = effect_tree.Node(effect_id); | 2104 const EffectNode* effect_node = effect_tree.Node(effect_id); |
2083 | 2105 |
2084 if (effect_node->surface_contents_scale.x() != 0.0 && | 2106 if (effect_node->surface_contents_scale.x() != 0.0 && |
2085 effect_node->surface_contents_scale.y() != 0.0) | 2107 effect_node->surface_contents_scale.y() != 0.0) |
2086 screen_space_transform.Scale(1.0 / effect_node->surface_contents_scale.x(), | 2108 screen_space_transform.Scale(1.0 / effect_node->surface_contents_scale.x(), |
2087 1.0 / effect_node->surface_contents_scale.y()); | 2109 1.0 / effect_node->surface_contents_scale.y()); |
2088 return screen_space_transform; | 2110 return screen_space_transform; |
2089 } | 2111 } |
2090 | 2112 |
2091 } // namespace cc | 2113 } // namespace cc |
OLD | NEW |