Skip to content

Commit

Permalink
feat(loading): Show ghost state for document preloaders and pages
Browse files Browse the repository at this point in the history
  • Loading branch information
jstoffan committed Apr 8, 2021
1 parent a80ab58 commit ffac1ba
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 138 deletions.
42 changes: 0 additions & 42 deletions src/lib/_loading.scss
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
@import 'boxuiVariables';

$spinner-size: 15px;

@mixin spinner() {
background: url('icons/loading.gif') center no-repeat;
background-size: $spinner-size $spinner-size;
}

@keyframes box-crawler {
0%,
80%,
Expand All @@ -21,17 +14,6 @@ $spinner-size: 15px;
}
}

@keyframes fadeIn {
0%,
50% {
opacity: 0;
}

100% {
opacity: 1;
}
}

.bp-loading-wrapper {
position: absolute;
top: 0;
Expand Down Expand Up @@ -100,27 +82,3 @@ $spinner-size: 15px;
animation-delay: .2s;
}
}

.bp .bp-doc.bp-doc-document,
.bp .bp-doc.bp-doc-presentation {
// Overrides PDF.js loading spinner
.pdfViewer .page .loadingIcon {
@include spinner;
}
}

.bp-document-preload-wrapper,
.bp-presentation-preload-wrapper {
.bp-preload-spinner {
@include spinner;

position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: $spinner-size;
height: $spinner-size;
margin: auto;
}
}
3 changes: 2 additions & 1 deletion src/lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ export const CLASS_BOX_PREVIEW_MOBILE = 'bp-is-mobile';
export const CLASS_BOX_PREVIEW_OVERLAY = 'bp-overlay';
export const CLASS_BOX_PREVIEW_OVERLAY_WRAPPER = 'bp-overlay-wrapper';
export const CLASS_BOX_PREVIEW_PRELOAD = 'bp-preload';
export const CLASS_BOX_PREVIEW_PRELOAD_BACKGROUND = 'bp-preload-background';
export const CLASS_BOX_PREVIEW_PRELOAD_CONTENT = 'bp-preload-content';
export const CLASS_BOX_PREVIEW_PRELOAD_OVERLAY = 'bp-preload-overlay';
export const CLASS_BOX_PREVIEW_PRELOAD_SPINNER = 'bp-preload-spinner';
export const CLASS_BOX_PREVIEW_PRELOAD_PLACEHOLDER = 'bp-preload-placeholder';
export const CLASS_BOX_PREVIEW_PRELOAD_WRAPPER_DOCUMENT = 'bp-document-preload-wrapper';
export const CLASS_BOX_PREVIEW_PRELOAD_WRAPPER_PRESENTATION = 'bp-presentation-preload-wrapper';
export const CLASS_BOX_PREVIEW_NOTIFICATION = 'bp-notification';
Expand Down
3 changes: 0 additions & 3 deletions src/lib/viewers/BaseViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,6 @@ class BaseViewer extends EventEmitter {
/** @property {number} - Zoom scale, if zoomed */
scale = 1;

/** @property {string} - Viewer-specific file loading icon */
fileLoadingIcon;

/** @property {Object} - Viewer options */
options;

Expand Down
38 changes: 17 additions & 21 deletions src/lib/viewers/doc/DocPreloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ import EventEmitter from 'events';
import Api from '../../api';
import {
CLASS_BOX_PREVIEW_PRELOAD,
CLASS_BOX_PREVIEW_PRELOAD_BACKGROUND,
CLASS_BOX_PREVIEW_PRELOAD_CONTENT,
CLASS_BOX_PREVIEW_PRELOAD_OVERLAY,
CLASS_BOX_PREVIEW_PRELOAD_SPINNER,
CLASS_BOX_PREVIEW_PRELOAD_PLACEHOLDER,
CLASS_BOX_PREVIEW_PRELOAD_WRAPPER_DOCUMENT,
CLASS_INVISIBLE,
CLASS_IS_TRANSPARENT,
CLASS_PREVIEW_LOADED,
PDFJS_CSS_UNITS,
PDFJS_HEIGHT_PADDING_PX,
PDFJS_MAX_AUTO_SCALE,
PDFJS_WIDTH_PADDING_PX,
PDFJS_HEIGHT_PADDING_PX,
} from '../../constants';
import { setDimensions, handleRepresentationBlobFetch } from '../../util';

Expand All @@ -24,8 +25,6 @@ const NUM_PAGES_MAX = 500; // Don't show more than 500 placeholder pages

const ACCEPTABLE_RATIO_DIFFERENCE = 0.025; // Acceptable difference in ratio of PDF dimensions to image dimensions

const SPINNER_HTML = `<div class="${CLASS_BOX_PREVIEW_PRELOAD_SPINNER}"></div>`;

class DocPreloader extends EventEmitter {
/** @property {Api} - Api layer used for XHR calls */
api = new Api();
Expand All @@ -39,12 +38,12 @@ class DocPreloader extends EventEmitter {
/** @property {HTMLElement} - Maximum auto-zoom scale */
maxZoomScale = PDFJS_MAX_AUTO_SCALE;

/** @property {HTMLElement} - Preload overlay element */
overlayEl;

/** @property {Object} - The EXIF data for the PDF */
pdfData;

/** @property {HTMLElement} - Preload placeholder element */
placeholderEl;

/** @property {HTMLElement} - Preload container element */
preloadEl;

Expand Down Expand Up @@ -101,17 +100,18 @@ class DocPreloader extends EventEmitter {
this.wrapperEl.className = this.wrapperClassName;
this.wrapperEl.innerHTML = `
<div class="${CLASS_BOX_PREVIEW_PRELOAD} ${CLASS_INVISIBLE}">
<img class="${CLASS_BOX_PREVIEW_PRELOAD_CONTENT}" src="${this.srcUrl}" />
<div class="${CLASS_BOX_PREVIEW_PRELOAD_CONTENT} ${CLASS_BOX_PREVIEW_PRELOAD_OVERLAY}">
${SPINNER_HTML}
<div class="${CLASS_BOX_PREVIEW_PRELOAD_PLACEHOLDER}">
<div class="${CLASS_BOX_PREVIEW_PRELOAD_BACKGROUND}"></div>
<img class="${CLASS_BOX_PREVIEW_PRELOAD_CONTENT}" src="${this.srcUrl}" />
<div class="${CLASS_BOX_PREVIEW_PRELOAD_OVERLAY}"></div>
</div>
</div>
`.trim();

this.containerEl.appendChild(this.wrapperEl);
this.placeholderEl = this.wrapperEl.querySelector(`.${CLASS_BOX_PREVIEW_PRELOAD_PLACEHOLDER}`);
this.preloadEl = this.wrapperEl.querySelector(`.${CLASS_BOX_PREVIEW_PRELOAD}`);
this.imageEl = this.preloadEl.querySelector(`img.${CLASS_BOX_PREVIEW_PRELOAD_CONTENT}`);
this.overlayEl = this.preloadEl.querySelector(`.${CLASS_BOX_PREVIEW_PRELOAD_OVERLAY}`);
this.imageEl = this.preloadEl.querySelector(`.${CLASS_BOX_PREVIEW_PRELOAD_CONTENT}`);
this.bindDOMListeners();
});
}
Expand All @@ -129,22 +129,18 @@ class DocPreloader extends EventEmitter {
return;
}

// Set image and overlay dimensions
setDimensions(this.imageEl, scaledWidth, scaledHeight);
setDimensions(this.overlayEl, scaledWidth, scaledHeight);
// Set initial placeholder dimensions
setDimensions(this.placeholderEl, scaledWidth, scaledHeight);

// Add and scale correct number of placeholder elements
for (let i = 0; i < numPages - 1; i += 1) {
const placeholderEl = document.createElement('div');
placeholderEl.className = CLASS_BOX_PREVIEW_PRELOAD_CONTENT;
placeholderEl.innerHTML = SPINNER_HTML;
placeholderEl.className = CLASS_BOX_PREVIEW_PRELOAD_PLACEHOLDER;
placeholderEl.innerHTML = `<div class="${CLASS_BOX_PREVIEW_PRELOAD_BACKGROUND}"></div>`;
setDimensions(placeholderEl, scaledWidth, scaledHeight);
this.preloadEl.appendChild(placeholderEl);
}

// Hide the preview-level loading indicator
this.previewUI.hideLoadingIndicator();

// Show preload element after content is properly sized
this.preloadEl.classList.remove(CLASS_INVISIBLE);

Expand Down Expand Up @@ -292,7 +288,7 @@ class DocPreloader extends EventEmitter {

const { scaledWidth, scaledHeight } = dimensionData;
// Scale preload and placeholder elements
const preloadEls = this.preloadEl.getElementsByClassName(CLASS_BOX_PREVIEW_PRELOAD_CONTENT);
const preloadEls = this.preloadEl.getElementsByClassName(CLASS_BOX_PREVIEW_PRELOAD_PLACEHOLDER);
for (let i = 0; i < preloadEls.length; i += 1) {
setDimensions(preloadEls[i], scaledWidth, scaledHeight);
}
Expand Down
36 changes: 23 additions & 13 deletions src/lib/viewers/doc/Document.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,31 @@
}
}

