Node group colors and toggling (draft)
This commit is contained in:
@@ -66,6 +66,7 @@ export const config = {
|
||||
},
|
||||
{
|
||||
label: 'Sala / Auditorium',
|
||||
color: 'rgb(212, 96, 75)',
|
||||
children: [
|
||||
{
|
||||
label: 'Peplano / Platea',
|
||||
@@ -108,6 +109,7 @@ export const config = {
|
||||
},
|
||||
{
|
||||
label: 'Scena',
|
||||
color: 'rgb(75, 100, 212)',
|
||||
children: [
|
||||
{
|
||||
label: 'Palcoscenico',
|
||||
@@ -129,6 +131,7 @@ export const config = {
|
||||
},
|
||||
{
|
||||
label: 'Spazi tecnici',
|
||||
color: 'rgb(42, 139, 75)',
|
||||
children: [
|
||||
{
|
||||
label: 'Spazio tecnico superiore',
|
||||
@@ -152,6 +155,7 @@ export const config = {
|
||||
},
|
||||
{
|
||||
label: 'Orchestra',
|
||||
color: 'rgb(187, 120, 218)',
|
||||
children: [
|
||||
{
|
||||
label: 'Fossa orchestra',
|
||||
|
||||
@@ -34,8 +34,46 @@ export default class extends Controller {
|
||||
*/
|
||||
const id = event?.params.node;
|
||||
const status = event?.target?.checked;
|
||||
ATON.getSceneNode(id).toggle(status);
|
||||
AppState.normalizedNodes.find(n => n.id === id).active = status;
|
||||
const node = AppState.normalizedNodes.find(n => n.id === id);
|
||||
|
||||
if (node.children.length > 0) {
|
||||
this.#toggleGroup(node, status);
|
||||
this.#syncGroupCheckboxes(node, status, this.layersTarget);
|
||||
} else {
|
||||
ATON.getSceneNode(id).toggle(status);
|
||||
node.active = status;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Recursively toggle children in a nodes group
|
||||
* @param {Object} groupNode
|
||||
* @param {Boolean} status
|
||||
*/
|
||||
#toggleGroup(groupNode, status) {
|
||||
for (const child of groupNode.children) {
|
||||
if (child.model) {
|
||||
ATON.getSceneNode(child.id).toggle(status);
|
||||
child.active = status;
|
||||
}
|
||||
if (child.children.length > 0) {
|
||||
this.#toggleGroup(child, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
#syncGroupCheckboxes(groupNode, status, container) {
|
||||
for (const child of groupNode.children) {
|
||||
const checkbox = container.querySelector(
|
||||
`[data-menu-node-param="${child.id}"]`
|
||||
);
|
||||
|
||||
console.debug(checkbox, child.id);
|
||||
|
||||
if (checkbox) checkbox.checked = status;
|
||||
|
||||
if (child.children.length > 0) {
|
||||
this.#syncGroupCheckboxes(child, status, container);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Clone a <template> by id
|
||||
|
||||
@@ -79,6 +79,11 @@ function loadNodes(nodes) {
|
||||
node.load(n.model);
|
||||
node.setRotation(...config.scene.initRotation);
|
||||
|
||||
node.setMaterial(new THREE.MeshPhongMaterial({
|
||||
transparent: false,
|
||||
color: n.color ?? '#fff',
|
||||
}));
|
||||
|
||||
// Apply any transparency before attaching to scene
|
||||
if (n.opacity !== undefined && n.opacity !== null) {
|
||||
node.setMaterial(new THREE.MeshPhongMaterial({
|
||||
|
||||
@@ -28,41 +28,49 @@
|
||||
* @param {Array} flatList
|
||||
* @param {Number} depth
|
||||
*/
|
||||
function traverse(node, flatList, depth = 1) {
|
||||
function traverseTree(node, flatList, depth = 1, inheritedColor = null) {
|
||||
if (!node.label) {
|
||||
console.error("Node missing label:", node);
|
||||
return;
|
||||
}
|
||||
|
||||
const color = node.color ?? inheritedColor;
|
||||
|
||||
const normNode = {
|
||||
...node,
|
||||
id: node.id ?? node.label,
|
||||
isMain: node.isMain ?? false,
|
||||
active: true,
|
||||
color: color ?? null,
|
||||
depth,
|
||||
children: [],
|
||||
};
|
||||
if (node.model) {
|
||||
normNode.model = node.model;
|
||||
}
|
||||
flatList.push({
|
||||
...normNode,
|
||||
depth
|
||||
});
|
||||
|
||||
flatList.push(normNode);
|
||||
|
||||
if (node.children && Array.isArray(node.children)) {
|
||||
for(let child of node.children) {
|
||||
traverse(child, flatList, depth + 1);
|
||||
for(const child of node.children) {
|
||||
normNode.children.push(
|
||||
traverseTree(child, flatList, depth + 1, color)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return normNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a flat list of nodes from
|
||||
* the nested structure in config
|
||||
* @param {Array} nodes
|
||||
* @returns {NormalizedSceneNode[]} A flat list of nodes
|
||||
* @returns {{flat: NormalizedSceneNode[], normNode: object}} A flat list of nodes
|
||||
**/
|
||||
export function normalizeNodes (nodes) {
|
||||
let flatList = [];
|
||||
traverse(nodes, flatList);
|
||||
const normNode = traverseTree(nodes, flatList);
|
||||
|
||||
return flatList;
|
||||
return {flat: flatList, normNode};
|
||||
}
|
||||
|
||||
@@ -46,6 +46,13 @@
|
||||
<script type="text/javascript" src="../../vendor/three/examples/js/controls/DragControls.js"></script>
|
||||
<script type="text/javascript" src="/dist/ATON.min.js"></script>
|
||||
|
||||
<script type="importmap">
|
||||
{
|
||||
"imports": {
|
||||
"@hotwired/stimulus": "../../vendor/@hotwired/stimulus/dist/stimulus.js"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<!-- Main js entry -->
|
||||
<script type="module" src="./index.js"></script>
|
||||
</head>
|
||||
|
||||
@@ -2,13 +2,14 @@ import { openScene } from "../../js/scene.js";
|
||||
import { config } from "../../config.js";
|
||||
import AppState from "../../js/state.js";
|
||||
import { normalizeNodes } from "../../js/utils/nodeUtils.js";
|
||||
import { initUI, pauseAudio } from "../../js/ui.js";
|
||||
import { initStimulus } from "../../js/utils/stimulus.js";
|
||||
|
||||
initStimulus();
|
||||
|
||||
AppState.currentScene = 'salvador';
|
||||
AppState.sceneHasAudio = true;
|
||||
const marker = config.markers.find(m => m.id === 'salvador');
|
||||
AppState.normalizedNodes = normalizeNodes(marker.nodes);
|
||||
AppState.normalizedNodes = normalizeNodes(marker.nodes).flat;
|
||||
|
||||
openScene(marker, AppState.normalizedNodes);
|
||||
initUI();
|
||||
pauseAudio('[data-bs-dismiss="modal"]');
|
||||
console.debug(AppState.normalizedNodes);
|
||||
|
||||
openScene(marker, AppState.normalizedNodes);
|
||||
@@ -8,6 +8,6 @@ initStimulus();
|
||||
|
||||
AppState.currentScene = 'ssgp';
|
||||
const marker = config.markers.find(m => m.id === 'ssgp');
|
||||
AppState.normalizedNodes = normalizeNodes(marker.nodes);
|
||||
AppState.normalizedNodes = normalizeNodes(marker.nodes).flat;
|
||||
|
||||
openScene(marker, AppState.normalizedNodes);
|
||||
|
||||
Reference in New Issue
Block a user