import { getScene } from "./api"; import { loadSidebar } from "./scene/sidebar"; import { loadNavbar } from "./scene/navbar"; import aframe from "aframe"; import { Dropdown, Collapse } from "bootstrap"; import "../scss/frontend.scss"; import "../css/scene.css"; // Detect iOS devices // There is probably a better way to handle issues there, but... var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent); // Define the element class QuackscapeScene extends HTMLElement { connectedCallback() { // When one is created, automatically load the scene this.scene = this.getAttribute("scene"); this.embedded = this.getAttribute("embedded") != undefined; this.x = this.getAttribute("x") | 0; this.y = this.getAttribute("y") | 0; this.z = this.getAttribute("z") | 0; this.navbar = this.getAttribute("navbar") != undefined; this.sidebar = this.getAttribute("sidebar") != undefined; loadScene(this.scene, this.x, this.y, this.z, this, this.embedded); if (this.navbar) { loadNavbar(this.scene, this); } else if (this.sidebar) { loadSidebar(this.scene, this); } } } document.addEventListener("contextmenu", function (event) { event.preventDefault(); }); customElements.define("quackscape-scene", QuackscapeScene); // Function to load a scene into a destination object // x and y signify the initial looking direction, -1 for the scene's default async function loadScene( scene_id, x = -1, y = -1, z = -1, destination = null, embedded = false ) { // Get WebGL maximum texture size var canvas = document.createElement("canvas"); var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl"); if (!gl) { alert("Unable to initialize WebGL. Your browser may not support it."); return; } var maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); if (iOS) { maxTextureSize = Math.min(8192, maxTextureSize); } // Get scene information from API getScene(scene_id).then((response) => { var scene = response.obj; // Get largest image that will fit in the texture size from scene.resolutions // First, order the resolutions by width var resolutions = scene.base_content.resolutions.sort( (a, b) => b.width - a.width ); // Then, find the first resolution that is less than or equal to the max texture size var content = resolutions.find( (resolution) => resolution.width <= maxTextureSize ); // Select a destination element if not specified if (!destination) { destination = document.getElementsByTagName("quackscape-scene")[0]; } destination.setAttribute("id", scene_id); // Start by removing any existing scenes var scenes = document.getElementsByTagName("a-scene"); if (scenes.length > 0) { scenes[0].remove(); } // Now, build the scene element var a_scene = document.createElement("a-scene"); a_scene.setAttribute("cursor", "rayOrigin: mouse"); if (embedded) { a_scene.setAttribute("embedded", "embedded"); } // Create a-camera element var rig = document.createElement("a-entity"); rig.setAttribute("id", "rig"); // Rotate camera if requested if (x != -1 && y != -1 && z != -1) { rig.setAttribute("rotation", x + " " + y + " " + z); } var camera = document.createElement("a-camera"); camera.setAttribute("wasd-controls-enabled", "false"); // TODO: Find a more elegant way to disable z axis movement rig.appendChild(camera); a_scene.appendChild(rig); // Create a-assets element var assets = document.createElement("a-assets"); a_scene.appendChild(assets); // Add background image as sky var sky = document.createElement("a-sky"); sky.setAttribute("src", "#" + content.id); a_scene.appendChild(sky); // Add img element to assets var background = document.createElement("img"); background.setAttribute("id", content.id); background.setAttribute("src", content.file); assets.appendChild(background); // Add elements to scene scene.elements.forEach((element) => { var node = document.createElement(element.data.tag); node.setAttribute("id", element.data.id); for (const [key, value] of Object.entries(element.data.attributes)) { node.setAttribute(key, value); } // Add node to scene a_scene.appendChild(node); }); destination.appendChild(a_scene); // Dispatch a signal for the editor to pick up const loaded_event = new CustomEvent("loadedQuackscapeScene"); document.dispatchEvent(loaded_event); }); } window.loadScene = loadScene; window.aframe = aframe; export { loadScene };