diff --git a/assets/scripts/src/element.js b/assets/scripts/src/element.js index befcd533d18a898745a572d3c14f531a3ce3eff4..79a1a29e49db9c63d27eb37592a4a3c3c208960f 100644 --- a/assets/scripts/src/element.js +++ b/assets/scripts/src/element.js @@ -102,19 +102,35 @@ export default class Element { return position; } + /** + * Is called when element is about to be deselected + * i.e. when moving the focus to next element of closing + */ onDeselected() { - // Will be called when element is about to be deselected + if (!this.popover) { + return; + } + this.popover.hide(); } + /** + * Is called when the element is about to be highlighted + * i.e. either if overlay has started moving the highlight towards + * this element of has just decided to highlight it + */ onHighlightStarted() { - // Will be triggered when the element is about to be highlighted - // i.e. overlay has started transitioning towards this element + if (!this.popover) { + return; + } + this.showPopover(); } onHighlighted() { - this.showPopover(); + if (this.popover) { + this.showPopover(); + } const highlightedElement = this; const lastHighlightedElement = this.overlay.getLastHighlightedElement(); @@ -130,7 +146,7 @@ export default class Element { highlightedElement.bringInView(); } - if (!popoverElement.isInView()) { + if (popoverElement && !popoverElement.isInView()) { popoverElement.bringInView(); } } diff --git a/assets/scripts/src/overlay.js b/assets/scripts/src/overlay.js index 4f2e19cf07034bda1deb531ee966a9133df1d046..1fccf79be4823a4e4db09e778cb8431d797e2b19 100644 --- a/assets/scripts/src/overlay.js +++ b/assets/scripts/src/overlay.js @@ -1,5 +1,5 @@ import Position from './position'; -import { ID_OVERLAY, OVERLAY_ANIMATE, OVERLAY_OPACITY, OVERLAY_PADDING, OVERLAY_ZINDEX } from './constants'; +import { ID_OVERLAY, OVERLAY_ZINDEX } from './constants'; /** * Responsible for overlay creation and manipulation i.e. @@ -7,20 +7,12 @@ import { ID_OVERLAY, OVERLAY_ANIMATE, OVERLAY_OPACITY, OVERLAY_PADDING, OVERLAY_ */ export default class Overlay { /** - * @param opacity number - * @param padding number - * @param animate bool + * @param options * @param window * @param document */ - constructor({ - opacity = OVERLAY_OPACITY, - padding = OVERLAY_PADDING, - animate = OVERLAY_ANIMATE, - }, window, document) { - this.opacity = opacity; // Fixed opacity for the layover - this.padding = padding; // Padding around the highlighted item - this.animate = animate; // Should animate between the transitions + constructor(options, window, document) { + this.options = options; this.overlayAlpha = 0; // Is used to animate the layover this.positionToHighlight = new Position({}); // position at which layover is to be patched at @@ -93,7 +85,7 @@ export default class Overlay { // 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.animate || !animate) { + if (!this.options.animate || !animate) { this.highlightedPosition = this.positionToHighlight; } @@ -121,7 +113,10 @@ export default class Overlay { */ clear() { this.positionToHighlight = new Position(); - this.highlightedElement.onDeselected(); + if (this.highlightedElement) { + this.highlightedElement.onDeselected(); + } + this.highlightedElement = null; this.lastHighlightedElement = null; @@ -160,18 +155,18 @@ export default class Overlay { // Cut the chunk of overlay that is over the highlighted item this.removeCloak({ - posX: this.highlightedPosition.left - this.window.scrollX - this.padding, - posY: this.highlightedPosition.top - this.window.scrollY - this.padding, - width: (this.highlightedPosition.right - this.highlightedPosition.left) + (this.padding * 2), - height: (this.highlightedPosition.bottom - this.highlightedPosition.top) + (this.padding * 2), + posX: this.highlightedPosition.left - this.window.scrollX - this.options.padding, + posY: this.highlightedPosition.top - this.window.scrollY - this.options.padding, + width: (this.highlightedPosition.right - this.highlightedPosition.left) + (this.options.padding * 2), + height: (this.highlightedPosition.bottom - this.highlightedPosition.top) + (this.options.padding * 2), }); // Fade the overlay in if we can highlight if (canHighlight) { - if (!this.animate) { - this.overlayAlpha = this.opacity; + if (!this.options.animate) { + this.overlayAlpha = this.options.opacity; } else { - this.overlayAlpha += (this.opacity - this.overlayAlpha) * 0.08; + this.overlayAlpha += (this.options.opacity - this.overlayAlpha) * 0.08; } } else { // otherwise fade out @@ -193,7 +188,7 @@ export default class Overlay { // or the alpha has not yet fully reached fully required opacity if (!this.hasPositionHighlighted()) { this.redrawAnimation = this.window.requestAnimationFrame(this.draw); - } else if (!this.animate && isFadingIn) { + } else if (!this.options.animate && isFadingIn) { this.redrawAnimation = this.window.requestAnimationFrame(this.draw); } else { // Element has been highlighted @@ -207,7 +202,7 @@ export default class Overlay { hasPositionHighlighted() { return this.positionToHighlight.equals(this.highlightedPosition) && - this.overlayAlpha > (this.opacity - 0.05); + this.overlayAlpha > (this.options.opacity - 0.05); } /** diff --git a/assets/scripts/src/sholo.js b/assets/scripts/src/sholo.js index 28f5490dd0504cc071698828585fa1d70c59af57..628c14e2af90d8fd11ed5fbecb551c5db2e1cb34 100644 --- a/assets/scripts/src/sholo.js +++ b/assets/scripts/src/sholo.js @@ -8,6 +8,9 @@ import { CLASS_PREV_STEP_BTN, ESC_KEY_CODE, ID_POPOVER, + OVERLAY_ANIMATE, + OVERLAY_OPACITY, + OVERLAY_PADDING, } from './constants'; /** @@ -19,9 +22,9 @@ export default class Sholo { */ constructor(options = {}) { this.options = Object.assign({ - padding: 10, - animate: true, - opacity: 0.75, + animate: OVERLAY_ANIMATE, // Whether to animate or not + opacity: OVERLAY_OPACITY, // Overlay opacity + padding: OVERLAY_PADDING, // Spacing around the element from the overlay }, options); this.document = document; @@ -173,6 +176,7 @@ export default class Sholo { } const elementOptions = Object.assign({}, this.options, step); + const popoverOptions = Object.assign({}, this.options, elementOptions.popover || {}); const domElement = this.document.querySelector(step.element); if (!domElement) { @@ -180,8 +184,7 @@ export default class Sholo { return; } - // @todo pass the options such as position, button text etc - const popover = new Popover(elementOptions, this.window, this.document); + const popover = elementOptions.popover ? new Popover(popoverOptions, this.window, this.document) : null; const element = new Element(domElement, elementOptions, popover, this.overlay, this.window, this.document); this.steps.push(element); diff --git a/index.html b/index.html index fdbe025f58bcdac2930a7444c28cd0dcb83201c0..cfd04d418bcdbd6c236ba198058c86b6d89d299d 100644 --- a/index.html +++ b/index.html @@ -64,11 +64,22 @@ }); sholo.defineSteps([ - { element: '.section__header' }, - { element: '.section__how' }, - { element: '.section__purpose' }, - { element: '.section__examples' }, - { element: '.section__contributing' }, + { + element: '.section__header' + }, + { + element: '.section__how', + popover: {} + }, + { + element: '.section__purpose', + }, + { + element: '.section__examples', + }, + { + element: '.section__contributing', + }, ]); document.querySelector('.btn__example')