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