Monopoly / monopoly-admin /src /utils /three /ThreeSceneBase.ts
Haruka041
chore: reset repository history with clean initial import
5b324f1
import * as THREE from "three";
import {debounce} from "@/utils";
export class ThreeSceneBase {
protected canvasEl: HTMLCanvasElement;
protected containerEl: HTMLDivElement | undefined;
protected renderer: THREE.WebGLRenderer;
protected scene: THREE.Scene;
protected camera: THREE.PerspectiveCamera;
protected requestAnimationFrameId: number = -1;
private resizeObserver: ResizeObserver | undefined;
constructor(canvas: HTMLCanvasElement) {
this.canvasEl = canvas;
this.renderer = new THREE.WebGLRenderer({canvas});
this.renderer.setSize(canvas.clientWidth, canvas.clientHeight);
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(75, canvas.clientWidth / canvas.clientHeight, 0.1, 1000)
// this.renderLoop();
const parentEl = canvas.parentElement;
if (parentEl) {
const tempDivEl = document.createElement('div');
Object.assign(tempDivEl.style, {
position: 'relative',
width: '100%',
height: '100%',
});
Object.assign(canvas.style, {
position: 'absolute ',
width: '100%',
height: '100%',
left: '0',
top: '0',
});
tempDivEl.append(canvas);
parentEl.append(tempDivEl)
this.containerEl = tempDivEl;
const callback: ResizeObserverCallback = (entries) => {
if (entries.length === 0) return
const _parentEl = entries[0].target;
if (_parentEl) {
this.renderer.setSize(_parentEl.clientWidth, _parentEl.clientHeight);
this.camera.aspect = _parentEl.clientWidth / _parentEl.clientHeight;
this.camera.updateProjectionMatrix();
}
}
const resizeObserver = new ResizeObserver(debounce(callback.bind(this), 100));
resizeObserver.observe(tempDivEl, {})
this.resizeObserver = resizeObserver;
}
}
protected setLoadingMaskVisible(visible: boolean) {
if (this.containerEl) {
if (visible) this.containerEl.setAttribute('loading', '');
else this.containerEl.removeAttribute('loading');
}
}
protected render() {
this.renderer.render(this.scene, this.camera);
}
protected destroy() {
this.resizeObserver && this.resizeObserver.disconnect();
cancelAnimationFrame(this.requestAnimationFrameId);
this.scene.traverse(object => {
//@ts-ignore
object.geometry && object.geometry.dispose();
//@ts-ignore
object.texture && object.texture.dispose();
//@ts-ignore
object.material && object.material.dispose();
})
this.scene.clear();
this.renderer.dispose();
this.renderer.forceContextLoss();
let gl = this.renderer.domElement.getContext("webgl");
if (gl) {
const e = gl.getExtension("WEBGL_lose_context")
e && e.loseContext();
}
}
}