-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
Copy pathviewportAndViewability.js
76 lines (59 loc) · 2.27 KB
/
viewportAndViewability.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import {getWindowTop} from '../../src/utils.js';
function getBoundingBox(element, {w, h} = {}) {
let {width, height, left, top, right, bottom} = element.getBoundingClientRect();
if ((width === 0 || height === 0) && w && h) {
width = w;
height = h;
right = left + w;
bottom = top + h;
}
return {width, height, left, top, right, bottom};
}
function getIntersectionOfRects(rects) {
const bbox = {
left: rects[0].left, right: rects[0].right, top: rects[0].top, bottom: rects[0].bottom
};
for (let i = 1; i < rects.length; ++i) {
bbox.left = Math.max(bbox.left, rects[i].left);
bbox.right = Math.min(bbox.right, rects[i].right);
if (bbox.left >= bbox.right) {
return null;
}
bbox.top = Math.max(bbox.top, rects[i].top);
bbox.bottom = Math.min(bbox.bottom, rects[i].bottom);
if (bbox.top >= bbox.bottom) {
return null;
}
}
bbox.width = bbox.right - bbox.left;
bbox.height = bbox.bottom - bbox.top;
return bbox;
}
export const percentInView = (element, topWin, {w, h} = {}) => {
const elementBoundingBox = getBoundingBox(element, {w, h});
// Obtain the intersection of the element and the viewport
const elementInViewBoundingBox = getIntersectionOfRects([{
left: 0, top: 0, right: topWin.innerWidth, bottom: topWin.innerHeight
}, elementBoundingBox]);
let elementInViewArea, elementTotalArea;
if (elementInViewBoundingBox !== null) {
// Some or all of the element is in view
elementInViewArea = elementInViewBoundingBox.width * elementInViewBoundingBox.height;
elementTotalArea = elementBoundingBox.width * elementBoundingBox.height;
return ((elementInViewArea / elementTotalArea) * 100);
}
// No overlap between element and the viewport; therefore, the element
// lies completely out of view
return 0;
}
export function getViewportCoordinates() {
try {
const win = getWindowTop();
let { scrollY: top, scrollX: left, innerHeight, innerWidth } = win;
innerHeight = innerHeight || win.document.documentElement.clientWidth || win.document.body.clientWidth;
innerWidth = innerWidth || win.document.documentElement.clientHeight || win.document.body.clientHeight
return { top, right: left + innerWidth, bottom: top + innerHeight, left };
} catch (e) {
return {};
}
}