UNPKG

threepipe

Version:

A 3D viewer framework built on top of three.js in TypeScript with a focus on quality rendering, modularity and extensibility.

312 lines 12.6 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var LoadingScreenPlugin_1; import { createDiv, createStyles, onChange, serialize, timeout } from 'ts-browser-helpers'; import styles from './LoadingScreenPlugin.css?inline'; import spinner1 from './loaders/spinner1.css?inline'; import { uiButton, uiDropdown, uiFolderContainer, uiInput, uiSlider, uiToggle } from 'uiconfig.js'; import { AAssetManagerProcessStatePlugin } from '../base/AAssetManagerProcessStatePlugin'; /** * Loading Screen Plugin * * Shows a configurable loading screen overlay over the canvas. * * @category Plugins */ let LoadingScreenPlugin = LoadingScreenPlugin_1 = class LoadingScreenPlugin extends AAssetManagerProcessStatePlugin { refresh() { if (!this._viewer) return; this._updateMainDiv(this._isPreviewing ? this._previewState : this._viewer.assetManager.processState, false); } togglePreview() { this.maximize(); this._isPreviewing = !this._isPreviewing; this.refresh(); if (this._isPreviewing) this.show(); else this.hideWithDelay(); } constructor(container) { super('LoadingScreen', container); this.styles = styles; this.spinners = [{ styles: spinner1, html: '<span class="loader"></span>', }]; this.loader = 0; this.loadingTextHeader = 'Loading Files'; this.errorTextHeader = 'Error Loading Files'; this.showFileNames = true; this.showProcessStates = true; this.showProgress = true; this.hideOnOnlyErrors = true; this.hideOnFilesLoad = true; this.hideOnSceneObjectLoad = false; /** * Minimize when scene has objects * Note: also checks for scene.environment and doesnt minimize when environment is null or undefined * @default true */ this.minimizeOnSceneObjectLoad = true; this.showOnFilesLoading = true; this.showOnSceneEmpty = true; this.hideDelay = 500; this.backgroundOpacity = 0.5; this.backgroundBlur = 24; this.background = '#ffffff'; this.textColor = '#222222'; this.logoImage = LoadingScreenPlugin_1.LS_DEFAULT_LOGO; this._isPreviewing = false; this._previewState = new Map([['file.glb', { state: 'downloading', progress: 50 }], ['environment.hdr', { state: 'adding' }]]); this.loadingElement = createDiv({ classList: ['loadingScreenLoadingElement'], addToBody: false }); this.filesElement = createDiv({ classList: ['loadingScreenFilesElement'], addToBody: false }); this.logoElement = createDiv({ classList: ['loadingScreenLogoElement'], addToBody: false }); this._isHidden = false; this._temp = document.createElement('template'); // disables showOnSceneEmpty this.isEditor = false; this._sceneUpdate = (e) => { if (!this._viewer) return; if (!e.hierarchyChanged) return; const sceneObjects = this._viewer.scene.modelRoot.children; if (sceneObjects.length === 0 && this.showOnSceneEmpty && !this.isEditor) { this.show(); } // console.log(sceneObjects.length) if (sceneObjects.length > 0) { if (this.hideOnSceneObjectLoad) this.hideWithDelay(); else if (this.minimizeOnSceneObjectLoad && this._viewer.scene.environment) timeout(this.hideDelay + 300).then(() => this.minimize()); } else if (this.minimizeOnSceneObjectLoad) this.maximize(); }; // const popupClose = createDiv({ // id: 'assetManagerLoadingScreenClose', // addToBody: false, // innerHTML: '&#10005', // }) // popupClose.addEventListener('click', () => { // this._mainDiv.style.display = 'none' // }) // this._mainDiv.appendChild(popupClose) this._mainDiv.prepend(this.loadingElement); this._mainDiv.prepend(this.logoElement); this._mainDiv.appendChild(this.filesElement); } get visible() { return !this._isHidden; } async hide() { this._isHidden = true; this._mainDiv.style.opacity = '0'; await timeout(502); if (this._isHidden) { this._mainDiv.style.display = 'none'; this._showMainDiv(); } } async hideWithDelay() { this._isHidden = true; await timeout(this.hideDelay); if (!this._isHidden) return; return this.hide(); } show() { if (!this._isHidden) return; this._isHidden = false; this._showMainDiv(); this._mainDiv.style.display = 'flex'; } _showMainDiv() { // this._mainDiv.style.opacity = this.opacity.toString() this._mainDiv.style.opacity = '1'; } minimize() { this._mainDiv.classList.add('minimizedLoadingScreen'); if (!this.showFileNames) this.loadingElement.style.display = 'block'; } maximize() { this._mainDiv.classList.remove('minimizedLoadingScreen'); this.loadingElement.style.display = ''; } _setHTML(elem, html) { this._temp.innerHTML = html; // Compare the parsed content instead of raw strings, as browsers might change html after setting. if (this._temp.innerHTML.trim() !== elem.innerHTML.trim()) elem.innerHTML = html; } _updateMainDiv(processState, updateVisibility = true) { if (!this._viewer) return; if (!this._contentDiv) return; if (!this.enabled) { this._mainDiv.style.display = 'none'; return; } if (this.showFileNames) { let text = ''; processState.forEach((v, k) => { text += (this.showProcessStates ? `<span class="loadingScreenProcessState">${v.state}</span>: ` : '') + (k || '').split('/').pop() + (this.showProgress && v.progress ? ' - ' + (v.progress.toFixed(0) + '%') : '') + '<br>'; }); this._setHTML(this.filesElement, text); } else { this._setHTML(this.filesElement, ''); } const errors = [...processState.values()].filter(v => v.state === 'error'); if (errors.length > 0 && errors.length === processState.size && !this.hideOnOnlyErrors) { this._setHTML(this._contentDiv, this.errorTextHeader); } else { this._setHTML(this._contentDiv, this.loadingTextHeader); } this._setHTML(this.loadingElement, this.spinners[this.loader].html); this._mainDiv.style.setProperty('--b-opacity', this.backgroundOpacity.toString()); this._mainDiv.style.setProperty('--b-background', this.background); this._mainDiv.style.backdropFilter = `blur(${this.backgroundBlur}px)`; this._mainDiv.style.color = this.textColor; this._setHTML(this.logoElement, this.logoImage ? `<img class="loadingScreenLogoImage" src="${this.logoImage}"/>` : ''); if (updateVisibility) { if (this.hideOnFilesLoad && (processState.size === 0 || errors.length === processState.size && this.hideOnOnlyErrors)) { this.hideDelay ? this.hideWithDelay() : this.hide(); } else if (processState.size > 0 && this.showOnFilesLoading) { const sceneObjects = this._viewer.scene.modelRoot.children; if (sceneObjects.length > 0 && this.minimizeOnSceneObjectLoad && this._viewer.scene.environment) this.minimize(); else this.maximize(); this.show(); } } } onAdded(viewer) { this.stylesheet = createStyles(this.styles, viewer.container); this.stylesheetLoader = this.spinners.map(s => createStyles(s.styles, viewer.container)); viewer.scene.addEventListener('sceneUpdate', this._sceneUpdate); super.onAdded(viewer); } onRemove(viewer) { viewer.scene.removeEventListener('sceneUpdate', this._sceneUpdate); this.stylesheet?.remove(); this.stylesheet = undefined; this.stylesheetLoader?.forEach(s => s.remove()); this.stylesheetLoader = undefined; return super.onRemove(viewer); } }; LoadingScreenPlugin.PluginType = 'LoadingScreenPlugin'; LoadingScreenPlugin.LS_DEFAULT_LOGO = 'https://threepipe.org/logo.svg'; __decorate([ uiDropdown('Loader', ['Spinner 1'].map((v, i) => ({ value: i, label: v }))), serialize() ], LoadingScreenPlugin.prototype, "loader", void 0); __decorate([ uiInput('Loading text header'), onChange(LoadingScreenPlugin.prototype.refresh), serialize() ], LoadingScreenPlugin.prototype, "loadingTextHeader", void 0); __decorate([ uiInput('Error text header'), serialize() ], LoadingScreenPlugin.prototype, "errorTextHeader", void 0); __decorate([ uiToggle('Show file names'), onChange(LoadingScreenPlugin.prototype.refresh), serialize() ], LoadingScreenPlugin.prototype, "showFileNames", void 0); __decorate([ uiToggle('Show process states'), onChange(LoadingScreenPlugin.prototype.refresh), serialize() ], LoadingScreenPlugin.prototype, "showProcessStates", void 0); __decorate([ uiToggle('Show progress'), onChange(LoadingScreenPlugin.prototype.refresh), serialize() ], LoadingScreenPlugin.prototype, "showProgress", void 0); __decorate([ uiToggle('Hide on only errors'), serialize() ], LoadingScreenPlugin.prototype, "hideOnOnlyErrors", void 0); __decorate([ uiToggle('Hide on files load'), serialize() ], LoadingScreenPlugin.prototype, "hideOnFilesLoad", void 0); __decorate([ uiToggle('Hide on scene object load'), serialize() ], LoadingScreenPlugin.prototype, "hideOnSceneObjectLoad", void 0); __decorate([ uiToggle('Minimize on scene object load'), serialize() ], LoadingScreenPlugin.prototype, "minimizeOnSceneObjectLoad", void 0); __decorate([ uiToggle('Show when files start loading'), serialize() ], LoadingScreenPlugin.prototype, "showOnFilesLoading", void 0); __decorate([ uiToggle('Show when scene empty'), serialize() ], LoadingScreenPlugin.prototype, "showOnSceneEmpty", void 0); __decorate([ uiInput('Hide delay (ms)'), serialize() ], LoadingScreenPlugin.prototype, "hideDelay", void 0); __decorate([ uiSlider('Background Opacity', [0, 1]), onChange(LoadingScreenPlugin.prototype.refresh), serialize() ], LoadingScreenPlugin.prototype, "backgroundOpacity", void 0); __decorate([ uiSlider('Background Blur', [0, 100]), onChange(LoadingScreenPlugin.prototype.refresh), serialize() ], LoadingScreenPlugin.prototype, "backgroundBlur", void 0); __decorate([ uiInput('Background Color'), onChange(LoadingScreenPlugin.prototype.refresh), serialize() ], LoadingScreenPlugin.prototype, "background", void 0); __decorate([ uiInput('Text Color'), onChange(LoadingScreenPlugin.prototype.refresh), serialize() ], LoadingScreenPlugin.prototype, "textColor", void 0); __decorate([ uiInput('Logo Image'), onChange(LoadingScreenPlugin.prototype.refresh), serialize() ], LoadingScreenPlugin.prototype, "logoImage", void 0); __decorate([ uiButton('Toggle preview') ], LoadingScreenPlugin.prototype, "togglePreview", null); __decorate([ uiButton('Minimize') ], LoadingScreenPlugin.prototype, "minimize", null); __decorate([ uiButton('Maximize') ], LoadingScreenPlugin.prototype, "maximize", null); LoadingScreenPlugin = LoadingScreenPlugin_1 = __decorate([ uiFolderContainer('Loading Screen') ], LoadingScreenPlugin); export { LoadingScreenPlugin }; //# sourceMappingURL=LoadingScreenPlugin.js.map