diff --git a/example/web-client/public/style.css b/example/web-client/public/style.css index f9c31d5a..d1b1340f 100644 --- a/example/web-client/public/style.css +++ b/example/web-client/public/style.css @@ -1,56 +1,44 @@ -:root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - color-scheme: light dark; - color: black; - background-color: #121212; - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -webkit-text-size-adjust: 100%; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; +html, +body, +#app, +#root { + width: 100%; + height: 100%; } body { margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; overflow: hidden; } -h1 { - font-size: 3.2em; - line-height: 1.1; +#app { + position: relative; + width: 100%; + height: 100%; + overflow: hidden; } -#app { - max-width: 100vw; - margin: 0 auto; - padding: 0; - text-align: center; +.frame-emu { + position: relative; + width: 90% !important; + height: 90% !important; + transform: translate(5%, 5%) !important; + overflow: hidden !important; } -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } +#tweakpane-panel { + position: fixed; + width: 400px; + height: 100%; + top: 0px; + right: calc(-50vw); + z-index: 99; + overflow: auto; + background-color: rgba(0, 0, 0, 0.66); + padding-left: 5px; + box-shadow: -7px 0px 12px rgba(0, 0, 0, 0.5); + transition: right cubic-bezier(0.83, 0, 0.17, 1) 0.7s; + + scrollbar-width: auto; + scrollbar-color: #aaaaaa #000000; } diff --git a/example/web-client/src/index.ts b/example/web-client/src/index.ts index d17722cc..1fcc64a3 100644 --- a/example/web-client/src/index.ts +++ b/example/web-client/src/index.ts @@ -91,6 +91,8 @@ export class App { private loadingProgressManager = new LoadingProgressManager(); private loadingScreen: LoadingScreen; + private appWrapper = document.getElementById("app"); + constructor() { document.addEventListener("mousedown", () => { if (this.audioListener.context.state === "suspended") { @@ -102,7 +104,11 @@ export class App { this.element.style.position = "absolute"; this.element.style.width = "100%"; this.element.style.height = "100%"; - document.body.appendChild(this.element); + if (this.appWrapper) { + this.appWrapper.appendChild(this.element); + } else { + document.body.appendChild(this.element); + } this.cameraManager = new CameraManager(this.element, this.collisionsManager); this.cameraManager.camera.add(this.audioListener); diff --git a/packages/3d-web-client-core/src/tweakpane/TweakPane.ts b/packages/3d-web-client-core/src/tweakpane/TweakPane.ts index 4a468dce..4272e1d1 100644 --- a/packages/3d-web-client-core/src/tweakpane/TweakPane.ts +++ b/packages/3d-web-client-core/src/tweakpane/TweakPane.ts @@ -27,7 +27,7 @@ import { setTweakpaneActive } from "./tweakPaneActivity"; import { tweakPaneStyle } from "./tweakPaneStyle"; export class TweakPane { - private gui: Pane = new Pane(); + private gui: Pane; private renderStatsFolder: RendererStatsFolder; private rendererFolder: RendererFolder; @@ -49,6 +49,12 @@ export class TweakPane { private scene: Scene, private composer: EffectComposer, ) { + const appWrapper = document.getElementById("app")!; + const tweakPaneWrapper = document.createElement("div"); + tweakPaneWrapper.id = "tweakpane-panel"; + appWrapper.appendChild(tweakPaneWrapper); + + this.gui = new Pane({ container: tweakPaneWrapper! }); this.gui.registerPlugin(EssentialsPlugin); if (this.saveVisibilityInLocalStorage) { @@ -81,24 +87,24 @@ export class TweakPane { this.export = this.gui.addFolder({ title: "import / export", expanded: false }); window.addEventListener("keydown", this.processKey.bind(this)); - - this.setupGUIListeners.bind(this)(); this.setupRenderPane = this.setupRenderPane.bind(this); - } - - private processKey(e: KeyboardEvent): void { - if (e.key === "p") this.toggleGUI(); + this.setupGUIListeners.bind(this)(); } private setupGUIListeners(): void { const gui = this.gui as any; const paneElement: HTMLElement = gui.containerElem_; - paneElement.style.display = this.guiVisible ? "unset" : "none"; + paneElement.style.right = this.guiVisible ? "0px" : "-450px"; + this.gui.element.addEventListener("mouseenter", () => setTweakpaneActive(true)); this.gui.element.addEventListener("mousedown", () => setTweakpaneActive(true)); this.gui.element.addEventListener("mouseup", () => setTweakpaneActive(false)); this.gui.element.addEventListener("mouseleave", () => setTweakpaneActive(false)); } + private processKey(e: KeyboardEvent): void { + if (e.key === "p") this.toggleGUI(); + } + public setupRenderPane( composer: EffectComposer, normalPass: NormalPass, @@ -192,10 +198,10 @@ export class TweakPane { } private toggleGUI(): void { + this.guiVisible = !this.guiVisible; const gui = this.gui as any; const paneElement: HTMLElement = gui.containerElem_; - paneElement.style.display = this.guiVisible ? "none" : "unset"; - this.guiVisible = !this.guiVisible; + paneElement.style.right = this.guiVisible ? "0px" : "-450px"; if (this.saveVisibilityInLocalStorage) { localStorage.setItem("guiVisible", this.guiVisible === true ? "true" : "false"); } diff --git a/packages/3d-web-client-core/src/tweakpane/blades/rendererStatsFolder.ts b/packages/3d-web-client-core/src/tweakpane/blades/rendererStatsFolder.ts index d9ca0218..f151e7a4 100644 --- a/packages/3d-web-client-core/src/tweakpane/blades/rendererStatsFolder.ts +++ b/packages/3d-web-client-core/src/tweakpane/blades/rendererStatsFolder.ts @@ -35,20 +35,15 @@ export class RendererStatsFolder { constructor(parentFolder: FolderApi, expanded: boolean = true) { this.folder = parentFolder.addFolder({ title: "renderStats", expanded: expanded }); - this.performance = this.folder.addFolder({ title: "performance", expanded: true }); - this.defails = this.folder.addFolder({ title: "pipeline details", expanded: false }); - this.folder.addBlade({ view: "separator" }); - - this.performance.addBinding(this.statsData, "FPS", { readonly: true }); - this.performance.addBinding(this.statsData, "deltaTime", { readonly: true }); - this.performance.addBinding(this.statsData, "rawDeltaTime", { readonly: true }); - - this.defails.addBinding(this.statsData, "triangles", { readonly: true }); - this.defails.addBinding(this.statsData, "geometries", { readonly: true }); - this.defails.addBinding(this.statsData, "textures", { readonly: true }); - this.defails.addBinding(this.statsData, "shaders", { readonly: true }); - this.defails.addBinding(this.statsData, "postPasses", { readonly: true }); - this.defails.addBinding(this.statsData, "drawCalls", { readonly: true }); + this.folder.addBinding(this.statsData, "FPS", { readonly: true }); + this.folder.addBinding(this.statsData, "deltaTime", { readonly: true }); + this.folder.addBinding(this.statsData, "rawDeltaTime", { readonly: true }); + this.folder.addBinding(this.statsData, "triangles", { readonly: true }); + this.folder.addBinding(this.statsData, "geometries", { readonly: true }); + this.folder.addBinding(this.statsData, "textures", { readonly: true }); + this.folder.addBinding(this.statsData, "shaders", { readonly: true }); + this.folder.addBinding(this.statsData, "postPasses", { readonly: true }); + this.folder.addBinding(this.statsData, "drawCalls", { readonly: true }); } public update(renderer: WebGLRenderer, composer: EffectComposer, timeManager: TimeManager): void { diff --git a/packages/3d-web-client-core/src/tweakpane/tweakPaneStyle.ts b/packages/3d-web-client-core/src/tweakpane/tweakPaneStyle.ts index a50fe986..4d280bcb 100644 --- a/packages/3d-web-client-core/src/tweakpane/tweakPaneStyle.ts +++ b/packages/3d-web-client-core/src/tweakpane/tweakPaneStyle.ts @@ -1,6 +1,6 @@ export const tweakPaneStyle = ` :root { - --tp-base-background-color: rgba(0, 0, 0, 0.6); + --tp-base-background-color: rgba(12, 12, 12, 0.6); --tp-base-shadow-color: hsla(0, 0%, 0%, 0.2); --tp-button-background-color: hsla(0, 0%, 80%, 1); --tp-button-background-color-active: hsla(0, 0%, 100%, 1); @@ -21,6 +21,9 @@ export const tweakPaneStyle = ` --tp-label-foreground-color: hsla(0, 0%, 100%, 0.6); --tp-monitor-background-color: hsla(0, 0%, 0%, 0.3); --tp-monitor-foreground-color: hsla(0, 0%, 100%, 0.3); + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; } .tp-brkv { @@ -30,28 +33,40 @@ export const tweakPaneStyle = ` } .tp-dfwv { + z-index: 100; color: white; - backdrop-filter: blur(12px); - width: 360px !important; + width: 600px !important; display: none; -webkit-user-select: none; -ms-user-select: none; user-select: none; } +.tp-fldv { + margin: 1px 0px 0px 0px !important; +} + +.tp-fldv_b { + overflow: visible !important; +} + .tp-fldv_t { - font-size: 11px; - background-color: rgba(0, 0, 0, 0.1); + font-size: 13px; + font-weight: 900; + color: #ffffff; + background-color: rgba(70, 70, 70, 0.3); + border-top: 1px solid rgba(210, 210, 210, 0.1); + border-radius: 3px; } .tp-lblv_l { - font-size: 11px; + font-size: 12px; padding-left: 0px !important; padding-right: 0px !important; } .tp-lblv_v { - width: 180px; + width: 150px; } .tp-sldtxtv_t { @@ -59,7 +74,11 @@ export const tweakPaneStyle = ` } .tp-sglv_i { - font-size: 11px; + font-size: 12px; color: rgba(255, 255, 255, 0.7); } + +.tp-ckbv_w { + border: 1px solid rgba(200, 200, 250, 0.2); +} `; diff --git a/packages/3d-web-text-chat/src/chat-ui/TextChatUI.tsx b/packages/3d-web-text-chat/src/chat-ui/TextChatUI.tsx index 039e6d18..a71dd6a2 100644 --- a/packages/3d-web-text-chat/src/chat-ui/TextChatUI.tsx +++ b/packages/3d-web-text-chat/src/chat-ui/TextChatUI.tsx @@ -18,13 +18,15 @@ export class TextChatUI { if (this.appRef.current) this.appRef.current.addMessage(username, message); } - private container = document.getElementById("text-chat-ui")!; + private wrapper = document.createElement("div"); + private container = document.getElementById("app")!; constructor( private clientname: string, private sendMessageToServerMethod: (message: string) => void, ) { - this.root = createRoot(this.container); + this.container.appendChild(this.wrapper); + this.root = createRoot(this.wrapper); this.sendMessageToServerMethod = sendMessageToServerMethod; } diff --git a/packages/3d-web-voice-chat/src/chat-ui/components/voice-chat-ui.tsx b/packages/3d-web-voice-chat/src/chat-ui/components/voice-chat-ui.tsx index ae31d53a..7c2302f7 100644 --- a/packages/3d-web-voice-chat/src/chat-ui/components/voice-chat-ui.tsx +++ b/packages/3d-web-voice-chat/src/chat-ui/components/voice-chat-ui.tsx @@ -128,7 +128,8 @@ const VoiceChatUIComponent = (props: VoiceChatUIComponentProps) => { export class VoiceChatUI { private root: Root; - private container = document.getElementById("voice-chat-ui")!; + private wrapper = document.createElement("div"); + private container = document.getElementById("app")!; private activeSpeakers: number = 0; private speaking: boolean = false; @@ -139,7 +140,8 @@ export class VoiceChatUI { private handleClickMic: () => void, private handlePassword: (password: string) => void, ) { - this.root = createRoot(this.container); + this.container.appendChild(this.wrapper); + this.root = createRoot(this.wrapper); } public setActiveSpeakers(activeSpeakers: number): void {