128 lines
3.5 KiB
JavaScript
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);
|