import { getScene, getSceneElement } from "./api"; import { Modal } from "bootstrap"; let clickTimestamp = 0; var editModal = null; // Find parent quackscape-scene for ID function findParentScene(element) { var parent = element.parentElement; while (parent.tagName != "QUACKSCAPE-SCENE") { parent = parent.parentElement; } return parent; } document.addEventListener("DOMContentLoaded", function () { editModal = new Modal("#editModal"); }); // Distinguishing clicks from drags based on duration. // TODO: Find a better way to distinguish these. function addEventListeners(element) { element.addEventListener("mousedown", function (event) { clickTimestamp = event.timeStamp; }); element.addEventListener("mouseup", function (event) { if (event.timeStamp - clickTimestamp > 200) { // Ignoring this, we only handle regular short clicks. // TODO: Find a way to handle drags of elements return; } else { handleClick(event); } // Right-clicks are definitely intentional. element.addEventListener("contextmenu", function (event) { handleClick(event); }); }); } // Open a modal for creating a new Element function startCreateModal(event) { var modalLabel = document.getElementById("editModalLabel"); modalLabel.textContent = "Create Element"; var modalContent = document.getElementById("editModalContent"); var thetaStart = cartesianToTheta( event.detail.intersection.point.x, event.detail.intersection.point.z ); modalContent.innerHTML = `Creating element at:
X: ${event.detail.intersection.point.x}
Y: ${event.detail.intersection.point.y}
Z: ${event.detail.intersection.point.z}
Calculated Theta: ${thetaStart}
Parent Element Type: ${event.srcElement.tagName}

`; editModal.show(); } function startModifyModal(event) { var modalLabel = document.getElementById("editModalLabel"); modalLabel.textContent = "Modify Element"; // Get element from API var scene = findParentScene(event.target); var element_data_request = getSceneElement( scene.getAttribute("id"), event.target.getAttribute("id") ); element_data_request.then((element_data) => { console.log(element_data); var modalContent = document.getElementById("editModalContent"); modalContent.innerHTML = `Modifying element:
Element Type: ${event.srcElement.tagName}
Element ID: ${event.target.getAttribute("id")}
Element data: ${JSON.stringify(element_data.obj)}

`; editModal.show(); }); } function cartesianToTheta(x, z) { // Calculate the angle in radians let angleRadians = Math.atan2(z, x); // Convert to degrees let angleDegrees = angleRadians * (180 / Math.PI); // A-Frame's thetaStart is measured from the positive X-axis ("right" direction) // and goes counter-clockwise, so this should directly give us the thetaStart value. let thetaStart = 90 - angleDegrees; // Since atan2 returns values from -180 to 180, let's normalize this to 0 - 360 thetaStart = thetaStart < 0 ? thetaStart + 360 : thetaStart; return thetaStart; } function latLonToXYZ(lat, lon, radius = 5) { // Convert lat/lon to X/Y/Z coordinates on the sphere const phi = (90 - lat) * (Math.PI / 180); const theta = (lon + 180) * (Math.PI / 180); const x = -(radius * Math.sin(phi) * Math.cos(theta)); const y = radius * Math.cos(phi); const z = radius * Math.sin(phi) * Math.sin(theta); return { x, y, z }; } function handleClick(event) { console.log(event); if (event.target.tagName == "A-SKY") { startCreateModal(event); } else { startModifyModal(event); } } document.addEventListener("loadedQuackscapeScene", function (event) { // Get the scene var scene = document.querySelector("a-scene"); // Get all children var children = scene.children; for (var i = 0; i < children.length; i++) { var child = children[i]; if (child.tagName.startsWith("A-")) { // Remove original onclick events if (child.hasAttribute("onclick")) { child.removeAttribute("onclick"); } // Add new event listeners addEventListeners(child); // Add click-drag component to all a-entity elements child.setAttribute("click-drag", ""); } } });