File size: 4,858 Bytes
22c7264 8755ee2 a47eab3 8755ee2 5d08a61 0aebd1a 27c03db bcf9be5 0aebd1a 5829a93 22c7264 37f5ac4 22c7264 97eb6a7 22c7264 8755ee2 97eb6a7 dc1e1c1 22c7264 dc1e1c1 22c7264 8755ee2 a47eab3 8755ee2 fe79342 5aa283f 27c03db 22c7264 ede8cb9 22c7264 8755ee2 bcf9be5 22c7264 27c03db bcf9be5 fe79342 5d08a61 fe79342 22c7264 22fca24 27c03db 8755ee2 37f5ac4 33909e6 5d08a61 f898881 27c03db 33909e6 24dfcae dc1e1c1 37f5ac4 bcf9be5 a47eab3 8755ee2 bcf9be5 22c7264 dc1e1c1 bcf9be5 24dfcae dc1e1c1 24dfcae b1c5f8c 24dfcae bcf9be5 dc1e1c1 24dfcae 22c7264 dc1e1c1 bb8be8c 8755ee2 a47eab3 8755ee2 bb8be8c f898881 bb8be8c 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 154 155 156 |
import Position from './position';
/**
* 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.highlightedPosition = new Position({}); // position at which layover is patched currently
this.highlightedElement = null; // currently highlighted dom element (instance of Element)
this.lastHighlightedElement = null; // element that was highlighted before current one
this.draw = this.draw.bind(this); // To pass the context of class, as it is to be used in redraw animation callback
this.window = window;
this.document = document;
this.resetOverlay();
}
/**
* Prepares the overlay
*/
resetOverlay() {
// @todo: append the elements if not there already
this.pageOverlay = this.document.getElementById('driver-page-overlay');
this.highlightStage = this.document.getElementById('driver-highlighted-element-stage');
}
/**
* Highlights the dom element on the screen
* @param {Element} element
* @param {boolean} animate
*/
highlight(element, animate = true) {
if (!element || !element.node) {
console.warn('Invalid element to highlight. Must be an instance of `Element`');
return;
}
// 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;
// If animation is not required then set the last path to be same
// as the current path so that there is no easing towards it
if (!this.options.animate || !animate) {
this.highlightedPosition = this.positionToHighlight;
}
this.draw();
}
/**
* 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.pageOverlay.style.opacity = '0';
this.highlightStage.style.display = 'none';
}
/**
* `draw` is called for every frame . Puts back the
* filled overlay on body (i.e. while removing existing highlight if any) and
* Slowly eases towards the item to be selected.
*/
draw() {
if (!this.highlightedElement || !this.positionToHighlight.canHighlight()) {
return;
}
// Make it two times the padding because, half will be given on left and half on right
const requiredPadding = this.options.padding * 2;
// Show the overlay
this.pageOverlay.style.opacity = `${this.options.opacity}`;
const width = (this.positionToHighlight.right - this.positionToHighlight.left) + (requiredPadding);
const height = (this.positionToHighlight.bottom - this.positionToHighlight.top) + (requiredPadding);
// Show the stage
this.highlightStage.style.display = 'block';
this.highlightStage.style.position = 'absolute';
this.highlightStage.style.width = `${width}px`;
this.highlightStage.style.height = `${height}px`;
this.highlightStage.style.top = `${this.positionToHighlight.top - (requiredPadding / 2)}px`;
this.highlightStage.style.left = `${this.positionToHighlight.left - (requiredPadding / 2)}px`;
// Element has been highlighted
this.highlightedElement.onHighlighted();
}
/**
* Refreshes the overlay i.e. sets the size according to current window size
* And moves the highlight around if necessary
*
* @param {boolean} animate
*/
refresh(animate = true) {
// 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, animate);
this.highlightedElement.onHighlighted();
}
}
}
|