diff options
Diffstat (limited to 'src/user/ThreeVideo.ts')
-rw-r--r-- | src/user/ThreeVideo.ts | 47 |
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() } } |