File size: 4,088 Bytes
22c7264 c7fb12b f3edffc 22c7264 8755ee2 a47eab3 bdfd65a a47eab3 8755ee2 bdfd65a 5d08a61 0aebd1a 27c03db c7fb12b 5829a93 22c7264 37f5ac4 bdfd65a 22c7264 bdfd65a 22c7264 8755ee2 bdfd65a 22c7264 bdfd65a 22c7264 8755ee2 a47eab3 8755ee2 f3edffc 5aa283f 27c03db 22c7264 c7fb12b ede8cb9 22c7264 8755ee2 bcf9be5 22c7264 27c03db bcf9be5 fe79342 c7fb12b 22c7264 22fca24 27c03db 8755ee2 37f5ac4 33909e6 5d08a61 f898881 27c03db 33909e6 c7fb12b bdfd65a 37f5ac4 8755ee2 c7fb12b f898881 c7fb12b ede8cb9 f898881 22c7264 |
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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
import Position from './position';
import { ANIMATION_DURATION_MS, ID_OVERLAY, OVERLAY_HTML } from '../common/constants';
import { createNodeFromString } from '../common/utils';
/**
* Responsible for overlay creation and manipulation i.e.
* cutting out the visible part, animating between the sections etc
*/
export default class Overlay {
/**
* @param {Object} options
* @param {Window} window
* @param {Stage} stage
* @param {Document} document
*/
constructor(options, stage, window, document) {
this.options = options;
this.positionToHighlight = new Position({}); // position at which layover is to be patched at
this.highlightedElement = null; // currently highlighted dom element (instance of Element)
this.lastHighlightedElement = null; // element that was highlighted before current one
this.hideTimer = null;
this.window = window;
this.document = document;
this.stage = stage;
this.makeNode();
}
/**
* Prepares the overlay
*/
makeNode() {
let pageOverlay = this.document.getElementById(ID_OVERLAY);
if (!pageOverlay) {
pageOverlay = createNodeFromString(OVERLAY_HTML);
document.body.appendChild(pageOverlay);
}
this.node = pageOverlay;
}
/**
* Highlights the dom element on the screen
* @param {Element} element
* @param {boolean} animate
*/
highlight(element) {
if (!element || !element.node) {
console.warn('Invalid element to highlight. Must be an instance of `Element`');
return;
}
// There might be hide timer from last time
// which might be getting triggered
this.window.clearTimeout(this.hideTimer);
// Trigger the hook for highlight started
element.onHighlightStarted();
// Old element has been deselected
if (this.highlightedElement) {
this.highlightedElement.onDeselected();
}
// get the position of element around which we need to draw
const position = element.getCalculatedPosition();
if (!position.canHighlight()) {
return;
}
this.lastHighlightedElement = this.highlightedElement;
this.highlightedElement = element;
this.positionToHighlight = position;
this.showOverlay();
// Show the stage
this.stage.show(this.positionToHighlight);
// Element has been highlighted
this.highlightedElement.onHighlighted();
}
showOverlay() {
this.node.style.opacity = `${this.options.opacity}`;
this.node.style.position = 'fixed';
this.node.style.left = '0';
this.node.style.top = '0';
this.node.style.bottom = '0';
this.node.style.right = '0';
}
hideOverlay() {
this.node.style.opacity = '0';
this.hideTimer = window.setTimeout(() => {
this.node.style.position = 'absolute';
this.node.style.left = '';
this.node.style.top = '';
this.node.style.bottom = '';
this.node.style.right = '';
}, ANIMATION_DURATION_MS);
}
/**
* Returns the currently selected element
* @returns {null|*}
*/
getHighlightedElement() {
return this.highlightedElement;
}
/**
* Gets the element that was highlighted before current element
* @returns {null|*}
*/
getLastHighlightedElement() {
return this.lastHighlightedElement;
}
/**
* Removes the overlay and cancel any listeners
*/
clear() {
this.positionToHighlight = new Position();
if (this.highlightedElement) {
this.highlightedElement.onDeselected();
}
this.highlightedElement = null;
this.lastHighlightedElement = null;
this.hideOverlay();
this.stage.hide();
}
/**
* Refreshes the overlay i.e. sets the size according to current window size
* And moves the highlight around if necessary
*/
refresh() {
// If the highlighted element was there Cancel the
// existing animation frame if any and highlight it again
// as its position might have been changed
if (this.highlightedElement) {
this.highlight(this.highlightedElement);
this.highlightedElement.onHighlighted();
}
}
}
|