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", "");
}
}
});