File size: 4,421 Bytes
22c7264 0797fb7 f3edffc 22c7264 8755ee2 a47eab3 8755ee2 a174130 5d08a61 0aebd1a 27c03db c7fb12b 5829a93 22c7264 37f5ac4 22c7264 8755ee2 bdfd65a 22c7264 bdfd65a 9eea97b 0797fb7 22c7264 8755ee2 a47eab3 8755ee2 f3edffc 5aa283f 27c03db 22c7264 a174130 3a2c734 a174130 c7fb12b ede8cb9 a174130 ede8cb9 22c7264 8755ee2 bcf9be5 22c7264 27c03db bcf9be5 fe79342 0797fb7 c7fb12b 0797fb7 9eea97b c7fb12b 9eea97b c7fb12b 22c7264 22fca24 27c03db 8755ee2 37f5ac4 33909e6 5d08a61 a174130 5d08a61 f898881 27c03db 33909e6 c7fb12b 37f5ac4 8755ee2 c7fb12b a174130 f898881 a174130 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 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
import Position from './position';
import { ANIMATION_DURATION_MS, CLASS_NO_ANIMATION, 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 {Document} document
*/
constructor(options, 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;
}
/**
* Prepares the overlay
*/
makeNode() {
let pageOverlay = this.document.getElementById(ID_OVERLAY);
if (!pageOverlay) {
pageOverlay = createNodeFromString(OVERLAY_HTML);
document.body.appendChild(pageOverlay);
}
this.node = pageOverlay;
this.node.style.opacity = '0';
if (!this.options.animate) {
this.node.classList.add(CLASS_NO_ANIMATION);
} else {
this.node.classList.remove(CLASS_NO_ANIMATION);
}
}
/**
* Highlights the dom element on the screen
* @param {Element} element
*/
highlight(element) {
if (!element || !element.node) {
console.warn('Invalid element to highlight. Must be an instance of `Element`');
return;
}
// If highlighted element is not changed from last time
if (element.isSame(this.highlightedElement)) {
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.isSame(this.lastHighlightedElement)) {
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.show();
// Element has been highlighted
this.highlightedElement.onHighlighted();
}
show() {
if (this.node && this.node.parentElement) {
return;
}
this.makeNode();
window.setTimeout(() => {
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 = '';
this.node.parentElement.removeChild(this.node);
}, 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(true);
}
this.highlightedElement = null;
this.lastHighlightedElement = null;
this.hideOverlay();
}
/**
* Refreshes the overlay i.e. sets the size according to current window size
* And moves the highlight around if necessary
*/
refresh() {
// If no highlighted element, cancel the refresh
if (!this.highlightedElement) {
return;
}
// Reposition the stage and show popover
this.highlightedElement.showPopover();
this.highlightedElement.showStage();
}
}
|