Skip to content
Snippets Groups Projects
Unverified Commit caddce90 authored by Robert Long's avatar Robert Long Committed by GitHub
Browse files

Merge pull request #197 from mozilla/feature/stats-plus

Stats panel component that collapses to an FPS counter
parents fb036eb9 58134bc7
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);
}
}
});
...@@ -49,6 +49,7 @@ import "./components/hand-poses"; ...@@ -49,6 +49,7 @@ import "./components/hand-poses";
import "./components/gltf-model-plus"; import "./components/gltf-model-plus";
import "./components/gltf-bundle"; import "./components/gltf-bundle";
import "./components/hud-controller"; import "./components/hud-controller";
import "./components/stats-plus";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import React from "react"; import React from "react";
...@@ -144,6 +145,8 @@ async function enterScene(mediaStream, enterInVR, janusRoomId) { ...@@ -144,6 +145,8 @@ async function enterScene(mediaStream, enterInVR, janusRoomId) {
document.querySelector("a-scene canvas").classList.remove("blurred"); document.querySelector("a-scene canvas").classList.remove("blurred");
scene.render(); scene.render();
scene.setAttribute("stats-plus", false);
if (enterInVR) { if (enterInVR) {
scene.enterVR(); scene.enterVR();
} }
...@@ -157,10 +160,6 @@ async function enterScene(mediaStream, enterInVR, janusRoomId) { ...@@ -157,10 +160,6 @@ async function enterScene(mediaStream, enterInVR, janusRoomId) {
serverURL: process.env.JANUS_SERVER serverURL: process.env.JANUS_SERVER
}); });
if (!qsTruthy("no_stats")) {
scene.setAttribute("stats", true);
}
if (isMobile || qsTruthy("mobile")) { if (isMobile || qsTruthy("mobile")) {
playerRig.setAttribute("virtual-gamepad-controls", {}); 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