Skip to content
Snippets Groups Projects
Commit 58134bc7 authored by Robert Long's avatar Robert Long
Browse files

Stats panel component that collapses to an FPS counter

parent 339fa099
No related branches found
No related tags found
No related merge requests found
:global(.rs-header) {
display: flex;
justify-content: space-between;
border-bottom: 1px rgba(255,255,255,0.1) solid;
margin-bottom: 8px;
}
:global(.rs-collapse-btn) {
cursor: pointer;
font-size: 12px;
}
:global(.rs-fps-counter) {
cursor: pointer;
position: absolute;
bottom: 0;
left: 0;
padding: 8px;
color: #aaa;
font-size: 10px;
}
:global(.rs-mobile) {
bottom: auto;
top: 0;
}
\ No newline at end of file
import "./stats-plus.css";
// Adapted from https://github.com/aframevr/aframe/blob/master/src/components/scene/stats.js
function createStats(scene) {
const threeStats = new window.threeStats(scene.renderer);
const aframeStats = new window.aframeStats(scene);
const plugins = scene.isMobile ? [] : [threeStats, aframeStats];
return new window.rStats({
css: [], // Our stylesheet is injected from AFrame.
values: {
fps: { caption: "fps", below: 30 }
},
groups: [{ caption: "Framerate", values: ["fps", "raf"] }],
plugins: plugins
});
}
const HIDDEN_CLASS = "a-hidden";
AFRAME.registerComponent("stats-plus", {
// Whether or not the stats panel is expanded.
// Shows FPS counter when collapsed.
schema: { default: false },
init() {
this.onExpand = this.onExpand.bind(this);
this.onCollapse = this.onCollapse.bind(this);
this.onEnterVr = this.onEnterVr.bind(this);
this.onExitVr = this.onExitVr.bind(this);
const scene = this.el.sceneEl;
this.stats = createStats(scene);
this.statsEl = document.querySelector(".rs-base");
// Add header to stats panel so we can collapse it
const statsHeaderEl = document.createElement("div");
statsHeaderEl.classList.add("rs-header");
const statsTitleEl = document.createElement("h1");
statsTitleEl.innerHTML = "Stats";
statsHeaderEl.appendChild(statsTitleEl);
const collapseEl = document.createElement("div");
collapseEl.classList.add("rs-collapse-btn");
collapseEl.innerHTML = "X";
collapseEl.addEventListener("click", this.onCollapse);
statsHeaderEl.appendChild(collapseEl);
this.statsEl.insertBefore(statsHeaderEl, this.statsEl.firstChild);
// Add fps counter to the page
this.fpsEl = document.createElement("div");
this.fpsEl.addEventListener("click", this.onExpand);
this.fpsEl.classList.add("rs-fps-counter");
document.body.appendChild(this.fpsEl);
this.lastFpsUpdate = performance.now();
this.frameCount = 0;
if (scene.isMobile) {
this.statsEl.classList.add("rs-mobile");
this.fpsEl.classList.add("rs-mobile");
}
scene.addEventListener("enter-vr", this.onEnterVr);
scene.addEventListener("exit-vr", this.onExitVr);
},
update(oldData) {
if (oldData !== this.data) {
if (this.data) {
this.statsEl.classList.remove(HIDDEN_CLASS);
this.fpsEl.classList.add(HIDDEN_CLASS);
} else {
this.statsEl.classList.add(HIDDEN_CLASS);
this.fpsEl.classList.remove(HIDDEN_CLASS);
}
}
},
tick() {
if (this.data) {
// Update rStats
const stats = this.stats;
stats("rAF").tick();
stats("FPS").frame();
stats().update();
} else {
// Update the fps counter
const now = performance.now();
this.frameCount++;
// Update the fps counter text once a second
if (now >= this.lastFpsUpdate + 1000) {
const fps = this.frameCount / ((now - this.lastFpsUpdate) / 1000);
this.fpsEl.innerHTML = Math.round(fps) + " FPS";
this.lastFpsUpdate = now;
this.frameCount = 0;
}
}
},
onEnterVr() {
// Hide all stats elements when entering VR on mobile
if (this.el.sceneEl.isMobile) {
this.statsEl.classList.add(HIDDEN_CLASS);
this.fpsEl.classList.add(HIDDEN_CLASS);
}
},
onExitVr() {
// Revert to previous state whe exiting VR on mobile
if (this.el.sceneEl.isMobile) {
if (this.data) {
this.statsEl.classList.remove(HIDDEN_CLASS);
} else {
this.fpsEl.classList.remove(HIDDEN_CLASS);
}
}
},
onExpand() {
this.el.setAttribute(this.name, true);
},
onCollapse() {
this.el.setAttribute(this.name, false);
},
remove() {
this.el.sceneEl.removeListener("enter-vr", this.hide);
this.el.sceneEl.removeListener("exit-vr", this.show);
if (this.statsEl) {
this.statsEl.parentNode.removeChild(this.statsEl);
this.fpsEl.parentNode.removeChild(this.fpsEl);
}
}
});
......@@ -46,6 +46,7 @@ import "./components/hand-poses";
import "./components/gltf-model-plus";
import "./components/gltf-bundle";
import "./components/hud-controller";
import "./components/stats-plus";
import ReactDOM from "react-dom";
import React from "react";
......@@ -133,6 +134,8 @@ async function enterScene(mediaStream, enterInVR, janusRoomId) {
document.querySelector("a-scene canvas").classList.remove("blurred");
scene.render();
scene.setAttribute("stats-plus", false);
if (enterInVR) {
scene.enterVR();
}
......@@ -146,10 +149,6 @@ async function enterScene(mediaStream, enterInVR, janusRoomId) {
serverURL: process.env.JANUS_SERVER
});
if (!qsTruthy("no_stats")) {
scene.setAttribute("stats", true);
}
if (isMobile || qsTruthy("mobile")) {
playerRig.setAttribute("virtual-gamepad-controls", {});
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment