UNPKG

threepipe

Version:

A modern 3D viewer framework built on top of three.js, written in TypeScript, designed to make creating high-quality, modular, and extensible 3D experiences on the web simple and enjoyable.

205 lines 7.53 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; }; // noinspection ES6PreferShortImport import { AViewerPluginSync } from '../../viewer/AViewerPlugin'; import { Dropzone } from '../../utils'; import { uiButton, uiConfig, uiFolderContainer, uiToggle } from 'uiconfig.js'; import { parseFileExtension, serialize } from 'ts-browser-helpers'; /** * Dropzone Plugin * * Adds a dropzone to the viewer for importing assets. * * Automatically imports and adds assets to the scene, the behavior can be configured. * @category Plugins */ let DropzonePlugin = class DropzonePlugin extends AViewerPluginSync { /** * Allowed file extensions. If undefined, all files are allowed. */ get allowedExtensions() { return this._allowedExtensions; } set allowedExtensions(value) { this._allowedExtensions = value; if (this._inputEl) this._inputEl.accept = value ? value.map(v => '.' + v).join(', ') : ''; } /** * Prompt for file selection using the browser file dialog. */ promptForFile() { if (this.isDisabled()) return; this.allowedExtensions = this._allowedExtensions; this._inputEl?.click(); } /** * Prompt for file url. */ async promptForUrl() { if (this.isDisabled() || !this._viewer) return; const res = await this._viewer.dialog.prompt('Enter URL: Enter a public URL for a 3d file with extension', '', true); if (!res || !res.length) return; await this.load(res, {}, true); } async load(res, options, dialog = false) { if (!this._viewer) { console.warn('DropzonePlugin: viewer not set'); return; } if (this.autoImport) { const manager = this._viewer.assetManager; const ext = parseFileExtension(res); if (this._allowedExtensions && !this._allowedExtensions.includes(ext)) { dialog && await this._viewer.dialog.alert(`DropzonePlugin: file extension ${ext} not allowed`); return; } const imported = await manager.importer.import(res, { ...this.importOptions, ...options ?? {}, }); const toAdd = [...imported ?? []].flat(2).filter(v => !!v) ?? []; if (this.autoAdd) { return await manager.loadImported(toAdd, { ...this.addOptions, ...options ?? {}, }); } return toAdd; } else { dialog && await this._viewer.dialog.alert('DropzonePlugin: autoImport is disabled, file was not imported'); } } constructor(options) { super(); this.enabled = true; this._allowedExtensions = undefined; // undefined and empty array is different. /** * Automatically import assets when dropped. */ this.autoImport = true; /** * Automatically add dropped and imported assets to the scene. * Works only if {@link autoImport} is true. */ this.autoAdd = true; /** * Import options for the {@link AssetImporter.importFiles} */ this.importOptions = { autoImportZipContents: true, forceImporterReprocess: false, }; /** * Add options for the {@link RootScene.addObject} */ this.addOptions = { autoCenter: true, importConfig: true, autoScale: true, autoScaleRadius: 2, centerGeometries: false, // in the whole hierarchy centerGeometriesKeepPosition: true, // this centers while keeping world position license: '', clearSceneObjects: false, disposeSceneObjects: false, autoSetBackground: false, autoSetEnvironment: true, }; if (!options) return; this._domElement = options.domElement; this.allowedExtensions = options.allowedExtensions; this.autoImport = options.autoImport ?? this.autoImport; this.autoAdd = options.autoAdd ?? this.autoAdd; this.importOptions = { ...this.importOptions, ...options.importOptions }; this.addOptions = { ...this.addOptions, ...options.addOptions }; } onAdded(viewer) { super.onAdded(viewer); this._inputEl = document.createElement('input'); this._inputEl.type = 'file'; if (!this._domElement) this._domElement = viewer.canvas; this._dropzone = new Dropzone(this._domElement, this._inputEl, { drop: this._onFileDrop.bind(this), }); this.allowedExtensions = this._allowedExtensions; } onRemove(viewer) { super.onRemove(viewer); this._dropzone?.destroy(); this._dropzone = undefined; this._inputEl = undefined; } async _onFileDrop({ files, nativeEvent }) { if (!files) return; if (this.isDisabled()) return; const viewer = this._viewer; if (!viewer) return; if (this._allowedExtensions !== undefined) { for (const file of files.keys()) { if (!this._allowedExtensions.includes(file.split('.').pop()?.toLowerCase() ?? '')) { files.delete(file); } } } if (files.size < 1) return; const manager = viewer.assetManager; let imported; let assets; if (this.autoImport) { imported = await manager.importer.importFiles(files, { allowedExtensions: this.allowedExtensions, ...this.importOptions, }); if (this.autoAdd) { const toAdd = [...imported?.values() ?? []].flat(2).filter(v => !!v) ?? []; assets = await manager.loadImported(toAdd, { ...this.addOptions }); } } this.dispatchEvent({ type: 'drop', files, imported, assets, nativeEvent }); } }; DropzonePlugin.PluginType = 'Dropzone'; __decorate([ uiToggle(), serialize() ], DropzonePlugin.prototype, "enabled", void 0); __decorate([ serialize() ], DropzonePlugin.prototype, "autoImport", void 0); __decorate([ uiToggle(), serialize() ], DropzonePlugin.prototype, "autoAdd", void 0); __decorate([ uiConfig(), serialize() ], DropzonePlugin.prototype, "importOptions", void 0); __decorate([ uiConfig(), serialize() ], DropzonePlugin.prototype, "addOptions", void 0); __decorate([ uiButton('Select Local files') ], DropzonePlugin.prototype, "promptForFile", null); __decorate([ uiButton('Import from URL') ], DropzonePlugin.prototype, "promptForUrl", null); DropzonePlugin = __decorate([ uiFolderContainer('Dropzone') ], DropzonePlugin); export { DropzonePlugin }; //# sourceMappingURL=DropzonePlugin.js.map