fix(overlay): incorrectly calculating centered position on a scrolled page with pushing (#13185)

Fixes a centered flexible overlay with pushing, on a scrolled page, not calculating the position properly. There were a couple of issues:
* We were using the `top` viewport offset to calculate along the X axis, as well as `left` to calculate along Y.
* We weren't accounting correctly for the scroll position.

Fixes #11868.
This commit is contained in:
Kristiyan Kostadinov
2018-10-02 22:27:51 +02:00
committed by vivian-hu
parent 38e7dd24cf
commit f5dd24aab5
2 changed files with 45 additions and 6 deletions
@@ -1744,6 +1744,40 @@ describe('FlexibleConnectedPositionStrategy', () => {
expect(Math.floor(overlayRect.top)).toBe(viewportMargin);
});
it('should center flexible overlay with push on a scrolled page', () => {
const veryLargeElement = document.createElement('div');
originElement.style.left = '200px';
originElement.style.top = '200px';
veryLargeElement.style.width = '100%';
veryLargeElement.style.height = '2000px';
document.body.appendChild(veryLargeElement);
window.scroll(0, 250);
positionStrategy
.withFlexibleDimensions()
.withPush(true)
.withPositions([{
overlayY: 'top',
overlayX: 'center',
originY: 'bottom',
originX: 'center'
}]);
attachOverlay({positionStrategy});
const overlayRect = overlayRef.overlayElement.getBoundingClientRect();
const originRect = originElement.getBoundingClientRect();
expect(Math.floor(overlayRect.left - overlayRect.width / 2))
.toBe(Math.floor(originRect.left - originRect.width / 2));
window.scroll(0, 0);
document.body.removeChild(veryLargeElement);
});
});
describe('onPositionChange with scrollable view properties', () => {
@@ -718,10 +718,13 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
bottom = viewport.height - origin.y + this._viewportMargin * 2;
height = viewport.height - bottom + this._viewportMargin;
} else {
// If neither top nor bottom, it means that the overlay
// is vertically centered on the origin point.
// If neither top nor bottom, it means that the overlay is vertically centered on the
// origin point. Note that we want the position relative to the viewport, rather than
// the page, which is why we don't use something like `viewport.bottom - origin.y` and
// `origin.y - viewport.top`.
const smallestDistanceToViewportEdge =
Math.min(viewport.bottom - origin.y, origin.y - viewport.left);
Math.min(viewport.bottom - origin.y + viewport.top, origin.y);
const previousHeight = this._lastBoundingBoxSize.height;
height = smallestDistanceToViewportEdge * 2;
@@ -751,10 +754,12 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
left = origin.x;
width = viewport.right - origin.x;
} else {
// If neither start nor end, it means that the overlay
// is horizontally centered on the origin point.
// If neither start nor end, it means that the overlay is horizontally centered on the
// origin point. Note that we want the position relative to the viewport, rather than
// the page, which is why we don't use something like `viewport.right - origin.x` and
// `origin.x - viewport.left`.
const smallestDistanceToViewportEdge =
Math.min(viewport.right - origin.x, origin.x - viewport.top);
Math.min(viewport.right - origin.x + viewport.left, origin.x);
const previousWidth = this._lastBoundingBoxSize.width;
width = smallestDistanceToViewportEdge * 2;