ktongue's picture
download
raw
3.7 kB
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>STL Viewer</title>
<style>
html,body { height:100%; margin:0 }
#viewer { width:100%; height:100vh; display:block }
.toolbar { position:fixed; left:8px; top:8px; z-index:10; background:rgba(255,255,255,0.9); padding:6px; border-radius:6px }
.toolbar a { margin-right:8px }
</style>
</head>
<body>
<div class="toolbar">
<label>File: <input id="fileInput" type="text" size="30"></label>
<button id="loadBtn">Load</button>
<a id="downloadLink" href="#">Download STL</a>
</div>
<div id="viewer"></div>
<script src="https://unpkg.com/three@0.150.1/build/three.min.js"></script>
<script src="https://unpkg.com/three@0.150.1/examples/js/controls/OrbitControls.js"></script>
<script src="https://unpkg.com/three@0.150.1/examples/js/loaders/STLLoader.js"></script>
<script>
const params = new URLSearchParams(window.location.search);
const defaultFile = params.get('file') || 'cylinder.stl';
const container = document.getElementById('viewer');
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xf0f0f0);
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, -80, 40);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.target.set(0,0,0);
controls.update();
const hemi = new THREE.HemisphereLight(0xffffff, 0x444444, 0.8);
scene.add(hemi);
const dir = new THREE.DirectionalLight(0xffffff, 0.8);
dir.position.set(0, 50, 50);
scene.add(dir);
let meshGroup = new THREE.Group();
scene.add(meshGroup);
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
function centerAndScale(object) {
const box = new THREE.Box3().setFromObject(object);
const size = new THREE.Vector3(); box.getSize(size);
const maxDim = Math.max(size.x, size.y, size.z);
const scale = maxDim > 0 ? 60 / maxDim : 1;
object.scale.setScalar(scale);
box.setFromObject(object);
const center = box.getCenter(new THREE.Vector3());
object.position.sub(center);
}
function loadSTL(url) {
const loader = new THREE.STLLoader();
loader.load(url,
geometry => {
meshGroup.clear();
const material = new THREE.MeshStandardMaterial({ color: 0x8f8fff, metalness: 0.1, roughness: 0.6 });
const mesh = new THREE.Mesh(geometry, material);
mesh.geometry.computeVertexNormals();
meshGroup.add(mesh);
centerAndScale(meshGroup);
controls.reset();
},
xhr => {},
err => { alert('Failed to load STL: ' + err); }
);
}
document.getElementById('fileInput').value = defaultFile;
document.getElementById('loadBtn').addEventListener('click', () => {
const f = document.getElementById('fileInput').value;
if (f) loadSTL(f);
document.getElementById('downloadLink').href = f;
});
document.getElementById('downloadLink').href = defaultFile;
// initial load
loadSTL(defaultFile);
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
</script>
</body>
</html>

Xet Storage Details

Size:
3.7 kB
·
Xet hash:
a2970a527d05d45fbf2301cd2ef352b425cfbdb8af29ba392120a89b445df245

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.