fcwv-flask/static/ThreeRendererElement.js

128 lines
3.5 KiB
JavaScript

import * as THREE from 'three';
import { STLLoader } from 'STLLoader';
import { OrbitControls } from 'OrbitControls';
export class ThreeRendererElement extends HTMLElement {
constructor() {
super();
var scene = this.scene = new THREE.Scene();
var camera = this.camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
var light = this.light = new THREE.AmbientLight(0xffffff, 1);
this.scene.add(light);
var point_light = this.point_light = new THREE.DirectionalLight(0xffffff, 0.5);
this.point_light.position.set(0, 0, 10);
this.point_light.target.position.set(-5, 0, 0);
this.scene.add(point_light);
this.scene.add(point_light.target);
var renderer = this.renderer = new THREE.WebGLRenderer();
var bb = this.parentElement.getBoundingClientRect();
this.renderer.setSize(bb.width, bb.height);
this.controls = new OrbitControls(camera, renderer.domElement);
this.geometry = new THREE.BoxGeometry();
this.material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
this.scene.background = new THREE.Color(0xababab);
this.camera.position.z = 5;
var group = this.group = new THREE.Group();
//group.rotation.x = group.rotation.y = Math.PI / 2;
this.scene.add(group);
// ground plane
const planeSize = 40;
const loader = new THREE.TextureLoader();
const texture = loader.load('static/three.js-master/examples/textures/checker.png');
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.magFilter = THREE.NearestFilter;
const repeats = planeSize / 2;
texture.repeat.set(repeats, repeats);
const planeGeo = new THREE.PlaneGeometry(planeSize, planeSize);
const planeMat = new THREE.MeshPhongMaterial({
map: texture,
side: THREE.DoubleSide,
});
const plane_mesh = new THREE.Mesh(planeGeo, planeMat);
window.plane_mesh = plane_mesh;
//plane_mesh.rotation.x = Math.PI * -.5;
plane_mesh.position.z = -10;
this.scene.add(plane_mesh);
if(this.hasAttribute('src')) {
this.loadObject(this.getAttribute('src'));
}
// XXX applWHY?
this.do_animate = this.do_animate.bind(this);
this.do_animate();
}
loadObject(src) {
const loader = new STLLoader();
const group = this.group;
loader.load(src, function (geometry) {
group.clear();
const material = new THREE.MeshStandardMaterial({
color: 0xababab,
metalness: 0.5,
specular: 0x111111,
shininess: 300
});
const mesh = new THREE.Mesh(geometry, material);
mesh.castShadow = true;
mesh.receiveShadow = true;
const edges = new THREE.EdgesGeometry(geometry);
const lines = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({
color: 0xff0000
}));
geometry.center();
edges.center();
group.add(mesh);
group.add(lines);
});
}
set src(url) {
return this.setAttribute('src', url);
}
get src() {
return this.getAttribute('src');
}
static get observedAttributes() {
return [ 'src' ];
}
do_animate() {
// TODO handle pausing
requestAnimationFrame(this.do_animate);
this.renderer.render(this.scene, this.camera);
}
attributeChangedCallback(name, old_value, value) {
if(name == 'src') {
this.loadObject(value);
}
}
connectedCallback() {
this.appendChild(this.renderer.domElement);
}
}
customElements.define('three-renderer', ThreeRendererElement);