Buckets:
| <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.