pages235/renderer/viewer/lib/DebugGui.ts
Vitaly 65af9a73c2
feat: rework hand! enable by default, fix bow anim (#261)
* refactor swing animation to controller

* idle animator!!!!

* implelment state switch transition

* a huge fix for UI server edit!

* adjust ui scaling so main menu elements clip less

* view bobbing, new config name, ws:

* EXTREMELY important fixes to entities rendering

* a lot of fixes, add dns resolve fallback

* improve f3 E, fix modal not found edge case

* set correctly target for old browsers, should fix ios 14 crash

* unecessary big refactor, to fix ts err

* fix isWysiwyg check

* fix entities rendering count
2025-02-15 05:14:36 +03:00

174 lines
4.6 KiB
TypeScript

// eslint-disable-next-line import/no-named-as-default
import GUI from 'lil-gui'
export interface ParamMeta {
min?: number
max?: number
step?: number
}
export class DebugGui {
private gui: GUI
private readonly storageKey: string
private target: any
private readonly params: string[]
private readonly paramsMeta: Record<string, ParamMeta>
private _visible = false // Default to not visible
private readonly initialValues: Record<string, any> = {} // Store initial values
private initialized = false
constructor (id: string, target: any, params?: string[], paramsMeta?: Record<string, ParamMeta>) {
this.gui = new GUI()
this.storageKey = `debug_params_${id}`
this.target = target
this.paramsMeta = paramsMeta ?? {}
this.params = params ?? Object.keys(target)
// Store initial values
for (const param of this.params) {
this.initialValues[param] = target[param]
}
// Hide by default
this.gui.domElement.style.display = 'none'
}
// Initialize and show the GUI
activate () {
if (!this.initialized) {
this.loadSavedValues()
this.setupControls()
this.initialized = true
}
this.show()
return this
}
// Getter for visibility
get visible (): boolean {
return this._visible
}
// Setter for visibility
set visible (value: boolean) {
this._visible = value
this.gui.domElement.style.display = value ? 'block' : 'none'
this.saveVisibility()
}
private loadSavedValues () {
try {
const saved = localStorage.getItem(this.storageKey)
if (saved) {
const values = JSON.parse(saved)
// Apply saved values to target
for (const param of this.params) {
if (param in values) {
const value = values[param]
if (value !== null) {
this.target[param] = value
}
}
}
}
} catch (e) {
console.warn('Failed to load debug values:', e)
}
}
private saveValues (deleteKey = false) {
try {
const values = {}
for (const param of this.params) {
values[param] = this.target[param]
}
if (deleteKey) {
localStorage.removeItem(this.storageKey)
} else {
localStorage.setItem(this.storageKey, JSON.stringify(values))
}
} catch (e) {
console.warn('Failed to save debug values:', e)
}
}
private saveVisibility () {
try {
localStorage.setItem(`${this.storageKey}_visible`, this._visible.toString())
} catch (e) {
console.warn('Failed to save debug visibility:', e)
}
}
private setupControls () {
// Add visibility toggle at the top
this.gui.add(this, 'visible').name('Show Controls')
this.gui.add({ resetAll: () => {
for (const param of this.params) {
this.target[param] = this.initialValues[param]
}
this.saveValues(true)
this.gui.destroy()
this.gui = new GUI()
this.setupControls()
} }, 'resetAll').name('Reset All Parameters')
for (const param of this.params) {
const value = this.target[param]
const meta = this.paramsMeta[param] ?? {}
if (typeof value === 'number') {
// For numbers, use meta values or calculate reasonable defaults
const min = meta.min ?? value - Math.abs(value * 2)
const max = meta.max ?? value + Math.abs(value * 2)
const step = meta.step ?? Math.abs(value) / 100
this.gui.add(this.target, param, min, max, step)
.onChange(() => this.saveValues())
} else if (typeof value === 'boolean') {
// For booleans, create a checkbox
this.gui.add(this.target, param)
.onChange(() => this.saveValues())
} else if (typeof value === 'string' && ['x', 'y', 'z'].includes(param)) {
// Special case for xyz coordinates
const min = meta.min ?? -10
const max = meta.max ?? 10
const step = meta.step ?? 0.1
this.gui.add(this.target, param, min, max, step)
.onChange(() => this.saveValues())
} else if (Array.isArray(value)) {
// For arrays, create a dropdown
this.gui.add(this.target, param, value)
.onChange(() => this.saveValues())
}
}
}
// Method to manually trigger save
save () {
this.saveValues()
this.saveVisibility()
}
// Method to destroy the GUI and clean up
destroy () {
this.saveVisibility()
this.gui.destroy()
}
// Toggle visibility
toggle () {
this.visible = !this.visible
}
// Show the GUI
show () {
this.visible = true
}
// Hide the GUI
hide () {
this.visible = false
}
}