threewebcomponents/ThreeRendererElement.js

114 lines
3.0 KiB
JavaScript

import * as THREE from 'https://esm.sh/three';
THREE.Object3D.DEFAULT_UP.set(0,0,1);
export class ThreeRendererElement extends HTMLCanvasElement {
constructor() {
super();
var parent_boundingbox = this.parentElement.getBoundingClientRect();
this.height = parent_boundingbox.height;
this.width = parent_boundingbox.width;
this.camera_persp = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
//this.camera_ortho = new THREE.OrthographicCamera( this.width / - 2, this.width / 2, this.height / 2, this.height / - 2, 1, 1000 );
this.camera = this.camera_persp;
this.camera.position.x = 0;
this.camera.position.y = 0;
this.camera.position.z = 0;
/*
var light = this.light = new THREE.AmbientLight(0xab1f2c, 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.scene.add(point_light);
*/
var renderer = this.renderer = new THREE.WebGLRenderer({
canvas: this
});
var bb = this.parentElement.getBoundingClientRect();
this.renderer.setSize(bb.width, bb.height);
/*
// ground plane
const planeSize = 40;
const loader = new THREE.TextureLoader();
const texture = loader.load('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;
this.scene.add(plane_mesh);
*/
// XXX applWHY?
this.do_animate = this.do_animate.bind(this);
this.do_animate();
// TODO improve value checking, current src="" will be true
/*
this.childObserver = new MutationObserver(function(changes) {
})
this.childObserver.observe(this, {
attributes: true,
childList: true,
subtree: true
});
*/
}
static get observedAttributes() {
return [ ];
}
do_animate() {
// TODO handle pausing
requestAnimationFrame(this.do_animate);
if(this.active_scene) {
this.renderer.render(this.active_scene, this.camera);
}
}
attributeChangedCallback(name, old_value, value) {
}
parsedCallack() {
console.log('parsedCallack');
}
setupRenderer() {
this.scenes = this.querySelectorAll('three-scene');
this.active_scene = this.scenes[this.scenes.length - 1].scene;
}
connectedCallback() {
if(document.readyState != "complete") {
document.addEventListener("DOMContentLoaded", this.setupRenderer.bind(this));
}
this.dispatchEvent(new CustomEvent("renderer-ready", {
cancelable: false
}));
}
}
customElements.define('three-renderer', ThreeRendererElement, { extends: 'canvas' });