Skip to content

Commit

Permalink
feat(#7): ✨ Created "Evelation Control" section with belonging functi…
Browse files Browse the repository at this point in the history
…onality
  • Loading branch information
mariewah committed Sep 29, 2025
1 parent 7ee1333 commit 07a8eff
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 3 deletions.
5 changes: 4 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
type="text/css"
href="/libs/jstree/themes/mixed/style.css"
/>
<link rel="stylesheet" type="text/css" href="src/style.css" />
</head>

<body>
Expand Down Expand Up @@ -67,6 +68,7 @@

viewer.loadGUI(() => {
viewer.setLanguage('en')
$('#menu_customised').next().show()
$('#menu_appearance').next().show()
$('#menu_tools').next().show()
$('#menu_scene').next().show()
Expand All @@ -82,11 +84,12 @@
material.pointSizeType = Potree.PointSizeType.ADAPTIVE
material.shape = Potree.PointShape.CIRCLE
material.activeAttributeName = 'elevation'
material.gradient = Potree.Gradients['RAINBOW']
material.gradient = Potree.Gradients['VIRIDIS']

viewer.scene.addPointCloud(pointcloud)
viewer.fitToScreen()
})
</script>
<script type="module" src="src/main.js"></script>
</body>
</html>
138 changes: 137 additions & 1 deletion src/main.js
Original file line number Diff line number Diff line change
@@ -1 +1,137 @@
/* Empty for now, add logic later */
/**
* Creating and inserting a new customised "Elevation Range" section in the sidebar above Apperance
* with the same css style features as Apperance
*/
(function () {

//Insert new the sidebar above Apperance
function insertCustomisedAboveAppearance() {
const appearanceHeader = document.querySelector('#menu_appearance');
if (!appearanceHeader) return false;
if (document.querySelector('#menu_customised_header')) return true;

//Clone the header for identical style to apperance
const customHeader = appearanceHeader.cloneNode(true);
customHeader.removeAttribute('id');
customHeader.id = 'menu_customised_header';
customHeader.textContent = 'Elevation Control';
customHeader.style.cursor = 'pointer';
customHeader.setAttribute('tabindex', '0');

//Creating a new "div" in the customised section similar to the Apperance div
const appearanceBody = appearanceHeader.nextElementSibling;
const bodyClass = appearanceBody ? appearanceBody.className : 'pv-menu-list';
const customBody = document.createElement('div');
customBody.className = bodyClass;
customBody.id = 'customised_list';
customBody.style.display = ''; // start expanded

//Insert both right before Appearance
appearanceHeader.parentElement.insertBefore(customHeader, appearanceHeader);
appearanceHeader.parentElement.insertBefore(customBody, appearanceHeader);

//collapse/expand
const toggle = () => {
const hidden = customBody.style.display === 'none';
customBody.style.display = hidden ? '' : 'none';
};
customHeader.addEventListener('click', toggle);
customHeader.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggle(); }
});

return true;
}

function init() {
if (insertCustomisedAboveAppearance()) return;
let tries = 0;
const t = setInterval(() => {
tries++;
if (insertCustomisedAboveAppearance() || tries > 50) clearInterval(t);
}, 200);
}

if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
else init();
})();



/**
* A function that:
* - Autoselects the first pointcloud
* - Move the Elevation block from the Scene section into the custimosed Elevation Control section
*
* Nice to know: In the oroginal code the Elevation section in the Properties panel is only built when the pointcloud is clicked on
*/
(function () {
const $ = (sel, root = document) => root.querySelector(sel);

//Select the fist pointcloud in the sidebar so that the Elevation section is built
function autoSelectFirstPointCloud() {
const cloudIcon = document.querySelector('#scene_objects i.jstree-themeicon-custom');
if (cloudIcon) {
cloudIcon.dispatchEvent(new MouseEvent('click', { bubbles: true }));
return true;
}
return false;
}

//(re)connect the elevation labels to the slider after the container is moved (was not handled by default)
function rebindElevationLabel() {
const slider = window.jQuery ? window.jQuery("#sldHeightRange") : null;
const label = document.getElementById("lblHeightRange");
if (!slider || !slider.length || !label) return;

const update = () => {
const low = $slider.slider("values", 0);
const high = $slider.slider("values", 1);
label.textContent = `${low.toFixed(2)} to ${high.toFixed(2)}`;
};

//clear any old namespaced handlers and attach fresh ones
slider.off("slide.custom slidestop.custom change.custom");
slider.on("slide.custom", update);
slider.on("slidestop.custom change.custom", update);
update();
}

//Move the elevation range section to the customised "Elevation Control" section
function moveElevationContainer() {
const target = $('#customised_list');
const elevationContainer = document.querySelector('#materials\\.elevation_container');
if (!elevationContainer) return false;
target.appendChild(elevationContainer);
rebindElevationLabel();
return true;

}

function init() {
let tries = 0;
const t = setInterval(() => {
const hasCloud = !!(window.viewer?.scene?.pointclouds?.length);
if (hasCloud) {
autoSelectFirstPointCloud();
// Wait until potree builds the Properties, then move the container
let innerTries = 0;
const t2 = setInterval(() => {
const movedElevation = moveElevationContainer();
if (movedElevation || ++innerTries > 100) clearInterval(t2);
}, 100);

clearInterval(t);
}
if (++tries > 30) clearInterval(t);
}, 100);
}

if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();


12 changes: 11 additions & 1 deletion src/style.css
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
/* Empty for now, add styles later */
/* making sure that the divider span the whole sidebar (as the original code) */
#customised_list > .divider {
margin: 0;
padding: 0;
}

/* Padding of list items in the elevation control section as the original code*/
#customised_list li {
list-style-type: none;
padding: 0 20px;
}

0 comments on commit 07a8eff

Please sign in to comment.