Handle animation for the popover
Browse files- src/common/constants.js +3 -1
- src/core/element.js +12 -7
- src/core/overlay.js +3 -10
- src/driver.scss +4 -0
src/common/constants.js
CHANGED
@@ -1,7 +1,6 @@
|
|
1 |
export const OVERLAY_OPACITY = 0.75;
|
2 |
export const OVERLAY_PADDING = 10;
|
3 |
export const OVERLAY_ANIMATE = true;
|
4 |
-
export const OVERLAY_ZINDEX = '999999999';
|
5 |
|
6 |
export const ESC_KEY_CODE = 27;
|
7 |
export const LEFT_KEY_CODE = 37;
|
@@ -20,6 +19,9 @@ export const CLASS_NEXT_STEP_BTN = 'driver-next-btn';
|
|
20 |
export const CLASS_PREV_STEP_BTN = 'driver-prev-btn';
|
21 |
export const CLASS_BTN_DISABLED = 'driver-disabled';
|
22 |
|
|
|
|
|
|
|
23 |
// language=HTML
|
24 |
export const POPOVER_HTML = `
|
25 |
<div id="${ID_POPOVER}">
|
|
|
1 |
export const OVERLAY_OPACITY = 0.75;
|
2 |
export const OVERLAY_PADDING = 10;
|
3 |
export const OVERLAY_ANIMATE = true;
|
|
|
4 |
|
5 |
export const ESC_KEY_CODE = 27;
|
6 |
export const LEFT_KEY_CODE = 37;
|
|
|
19 |
export const CLASS_PREV_STEP_BTN = 'driver-prev-btn';
|
20 |
export const CLASS_BTN_DISABLED = 'driver-disabled';
|
21 |
|
22 |
+
// It must match the one set in the animations in CSS file
|
23 |
+
export const ANIMATION_DURATION_MS = 200;
|
24 |
+
|
25 |
// language=HTML
|
26 |
export const POPOVER_HTML = `
|
27 |
<div id="${ID_POPOVER}">
|
src/core/element.js
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
import Position from './position';
|
|
|
2 |
|
3 |
/**
|
4 |
* Wrapper around DOMElements to enrich them
|
@@ -154,8 +155,6 @@ export default class Element {
|
|
154 |
* this element of has just decided to highlight it
|
155 |
*/
|
156 |
onHighlightStarted() {
|
157 |
-
this.showPopover();
|
158 |
-
|
159 |
// Because element has just started highlighting
|
160 |
// and hasn't completely highlighted
|
161 |
this.highlightFinished = false;
|
@@ -176,15 +175,16 @@ export default class Element {
|
|
176 |
this.highlightFinished = true;
|
177 |
|
178 |
const highlightedElement = this;
|
179 |
-
const lastHighlightedElement = this.overlay.getLastHighlightedElement();
|
180 |
-
const popoverElement = this.popover;
|
181 |
-
|
182 |
const highlightedNode = this.node;
|
|
|
|
|
183 |
const lastHighlightedNode = lastHighlightedElement && lastHighlightedElement.node;
|
184 |
|
185 |
// If this element is not already highlighted (because this call could
|
186 |
// be from the resize or scroll) and is not in view
|
187 |
if (highlightedNode !== lastHighlightedNode) {
|
|
|
|
|
188 |
if (popoverElement && !popoverElement.isInView()) {
|
189 |
popoverElement.bringInView();
|
190 |
}
|
@@ -223,9 +223,14 @@ export default class Element {
|
|
223 |
return;
|
224 |
}
|
225 |
|
226 |
-
const
|
|
|
|
|
|
|
227 |
|
228 |
-
|
|
|
|
|
229 |
}
|
230 |
|
231 |
/**
|
|
|
1 |
import Position from './position';
|
2 |
+
import { ANIMATION_DURATION_MS } from "../common/constants";
|
3 |
|
4 |
/**
|
5 |
* Wrapper around DOMElements to enrich them
|
|
|
155 |
* this element of has just decided to highlight it
|
156 |
*/
|
157 |
onHighlightStarted() {
|
|
|
|
|
158 |
// Because element has just started highlighting
|
159 |
// and hasn't completely highlighted
|
160 |
this.highlightFinished = false;
|
|
|
175 |
this.highlightFinished = true;
|
176 |
|
177 |
const highlightedElement = this;
|
|
|
|
|
|
|
178 |
const highlightedNode = this.node;
|
179 |
+
|
180 |
+
const lastHighlightedElement = this.overlay.getLastHighlightedElement();
|
181 |
const lastHighlightedNode = lastHighlightedElement && lastHighlightedElement.node;
|
182 |
|
183 |
// If this element is not already highlighted (because this call could
|
184 |
// be from the resize or scroll) and is not in view
|
185 |
if (highlightedNode !== lastHighlightedNode) {
|
186 |
+
const popoverElement = this.popover;
|
187 |
+
|
188 |
if (popoverElement && !popoverElement.isInView()) {
|
189 |
popoverElement.bringInView();
|
190 |
}
|
|
|
223 |
return;
|
224 |
}
|
225 |
|
226 |
+
const showAtPosition = this.getCalculatedPosition();
|
227 |
+
|
228 |
+
// For first highlight, show it immediately because there won't be any animation
|
229 |
+
const animationDuration = !this.overlay.lastHighlightedElement ? 0 : ANIMATION_DURATION_MS * 2;
|
230 |
|
231 |
+
window.setTimeout(() => {
|
232 |
+
this.popover.show(showAtPosition);
|
233 |
+
}, animationDuration);
|
234 |
}
|
235 |
|
236 |
/**
|
src/core/overlay.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
import Position from './position';
|
2 |
-
import { ID_OVERLAY, OVERLAY_HTML
|
3 |
-
import { createNodeFromString } from
|
4 |
|
5 |
/**
|
6 |
* Responsible for overlay creation and manipulation i.e.
|
@@ -17,7 +17,6 @@ export default class Overlay {
|
|
17 |
this.options = options;
|
18 |
|
19 |
this.positionToHighlight = new Position({}); // position at which layover is to be patched at
|
20 |
-
this.highlightedPosition = new Position({}); // position at which layover is patched currently
|
21 |
this.highlightedElement = null; // currently highlighted dom element (instance of Element)
|
22 |
this.lastHighlightedElement = null; // element that was highlighted before current one
|
23 |
|
@@ -48,7 +47,7 @@ export default class Overlay {
|
|
48 |
* @param {Element} element
|
49 |
* @param {boolean} animate
|
50 |
*/
|
51 |
-
highlight(element
|
52 |
if (!element || !element.node) {
|
53 |
console.warn('Invalid element to highlight. Must be an instance of `Element`');
|
54 |
return;
|
@@ -72,12 +71,6 @@ export default class Overlay {
|
|
72 |
this.highlightedElement = element;
|
73 |
this.positionToHighlight = position;
|
74 |
|
75 |
-
// If animation is not required then set the last path to be same
|
76 |
-
// as the current path so that there is no easing towards it
|
77 |
-
if (!this.options.animate || !animate) {
|
78 |
-
this.highlightedPosition = this.positionToHighlight;
|
79 |
-
}
|
80 |
-
|
81 |
this.draw();
|
82 |
}
|
83 |
|
|
|
1 |
import Position from './position';
|
2 |
+
import { ID_OVERLAY, OVERLAY_HTML } from '../common/constants';
|
3 |
+
import { createNodeFromString } from '../common/utils';
|
4 |
|
5 |
/**
|
6 |
* Responsible for overlay creation and manipulation i.e.
|
|
|
17 |
this.options = options;
|
18 |
|
19 |
this.positionToHighlight = new Position({}); // position at which layover is to be patched at
|
|
|
20 |
this.highlightedElement = null; // currently highlighted dom element (instance of Element)
|
21 |
this.lastHighlightedElement = null; // element that was highlighted before current one
|
22 |
|
|
|
47 |
* @param {Element} element
|
48 |
* @param {boolean} animate
|
49 |
*/
|
50 |
+
highlight(element) {
|
51 |
if (!element || !element.node) {
|
52 |
console.warn('Invalid element to highlight. Must be an instance of `Element`');
|
53 |
return;
|
|
|
71 |
this.highlightedElement = element;
|
72 |
this.positionToHighlight = position;
|
73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
this.draw();
|
75 |
}
|
76 |
|
src/driver.scss
CHANGED
@@ -118,6 +118,8 @@ div#driver-page-overlay {
|
|
118 |
opacity: 0;
|
119 |
pointer-events: none;
|
120 |
z-index: 100002 !important;
|
|
|
|
|
121 |
-webkit-transition: all 0.2s;
|
122 |
-moz-transition: all 0.2s;
|
123 |
-ms-transition: all 0.2s;
|
@@ -134,6 +136,8 @@ div#driver-highlighted-element-stage {
|
|
134 |
background: white;
|
135 |
z-index: 100003 !important;
|
136 |
display: none;
|
|
|
|
|
137 |
-webkit-transition: all 0.2s;
|
138 |
-moz-transition: all 0.2s;
|
139 |
-ms-transition: all 0.2s;
|
|
|
118 |
opacity: 0;
|
119 |
pointer-events: none;
|
120 |
z-index: 100002 !important;
|
121 |
+
|
122 |
+
// If you update this duration, make sure to update `ANIMATION_DURATION_MS` constant
|
123 |
-webkit-transition: all 0.2s;
|
124 |
-moz-transition: all 0.2s;
|
125 |
-ms-transition: all 0.2s;
|
|
|
136 |
background: white;
|
137 |
z-index: 100003 !important;
|
138 |
display: none;
|
139 |
+
|
140 |
+
// If you update this duration, make sure to update `ANIMATION_DURATION_MS` constant
|
141 |
-webkit-transition: all 0.2s;
|
142 |
-moz-transition: all 0.2s;
|
143 |
-ms-transition: all 0.2s;
|