// Position preload content as if they were blank loading pages
.bp-preload-background,
.bp-preload-content,
.bp-preload-overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}

.bp-preload-background {
@include bp-Ghost;
}

.bp-preload-content {
width: 100%;
}

.bp-preload-overlay {
background-color: rgba(255, 255, 255, .4);
}

.bp-preload-placeholder {
position: relative;
display: block;
margin: 15px auto 30px;
padding-left: 1px; // Slight padding to help image text align with real text
background-color: $white;

&.bp-preload-overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(255, 255, 255, .4);
}
overflow: hidden;
}
}
30 changes: 21 additions & 9 deletions src/lib/viewers/doc/Presentation.scss
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,31 @@
}
}

// Absolutely center preload content
.bp-preload-content {
.bp-preload-background,
.bp-preload-content,
.bp-preload-overlay,
.bp-preload-placeholder {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 1px; // Slight padding to help image text align with real text
display: block;
margin: auto;
background-color: $white;
left: 0;
}

&.bp-preload-overlay {
background-color: rgba(255, 255, 255, .4);
}
.bp-preload-background {
@include bp-Ghost;
}

.bp-preload-content {
width: 100%;
}

.bp-preload-overlay {
background-color: rgba(255, 255, 255, .4);
}

.bp-preload-placeholder {
margin: auto;
overflow: hidden;
}
}
19 changes: 4 additions & 15 deletions src/lib/viewers/doc/PresentationPreloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,10 @@ import { CLASS_INVISIBLE, CLASS_BOX_PREVIEW_PRELOAD_WRAPPER_PRESENTATION } from
import { setDimensions } from '../../util';

class PresentationPreloader extends DocPreloader {
/**
* @property {HTMLELement} - Maximum auto-zoom scale, set to 0 for no limit since presentation viewer doesn't
* have a maximum zoom scale and scales up to available viewport
*/
/** @inheritdoc */
maxZoomScale = 0;

/**
* [constructor]
*
* @param {PreviewUI} previewUI - UI instance
* @return {PresentationPreloader} PresentationPreloader instance
*/
/** @inheritdoc */
constructor(previewUI, options) {
super(previewUI, options);

Expand All @@ -35,11 +27,8 @@ class PresentationPreloader extends DocPreloader {
return;
}

setDimensions(this.imageEl, scaledWidth, scaledHeight);
setDimensions(this.overlayEl, scaledWidth, scaledHeight);

// Hide the preview-level loading indicator
this.previewUI.hideLoadingIndicator();
// Set initial placeholder dimensions
setDimensions(this.placeholderEl, scaledWidth, scaledHeight);

// Show preload element after content is properly sized
this.preloadEl.classList.remove(CLASS_INVISIBLE);
Expand Down
Loading

0 comments on commit ffac1ba

Please sign in to comment.