Refractored glb loader, Added dropdown selector, Added record number and scientific name text display, css styling

This commit is contained in:
2026-05-27 03:28:55 +08:00
parent 3d372494ff
commit 8da6546079
6 changed files with 145 additions and 49 deletions
Binary file not shown.
Binary file not shown.
+9 -1
View File
@@ -14,8 +14,16 @@
<style>
body { margin: 0; }
</style>
<link type="text/css" rel="stylesheet" href="main.css">
</head>
<body>
<script type="module" src="/main.js"></script>
<div id="mabuligheader">
<h1>Mabulig Web</h1>
</div>
<div id="info">
<h2 id="recordnumbertext">Record Number</h2>
<h1 id="nametext"> Scientific Name</h1>
</div>
<script type="module" src="main.js"></script>
</body>
</html>
+54
View File
@@ -0,0 +1,54 @@
@font-face {
font-family: "Blender Pro Book";
src: url("fonts/BlenderPro-Bold.woff2") format("woff2"),
url("fonts/BlenderPro-Bold.woff") format("woff");
}
#info {
position: absolute;
bottom: 50px;
width: 100%;
padding: 10px;
box-sizing: border-box;
text-align: center;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
pointer-events: none;
z-index: 1; /* TODO Solve this in HTML */
font-family: 'Blender Pro Book';
font-weight: normal;
font-style: normal;
}
#mabuligheader {
position: absolute;
top: 10px;
width: 100%;
padding: 10px;
box-sizing: border-box;
text-align: center;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
pointer-events: none;
z-index: 1; /* TODO Solve this in HTML */
font-family: 'Blender Pro Book';
font-weight: normal;
font-style: normal;
}
h1 {
margin: 5px;
}
h2 {
margin: 0px;
}
h3 {
margin: 0px;
}
+81 -47
View File
@@ -12,7 +12,6 @@ const sizes = {
height: window.innerHeight,
}
//console.log(sizes.width + "x" + sizes.height);
//RENDERER
const renderer = new THREE.WebGLRenderer({antialias:true});
@@ -25,11 +24,12 @@ renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFShadowMap;
document.body.appendChild( renderer.domElement );
//CAMERA
const camera = new THREE.PerspectiveCamera( 65, sizes.width / sizes.height, 0.1, 1000 );
camera.position.x = 0;
camera.position.y = 2;
camera.position.z = 7.5;
camera.position.y = 0;
camera.position.z = 2;
const controls = new OrbitControls( camera, renderer.domElement );
controls.enableDamping = true;
@@ -38,8 +38,6 @@ controls.screenSpacePanning = false; // Vertical panning along screen
controls.update();
//RESIZING
function handleResize(){
sizes.width = window.innerWidth;
@@ -52,67 +50,103 @@ function handleResize(){
window.addEventListener("resize", handleResize);
//MODEL LOADER
let core_logo_mesh;
const loader = new GLTFLoader();
loader.load( 'models/MBS-2408 Oreophryne anulata.glb', function ( glb ) {
core_logo_mesh = glb.scene;
scene.add( glb.scene );
let currentModel = null;
}, undefined, function ( error ) {
console.error( error );
// MODEL PATHS
const modelPaths = {
'[MBS-2351] Ansonia muelleri': 'models/MBS-2351 Ansonia muelleri.glb',
'[MBS-2355] Platymantis corrugatus': 'models/MBS-2355 Platymantis corrugatus.glb',
'[MBS-2357] Hylarana grandocula': 'models/MBS-2357 Hylarana grandocula.glb',
'[MBS-2358] Sanguirana mearnsi': 'models/MBS-2358 Sanguirana mearnsi.glb',
'[MBS-2362] Hoplobatrachus rugulosus': 'models/MBS-2362 Hoplobatrachus rugulosus.glb',
'[MBS-2407] Staurois natator': 'models/MBS-2407 Staurois natator.glb',
'[MBS-2408] Oreophryne anulata': 'models/MBS-2408 Oreophryne anulata.glb',
'[MBS-2410] Platymantis guentheri': 'models/MBS-2410 Platymantis guentheri.glb',
'[MBS-2415] Kaloula pulchra': 'models/MBS-2415 Kaloula pulchra.glb',
'[MBS-2416] Rhinella marina': 'models/MBS-2416 Rhinella marina.glb',
'Frog Zoo': 'models/-------- Frog Zoo.glb'
};
const params = {
selectedModel: modelPaths['[MBS-2351] Ansonia muelleri'] // default selected option
};
function updateNameText(name) {
const recordtitleElement = document.getElementById('recordnumbertext');
const titleElement = document.getElementById('nametext');
//Record Number
const recnumberstart = name.slice(7);
const trimmedrecnumber = recnumberstart.slice(0,8);
recordtitleElement.textContent = trimmedrecnumber;
//Scientific Name
const trimmedstart = name.slice(16);
const trimmedsciname = trimmedstart.slice(0, -4);
titleElement.textContent = trimmedsciname;
}
// LOADING FUNCTION
function loadNewModel(url) {
if (currentModel) {
scene.remove(currentModel);
currentModel.traverse((child) => {
if (child.isMesh) {
child.geometry.dispose();
if (Array.isArray(child.material)) {
child.material.forEach(mat => mat.dispose());
} else {
child.material.dispose();
}
}
});
currentModel = null;
}
//Load the new model
loader.load(
url,
(glb) => {
currentModel = glb.scene;
scene.add(currentModel);
}
);
//Call function to update name text
updateNameText(params.selectedModel);
}
// GUI
const gui = new GUI({ width: 425 });
gui.add(params, 'selectedModel', modelPaths)
.name('Displayed Model:')
.onChange((newUrl) => {
loadNewModel(newUrl);
});
// Load the initial default model right away
loadNewModel(params.selectedModel);
gui.domElement.style.right = '0px';
//ENVIRONMENT
const env_loader = new UltraHDRLoader();
const env_texture = await env_loader.loadAsync( 'assets/studio_small_08_4k.jpg' );
env_texture.mapping = THREE.EquirectangularReflectionMapping;
scene.background = new THREE.Color(0xe6e6e6);
// scene.background = env_texture;
// scene.backgroundBlurriness = 0.5;
scene.environment = env_texture;
// console.log(scene.environment);
//LIGHTS
const ambient_light = new THREE.AmbientLight( 0xFFFFFF , 0.1); // soft white light
scene.add( ambient_light );
const sun = new THREE.DirectionalLight( 0xFFFFFF, 0.5);
sun.castShadow = true;
scene.add( sun );
// const helper = new THREE.DirectionalLightHelper( sun, 5 );
// scene.add( helper );
//EFFECTS PASS
// const composer = new EffectComposer( renderer );
// const renderPass = new RenderPass(scene, camera);
// composer.addPass(renderPass);
// const bloomPass = new UnrealBloomPass(
// new THREE.Vector2(sizes.width, sizes.height),
// 0.35, // strength
// 1, // radius
// 1 // threshold
// );
// composer.addPass(bloomPass);
//UPDATE PER FRAME
renderer.setAnimationLoop( animate );
function animate( time ) {
//cube.rotation.x = time / 2000;
//cube.rotation.y = time / 1000;
controls.update();
//core_logo_mesh.rotation.y = time / 1000;
renderer.render( scene, camera );
//console.log(camera.position);
// if (core_logo_mesh){
// core_logo_mesh.rotation.y = time / 1500;
// }
//composer.render();
}