這篇文章將教您如何使用Three.js來建立一個簡單的STL模型查看器,支援上傳STL檔案並即時顯示3D模型。本文將逐步分解完整範例程式碼,幫助您理解每個部分的功能。
使用者可以拖曳滑鼠來旋轉視角,並點擊頁面下方的上傳按鈕選擇STL檔案。選擇的模型會自動調整大小並置中,方便瀏覽。
首先,我們需要定義HTML頁面結構:
<!DOCTYPE html>
<html>
<head>
<title>STL Model Viewer</title>
<style>
body { margin: 0; overflow: hidden; }
#info {
position: absolute; top: 10px; width: 100%; text-align: center; color: white;
font-family: Arial; font-size: 18px; pointer-events: none;
}
#file-input {
position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%);
z-index: 100; padding: 10px; background: white; border-radius: 5px;
}
#loading {
position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
color: white; font-family: Arial; font-size: 20px; display: none;
}
#canvas-container { width: 100%; height: 100vh; background: #1a1a1a; }
</style>
</head>
<body>
<div id="info">STL模型查看器 - 使用滑鼠來控制視角</div>
<div id="loading">載入中...</div>
<input type="file" id="file-input" accept=".stl" />
<div id="canvas-container"></div>
</body>
</html>
這段程式碼定義了:
#info
。#file-input
。#canvas-container
。#loading
。接下來,我們使用Three.js建立3D渲染場景、相機與控制器:
// 初始化場景、相機和渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.getElementById('canvas-container').appendChild(renderer.domElement);
這裡主要的步驟包括:
scene
(場景),作為所有3D物件的容器。camera
(相機),設定視野角度為75度,適合普通用途。renderer
(渲染器),並將畫布添加到 #canvas-container
中。3D模型需要光照來呈現材質與細節,並透過控制器實現互動功能:
// 添加燈光
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(1, 1, 1);
scene.add(directionalLight);
const ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
// 軌道控制器
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
// 設定相機位置
camera.position.z = 5;
DirectionalLight
模擬來自單一方向的光源,AmbientLight
提供環境光以均勻照亮場景。OrbitControls
則允許使用者拖曳滑鼠控制視角。
實現STL檔案上傳與模型顯示是這個應用的核心部分:
const loader = new THREE.STLLoader();
let currentModel = null;
document.getElementById('file-input').addEventListener('change', function(event) {
const file = event.target.files[0];
if (file) {
const loadingEl = document.getElementById('loading');
loadingEl.style.display = 'block';
const url = URL.createObjectURL(file);
if (currentModel) {
scene.remove(currentModel);
}
loader.load(url, function(geometry) {
const material = new THREE.MeshPhongMaterial({ color: 0xcccccc, specular: 0x111111, shininess: 200 });
const mesh = new THREE.Mesh(geometry, material);
geometry.computeBoundingBox();
const box = new THREE.Box3().setFromObject(mesh);
const center = box.getCenter(new THREE.Vector3());
const size = box.getSize(new THREE.Vector3());
const maxDim = Math.max(size.x, size.y, size.z);
const scale = 5 / maxDim;
mesh.scale.setScalar(scale);
mesh.position.sub(center.multiplyScalar(scale));
scene.add(mesh);
currentModel = mesh;
loadingEl.style.display = 'none';
URL.revokeObjectURL(url);
}, function(xhr) {
const percent = (xhr.loaded / xhr.total * 100).toFixed(0);
loadingEl.textContent = `載入中... ${percent}%`;
}, function(error) {
console.error(error);
loadingEl.textContent = '載入失敗';
setTimeout(() => loadingEl.style.display = 'none', 2000);
});
}
});
為了持續渲染與適應視窗大小,我們添加動畫函式與resize監聽器:
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
animate();
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
完成以上所有步驟後,您將擁有一個簡單卻功能齊全的STL模型查看器。這個範例結構清晰且易於擴展,可以加入更多功能,例如材質選擇、模型保存等。希望這篇文章對您學習Three.js開發3D應用有所幫助!