The website of the KaosCube
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
2.3 KiB

  1. import './three.min.js';
  2. import './STLLoader.js';
  3. import './OrbitControls.js';
  4. class STLViewer extends HTMLElement {
  5. constructor() {
  6. super();
  7. }
  8. connectedCallback() {
  9. this.connected = true;
  10. const shadowRoot = this.attachShadow({ mode: 'open' });
  11. const container = document.createElement('div');
  12. container.style.width = '100%';
  13. container.style.height = '100%';
  14. shadowRoot.appendChild(container);
  15. if (!this.hasAttribute('model')) {
  16. throw new Error('model attribute is required');
  17. }
  18. const model = this.getAttribute('model');
  19. let camera = new THREE.PerspectiveCamera(70, container.clientWidth / container.clientHeight, 1, 1000);
  20. let renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
  21. renderer.setSize(container.clientWidth, container.clientHeight);
  22. container.appendChild(renderer.domElement);
  23. window.addEventListener('resize', function () {
  24. renderer.setSize(container.clientWidth, container.clientHeight);
  25. camera.aspect = container.clientWidth / container.clientHeight;
  26. camera.updateProjectionMatrix();
  27. }, false);
  28. let controls = new THREE.OrbitControls(camera, renderer.domElement);
  29. controls.enableZoom = true;
  30. let scene = new THREE.Scene();
  31. scene.add(new THREE.HemisphereLight(0xffffff, 1.5));
  32. new THREE.STLLoader().load(model, (geometry) => {
  33. let material = new THREE.MeshPhongMaterial({
  34. color: 0x6A39FF,
  35. specular: 100,
  36. shininess: 100,
  37. });
  38. let mesh = new THREE.Mesh(geometry, material);
  39. scene.add(mesh);
  40. let middle = new THREE.Vector3();
  41. geometry.computeBoundingBox();
  42. geometry.boundingBox.getCenter(middle);
  43. mesh.geometry.applyMatrix4(new THREE.Matrix4().makeTranslation(-middle.x, -middle.y, -middle.z));
  44. let largestDimension = Math.max(geometry.boundingBox.max.x, geometry.boundingBox.max.y, geometry.boundingBox.max.z)
  45. camera.position.z = largestDimension * 1.5;
  46. controls.autoRotate = true;
  47. controls.autoRotateSpeed = 1;
  48. let animate = () => {
  49. controls.update();
  50. renderer.render(scene, camera);
  51. if (this.connected) {
  52. requestAnimationFrame(animate);
  53. }
  54. };
  55. animate();
  56. });
  57. }
  58. disconnectedCallback() {
  59. this.connected = false;
  60. }
  61. }
  62. customElements.define('stl-viewer', STLViewer);