UNPKG

@giro3d/giro3d

Version:

A JS/WebGL framework for 3D geospatial data visualization

142 lines (135 loc) 4.2 kB
/* * Copyright (c) 2015-2018, IGN France. * Copyright (c) 2018-2026, Giro3D team. * SPDX-License-Identifier: MIT */ import GUI from 'lil-gui'; import { isDisposable } from '../core/Disposable'; import DrawToolPanel from './DrawToolPanel'; import EntityPanel from './EntityPanel'; import InstanceInspector from './InstanceInspector'; import Outliner from './outliner/Outliner'; import PackageInfoInspector from './PackageInfoInspector'; import ProcessingInspector from './ProcessingInspector'; import SunExposurePanel from './SunExposurePanel'; import ViewInspector from './ViewInspector'; // Here follows the style adaptation to lil-gui const styles = ` .lil-gui .title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: monospace; } `; function visit(root, callbackFn) { if (root != null) { callbackFn(root); if (root.childElementCount > 0) { for (const child of root.children) { visit(child, callbackFn); } } } } const styleSheet = document.createElement('style'); styleSheet.type = 'text/css'; styleSheet.innerText = styles; document.head.appendChild(styleSheet); /** * Provides a user interface to inspect and edit the Giro3D scene. * The inspector is made of several {@link Panel}. * You can implement custom panels and add them to the inspector with * {@link Inspector.addPanel}. * */ class Inspector { /** * Creates an instance of the inspector. * * @param parent - The HTML element to attach the panel to, or the `id` of this element. * @param instance - The Giro3D instance. * @param options - The options. */ constructor(parent, instance, options = {}) { this.instance = instance; this.gui = new GUI({ autoPlace: false, width: options.width ?? 450, title: options.title ?? 'Inspector' }); this.gui.close(); this.gui.add(this, 'collapse'); if (typeof parent === 'string') { parent = document.getElementById(parent); } parent.appendChild(this.gui.domElement); instance.addEventListener('update-end', () => this.update()); this.folders = []; this.addPanel(new PackageInfoInspector(this.gui, instance)); this.addPanel(new InstanceInspector(this.gui, instance)); this.addPanel(new ViewInspector(this.gui, instance)); this.addPanel(new DrawToolPanel(this.gui, instance)); this.addPanel(new SunExposurePanel(this.gui, instance)); this.addPanel(new ProcessingInspector(this.gui, instance)); this.addPanel(new EntityPanel(this.gui, instance)); this.addPanel(new Outliner(this.gui, instance)); } collapse() { this.folders.forEach(f => f.collapse()); } /** * Removes all panel from the inspector. * */ clearPanels() { while (this.folders.length > 0) { const gui = this.folders.pop(); if (isDisposable(gui)) { gui.dispose(); } } } /** * Adds a panel to the inspector. * * @param panel - The panel to add. */ addPanel(panel) { this.folders.push(panel); } /** * Attaches the inspector to the specified DOM element. * * @param parent - The element to attach the panel to, or the `id` to the element. * @param instance - The Giro3D instance. * @param options - The options. * @returns The created inspector. */ static attach(parent, instance, options = {}) { const inspector = new Inspector(parent, instance, options); return inspector; } /** * Detach this Inspector from its instance. * */ detach() { this.clearPanels(); this.instance.removeEventListener('update-end', () => this.update()); this.gui.domElement.remove(); } update() { this.folders.forEach(f => f.update()); // Remove autocomplete on all Input elements to avoid causing issues on some browsers // See https://gitlab.com/giro3d/giro3d/-/issues/526 // Note: we have to do it for each iteration because the content of the inspector can change // over time (e.g entities added and removed) visit(this.gui.domElement, element => { if (element instanceof HTMLInputElement) { element.autocomplete = 'off'; } }); } } export default Inspector;