feat: add dynamic navbar to scenes

Introduced a new CSS file for styling a fixed navbar in scenes,
enhancing user navigation within the virtual environment. Modified
scene.js to include fetching categories and generating a navbar with
scene options dynamically based on the category of the current scene.
This allows users to switch scenes more intuitively. The `nonavbar`
attribute was added for scenes where the navbar should be omitted,
providing flexibility in scene presentation. Additionally, streamlined
CSS and SCSS imports across JS files for consistency and removed an
unnecessary SCSS import from editor.js, optimizing load times and
project structure.

This update significantly improves user experience by facilitating
easier navigation and scene exploration within the application.
This commit is contained in:
Kumi 2024-03-15 16:41:37 +01:00
parent 2e819ba0a6
commit e3cff5b9b7
Signed by: kumi
GPG key ID: ECBCC9082395383F
4 changed files with 77 additions and 2 deletions

5
assets/css/scene.css Normal file
View file

@ -0,0 +1,5 @@
#sceneNavbar {
z-index: 99999;
position: fixed;
width: 100%;
}

View file

@ -1,7 +1,6 @@
import { getScene, getSceneElement, getCategory } from "./api"; import { getScene, getSceneElement, getCategory } from "./api";
import { populateDestinationDropdown } from "./editor/teleport"; import { populateDestinationDropdown } from "./editor/teleport";
import "../scss/frontend.scss";
import "../css/editor.css"; import "../css/editor.css";
let clickTimestamp = 0; let clickTimestamp = 0;

View file

@ -1,4 +1,8 @@
import { getScene } from "./api"; import { getScene, getCategory } from "./api";
import { Dropdown } from "bootstrap";
import "../scss/frontend.scss";
import "../css/scene.css";
require("aframe"); require("aframe");
@ -16,8 +20,13 @@ class QuackscapeScene extends HTMLElement {
this.x = this.getAttribute("x") | 0; this.x = this.getAttribute("x") | 0;
this.y = this.getAttribute("y") | 0; this.y = this.getAttribute("y") | 0;
this.z = this.getAttribute("z") | 0; this.z = this.getAttribute("z") | 0;
this.navbar = this.getAttribute("nonavbar") == undefined;
loadScene(this.scene, this.x, this.y, this.z, this, this.embedded); loadScene(this.scene, this.x, this.y, this.z, this, this.embedded);
if (this.navbar) {
loadNavbar(this.scene, this);
}
} }
} }
@ -27,6 +36,67 @@ document.addEventListener("contextmenu", function (event) {
customElements.define("quackscape-scene", QuackscapeScene); customElements.define("quackscape-scene", QuackscapeScene);
// Function to add a navbar to the destination object
async function loadNavbar(scene_id, destination) {
getScene(scene_id).then((scene) => {
getCategory(scene.obj.category).then((category) => {
var nav = document.createElement("nav");
nav.setAttribute("class", "navbar navbar-expand-lg navbar-dark bg-dark");
nav.setAttribute("id", "sceneNavbar");
var container = document.createElement("div");
container.setAttribute("class", "container-fluid");
var dropdown = document.createElement("div");
dropdown.setAttribute("class", "dropdown");
var sceneSelector = document.createElement("button");
sceneSelector.setAttribute("class", "btn btn-secondary dropdown-toggle");
sceneSelector.setAttribute("type", "button");
sceneSelector.setAttribute("id", "sceneSelector");
sceneSelector.setAttribute("data-bs-toggle", "dropdown");
sceneSelector.setAttribute("aria-expanded", "true");
sceneSelector.textContent = "Select Scene";
var dropdownMenu = document.createElement("ul");
dropdownMenu.setAttribute("class", "dropdown-menu show");
dropdownMenu.setAttribute("aria-labelledby", "sceneSelector");
console.log(dropdownMenu);
category.obj.scenes.forEach((scene) => {
console.log(scene);
var sceneLink = document.createElement("a");
sceneLink.setAttribute("class", "dropdown-item");
sceneLink.setAttribute("href", "#");
sceneLink.textContent = scene.title;
sceneLink.addEventListener("click", function () {
loadScene(scene.id, -1, -1, -1, destination);
});
dropdownMenu.appendChild(sceneLink);
});
var sceneTitle = document.createElement("a");
sceneTitle.setAttribute("class", "navbar-brand");
sceneTitle.setAttribute("href", "#");
sceneTitle.setAttribute("id", "sceneTitle");
sceneTitle.textContent = scene.obj.title;
dropdown.appendChild(sceneSelector);
dropdown.appendChild(dropdownMenu);
console.log(dropdownMenu);
container.appendChild(dropdown);
container.appendChild(sceneTitle);
nav.appendChild(container);
destination.prepend(nav);
});
});
}
// Function to load a scene into a destination object // Function to load a scene into a destination object
// x and y signify the initial looking direction, -1 for the scene's default // x and y signify the initial looking direction, -1 for the scene's default

View file

@ -30,6 +30,7 @@
y="{{ scene.default_y }}" y="{{ scene.default_y }}"
z="{{ scene.default_z }}" z="{{ scene.default_z }}"
embedded embedded
nonavbar
></quackscape-scene> ></quackscape-scene>
</div> </div>