aboutsummaryrefslogtreecommitdiffstats
path: root/src/user/ThreeVideo.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/ThreeVideo.ts')
-rw-r--r--src/user/ThreeVideo.ts47
1 files changed, 46 insertions, 1 deletions
diff --git a/src/user/ThreeVideo.ts b/src/user/ThreeVideo.ts
index bbce038..92615f1 100644
--- a/src/user/ThreeVideo.ts
+++ b/src/user/ThreeVideo.ts
@@ -1,8 +1,53 @@
import { Video as BaseVideo, type FrameTime, type InitConfig } from '$/lib/Player/Video';
import * as THREE from 'three';
+import type { OrbitControls } from 'three/examples/jsm/Addons.js';
+
+export const OnceCell = <T>(create: () => T) => {
+ let called = false,
+ cached = null as unknown as T
+ return () => {
+ if (called) return cached
+ else { cached = create(); called = true; return cached }
+ }
+}
export default abstract class ThreeVideo extends BaseVideo {
- public async init(config: InitConfig): Promise<void> {
+ protected abstract ctx: CanvasRenderingContext2D
+ protected scene!: THREE.Scene;
+ protected camera!: THREE.PerspectiveCamera;
+ protected renderer!: THREE.WebGLRenderer;
+ protected threeCanvas!: HTMLCanvasElement;
+ protected orbitControls?: OrbitControls;
+ public async init(_config: InitConfig): Promise<void> {
+ this.scene = new THREE.Scene();
+ this.camera = new THREE.PerspectiveCamera(75, this.w / this.h, 0.1, 1000);
+ const canvas = this.threeCanvas = document.createElement('canvas');
+ canvas.width = this.canvas.width
+ canvas.height = this.canvas.height
+ canvas.style.opacity = "0"
+ canvas.style.position = "fixed";
+ canvas.style.top = "1000vh"
+ canvas.style.left = "1000vw"
+ document.body.appendChild(canvas)
+
+ this.renderer = new THREE.WebGLRenderer({
+ canvas: canvas,
+ alpha: true,
+ powerPreference: 'high-performance',
+ });
+ this.renderer.setSize(this.w, this.h);
+ this.renderer.setAnimationLoop(() => this.renderScene());
+ }
+ public renderScene(ctx?: CanvasRenderingContext2D) {
+ if (this.orbitControls)
+ this.orbitControls.update()
+ this.renderer.render(this.scene, this.camera)
+ if (ctx)
+ ctx.drawImage(this.threeCanvas, 0, 0)
+ }
+ public cleanup(): void {
+ this.renderer.dispose()
+ this.threeCanvas.remove()
}
}