kamrify commited on
Commit
095d0ef
·
1 Parent(s): 28c1a4b

Bring element to view if not in view

Browse files
assets/scripts/src/element.js CHANGED
@@ -34,6 +34,40 @@ export default class Element {
34
  return { x, y };
35
  }
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  /**
38
  * Gets the calculated position on screen, around which
39
  * we need to draw
@@ -82,17 +116,17 @@ export default class Element {
82
 
83
  const popoverTip = this.popover.querySelector('.sholo-popover-tip');
84
 
85
- const documentHeight = this.getDocumentHeight();
86
  const popoverHeight = this.getPopoverHeight();
87
  const popoverMargin = this.options.padding + 10;
88
 
89
  this.popover.style.left = `${position.left - this.options.padding}px`;
90
 
91
  // Calculate different dimensions after attaching popover
92
- const documentHeightAfterPopOver = position.bottom + popoverHeight + popoverMargin;
93
 
94
  // If adding popover would go out of the window height, then show it to the top
95
- if (documentHeightAfterPopOver >= documentHeight) {
96
  this.popover.style.top = `${position.top - popoverHeight - popoverMargin}px`;
97
  popoverTip.classList.add('bottom');
98
  } else {
@@ -113,12 +147,15 @@ export default class Element {
113
  this.popover.style.display = 'none';
114
  }
115
 
116
- getDocumentHeight() {
117
  // eslint-disable-next-line prefer-destructuring
118
  const body = this.document.body;
119
  const html = this.document.documentElement;
120
 
121
- return Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
 
 
 
122
  }
123
 
124
  getPopoverHeight() {
 
34
  return { x, y };
35
  }
36
 
37
+ isInView() {
38
+ let top = this.node.offsetTop;
39
+ let left = this.node.offsetLeft;
40
+ const width = this.node.offsetWidth;
41
+ const height = this.node.offsetHeight;
42
+
43
+ let el = this.node;
44
+
45
+ while (el.offsetParent) {
46
+ el = el.offsetParent;
47
+ top += el.offsetTop;
48
+ left += el.offsetLeft;
49
+ }
50
+
51
+ return (
52
+ top >= this.window.pageYOffset &&
53
+ left >= this.window.pageXOffset &&
54
+ (top + height) <= (this.window.pageYOffset + this.window.innerHeight) &&
55
+ (left + width) <= (this.window.pageXOffset + this.window.innerWidth)
56
+ );
57
+ }
58
+
59
+ bringInView() {
60
+ if (this.isInView()) {
61
+ return;
62
+ }
63
+
64
+ const elementRect = this.getCalculatedPosition();
65
+ const absoluteElementTop = elementRect.top + window.pageYOffset;
66
+ const middle = absoluteElementTop - (window.innerHeight / 2);
67
+
68
+ window.scrollTo(0, middle);
69
+ }
70
+
71
  /**
72
  * Gets the calculated position on screen, around which
73
  * we need to draw
 
116
 
117
  const popoverTip = this.popover.querySelector('.sholo-popover-tip');
118
 
119
+ const pageHeight = this.getFullPageSize().height;
120
  const popoverHeight = this.getPopoverHeight();
121
  const popoverMargin = this.options.padding + 10;
122
 
123
  this.popover.style.left = `${position.left - this.options.padding}px`;
124
 
125
  // Calculate different dimensions after attaching popover
126
+ const pageHeightAfterPopOver = position.bottom + popoverHeight + popoverMargin;
127
 
128
  // If adding popover would go out of the window height, then show it to the top
129
+ if (pageHeightAfterPopOver >= pageHeight) {
130
  this.popover.style.top = `${position.top - popoverHeight - popoverMargin}px`;
131
  popoverTip.classList.add('bottom');
132
  } else {
 
147
  this.popover.style.display = 'none';
148
  }
149
 
150
+ getFullPageSize() {
151
  // eslint-disable-next-line prefer-destructuring
152
  const body = this.document.body;
153
  const html = this.document.documentElement;
154
 
155
+ return {
156
+ height: Math.max(body.scrollHeight, body.offsetHeight, html.scrollHeight, html.offsetHeight),
157
+ width: Math.max(body.scrollWidth, body.offsetWidth, html.scrollWidth, html.offsetWidth),
158
+ };
159
  }
160
 
161
  getPopoverHeight() {
assets/scripts/src/sholo.js CHANGED
@@ -72,12 +72,22 @@ export default class Sholo {
72
  const prevClicked = e.target.classList.contains('sholo-prev-btn');
73
  const closeClicked = e.target.classList.contains('sholo-close-btn');
74
 
 
 
 
 
 
75
  if (nextClicked) {
76
  this.moveNext();
77
  } else if (prevClicked) {
78
  this.movePrevious();
79
- } else if (closeClicked) {
80
- this.reset();
 
 
 
 
 
81
  }
82
  }
83
 
 
72
  const prevClicked = e.target.classList.contains('sholo-prev-btn');
73
  const closeClicked = e.target.classList.contains('sholo-close-btn');
74
 
75
+ if (closeClicked) {
76
+ this.reset();
77
+ return;
78
+ }
79
+
80
  if (nextClicked) {
81
  this.moveNext();
82
  } else if (prevClicked) {
83
  this.movePrevious();
84
+ }
85
+
86
+ // @todo - move to onHighlighted hook and add the check if not visible then do this
87
+ if (this.overlay.highlightedElement) {
88
+ window.setTimeout(() => {
89
+ this.overlay.highlightedElement.bringInView();
90
+ }, 800);
91
  }
92
  }
93
 
index.html CHANGED
@@ -77,6 +77,8 @@
77
 
78
  sholo.defineSteps([
79
  { element: '.section__header' },
 
 
80
  { element: '.section__examples' },
81
  { element: '.section__contributing' },
82
  ]);
 
77
 
78
  sholo.defineSteps([
79
  { element: '.section__header' },
80
+ { element: '.section__how' },
81
+ { element: '.section__purpose' },
82
  { element: '.section__examples' },
83
  { element: '.section__contributing' },
84
  ]);