如何在文件作用域获取匿名函数属性并适配容器尺寸至加载对象大小
Hey there! Let's break down how to solve your two requirements step by step, with code examples tailored to your existing snippet.
1. Access Properties from the Anonymous Callback in File Scope
The core challenge here is handling the asynchronous nature of loader.load()—the callback runs only after the file finishes loading, so we need a reliable way to capture those values and use them outside the callback. Here are two practical approaches:
Option 1: Use a File-Scoped Variable
Declare a variable outside the load() call, then assign it inside the callback. Just keep in mind: don’t try to use the variable immediately after load()—it’ll stay undefined until the callback executes.
// Declare variable in file scope let globalSliceZ; let loader = new THREE.NRRDLoader(); loader.load(this.Filename, function (volume) { // Assign the extracted slice to the file-scoped variable globalSliceZ = volume.extractSlice('z', Math.floor(volume.RASDimensions[2] / 4)); scene.add(globalSliceZ.mesh); // Trigger any logic that depends on globalSliceZ here adjustContainerSize(); }); // Example function that uses the global variable (call it only after the callback runs!) function adjustContainerSize() { if (!globalSliceZ) return; // Your container resizing logic goes here }
Option 2: Wrap Loader in a Promise (Async/Await Style)
This makes your code read like synchronous code, avoiding messy callback nesting and making it easier to access values in the file scope.
let loader = new THREE.NRRDLoader(); // Wrap the load function in a Promise to use async/await function loadNRRD(filename) { return new Promise((resolve, reject) => { loader.load(filename, resolve, undefined, reject); }); } // Use async/await to fetch and process the volume async function initVolume() { try { const volume = await loadNRRD(this.Filename); const sliceZ = volume.extractSlice('z', Math.floor(volume.RASDimensions[2] / 4)); scene.add(sliceZ.mesh); // Now sliceZ is available here, and you can pass it to other functions adjustContainerSize(sliceZ); // Assign to file scope if needed window.globalSliceZ = sliceZ; } catch (error) { console.error('Failed to load NRRD file:', error); } } // Start the loading process initVolume();
2. Read Loaded Object Dimensions & Resize Container to Match
Three.js meshes don’t have a direct width/height property, so we’ll calculate the mesh’s bounding box to get its actual size. Then we’ll adjust the HTML container and update the Three.js camera/renderer to fit the new dimensions.
Here’s the implementation (building on the adjustContainerSize function from earlier):
function adjustContainerSize(sliceZ) { const mesh = sliceZ.mesh; // Calculate the mesh's bounding box mesh.geometry.computeBoundingBox(); const boundingBox = mesh.geometry.boundingBox; if (!boundingBox) { console.warn('Could not calculate bounding box for the mesh'); return; } // Get actual width/height (account for mesh scale) const width = (boundingBox.max.x - boundingBox.min.x) * mesh.scale.x; const height = (boundingBox.max.y - boundingBox.min.y) * mesh.scale.y; // Target your HTML container (replace with your actual container ID/class) const container = document.getElementById('threejs-container'); // Set container size (add padding if needed) container.style.width = `${width}px`; container.style.height = `${height}px`; // Update Three.js camera and renderer to fit the new container const camera = yourCamera; // Replace with your actual camera instance const renderer = yourRenderer; // Replace with your actual renderer instance camera.aspect = width / height; camera.updateProjectionMatrix(); renderer.setSize(width, height); }
Quick Notes:
- Replace
'threejs-container',yourCamera, andyourRendererwith your actual DOM element ID and Three.js instances. - For meshes with complex materials (like transparency), the bounding box calculation still works for basic dimension needs.
内容的提问来源于stack exchange,提问作者Yone

