import Constants from './constants';
class Overlay {
/**
* @constructor
*
*/
constructor(config) {
this.shouldOverlay = config.shouldOverlay === undefined ? true : config.shouldOverlay;
this.overlayColor = config.overlayColor || 'rgba(255,255,255,0.8)';
this.useTransparentOverlayStrategy = !!config.useTransparentOverlayStrategy;
this._resizeHandler = null;
}
isVisible() {
return this.shouldOverlay === false;
}
render() {
if (this.isVisible()) return;
this.$document = $(document);
let $body = $('body');
let $overlay = this._createOverlay();
$body.append($overlay);
this.$overlay = $overlay;
let $transparentOverlay = this._createTransparentOverlay();
$body.append($transparentOverlay);
this.$transparentOverlay = $transparentOverlay;
}
isTransparentOverlayStrategy() {
return this.useTransparentOverlayStrategy;
}
// The following 2 methods are part of the "clone element" strategy
/**
* Shows a background overlay to obscure the main interface, and acts as the
* background for the cloned elements involved in the tutorial.
* This method is involved in the "clone element" strategy.
*/
showBackgroundOverlay() {
// Remove the resize handler that might exist from focusOnElement
// (Note: take care to not call this after cloning elements, because they
// have their own window resize handlers)
let $window = $(window);
this.$overlay.css({
background: this.overlayColor,
border: 'none'
});
this._resizeOverlayToFullScreen();
this._resizeHandler = this._resizeOverlayToFullScreen.bind(this);
}
/**
* Shows a transparent overlay to prevent user from interacting with cloned
* elements.
*/
showTransparentOverlay() {
this.$transparentOverlay.show();
}
/**
* Focuses on an element by resizing a transparent overlay to match its
* dimensions and changes the borders to be colored to obscure the main UI.
* This method is involved in the "transparent overlay" strategy.
*/
focusOnElement($element) {
// Hide overlay from showTransparentOverlay
this.$transparentOverlay.hide();
this._resizeOverlayToElement($element);
this._resizeHandler = this._resizeOverlayToElement.bind(this, $element);
}
resize() {
this._resizeHandler();
}
tearDown() {
this.$overlay.remove();
if (this.$transparentOverlay) {
this.$transparentOverlay.remove();
}
}
toString() {
return `[Overlay - shouldOverlay: ${this.shouldOverlay}, ` +
`overlayColor: ${this.overlayColor}]`;
}
//// PRIVATE
_createOverlay() {
let $overlay = $("<div class='chariot-overlay'></div>");
$overlay.css({ 'z-index': Constants.OVERLAY_Z_INDEX });
return $overlay;
}
_createTransparentOverlay() {
let $transparentOverlay = $("<div class='chariot-transparent-overlay'></div>");
$transparentOverlay.css({
'z-index': Constants.CLONE_Z_INDEX + 1,
width: document.body.scrollWidth,
height: document.body.scrollHeight
});
return $transparentOverlay;
}
// Used for clone element strategy
_resizeOverlayToFullScreen() {
this.$overlay.css({
width: document.body.scrollWidth,
height: document.body.scrollHeight
});
}
// Used for transparent overlay strategy
_resizeOverlayToElement($element) {
// First position the overlay
let offset = $element.offset();
// Then resize it
let borderStyles = `solid ${this.overlayColor}`;
let $document = this.$document;
let docWidth = $document.outerWidth();
let docHeight = $document.outerHeight();
let width = $element.outerWidth();
let height = $element.outerHeight();
let leftWidth = offset.left;
let rightWidth = docWidth - (offset.left + width);
let topWidth = offset.top;
let bottomWidth = docHeight - (offset.top + height);
this.$overlay.css({
background: 'transparent',
width, height,
'border-left': `${leftWidth}px ${borderStyles}`,
'border-top': `${topWidth}px ${borderStyles}`,
'border-right': `${rightWidth}px ${borderStyles}`,
'border-bottom': `${bottomWidth}px ${borderStyles}`
});
}
}
export default Overlay;